mirror of
https://github.com/dart-lang/sdk
synced 2024-10-03 21:21:32 +00:00
Convert ThisAccessor to ThisAccessGenerator
Change-Id: I097c330712c789a65a1ce9c6a57ef0c81a3a32ed Reviewed-on: https://dart-review.googlesource.com/55893 Commit-Queue: Peter von der Ahé <ahe@google.com> Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
parent
cb9bf910f9
commit
4610daa1c1
|
@ -102,7 +102,7 @@ import 'expression_generator.dart'
|
|||
SendAccessor,
|
||||
StaticAccessGenerator,
|
||||
SuperIndexedAccessGenerator,
|
||||
ThisAccessor,
|
||||
ThisAccessGenerator,
|
||||
ThisPropertyAccessGenerator,
|
||||
TypeDeclarationAccessor,
|
||||
UnresolvedAccessor,
|
||||
|
@ -1014,8 +1014,8 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
Expression argument = popForValue();
|
||||
var receiver = pop();
|
||||
bool isSuper = false;
|
||||
if (receiver is ThisAccessor && receiver.isSuper) {
|
||||
ThisAccessor thisAccessorReceiver = receiver;
|
||||
if (receiver is ThisAccessGenerator && receiver.isSuper) {
|
||||
ThisAccessGenerator thisAccessorReceiver = receiver;
|
||||
isSuper = true;
|
||||
receiver = forest.thisExpression(thisAccessorReceiver.token);
|
||||
}
|
||||
|
@ -2417,7 +2417,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
debugEvent("IndexedExpression");
|
||||
Expression index = popForValue();
|
||||
var receiver = pop();
|
||||
if (receiver is ThisAccessor && receiver.isSuper) {
|
||||
if (receiver is ThisAccessGenerator && receiver.isSuper) {
|
||||
push(new SuperIndexedAccessGenerator(
|
||||
this,
|
||||
openSquareBracket,
|
||||
|
@ -2457,7 +2457,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
}
|
||||
bool isSuper = false;
|
||||
Expression receiverValue;
|
||||
if (receiver is ThisAccessor && receiver.isSuper) {
|
||||
if (receiver is ThisAccessGenerator && receiver.isSuper) {
|
||||
isSuper = true;
|
||||
receiverValue = forest.thisExpression(receiver.token);
|
||||
} else {
|
||||
|
@ -2935,7 +2935,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
void handleThisExpression(Token token, IdentifierContext context) {
|
||||
debugEvent("ThisExpression");
|
||||
if (context.isScopeReference && isInstanceContext) {
|
||||
push(new ThisAccessor(this, token, inInitializer));
|
||||
push(new ThisAccessGenerator(this, token, inInitializer));
|
||||
} else {
|
||||
push(new IncompleteError(this, token, fasta.messageThisAsIdentifier));
|
||||
}
|
||||
|
@ -2947,7 +2947,7 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
|
|||
if (context.isScopeReference && isInstanceContext) {
|
||||
Member member = this.member.target;
|
||||
member.transformerFlags |= TransformerFlag.superCalls;
|
||||
push(new ThisAccessor(this, token, inInitializer, isSuper: true));
|
||||
push(new ThisAccessGenerator(this, token, inInitializer, isSuper: true));
|
||||
} else {
|
||||
push(new IncompleteError(this, token, fasta.messageSuperAsIdentifier));
|
||||
}
|
||||
|
@ -4679,7 +4679,7 @@ String getNodeName(Object node) {
|
|||
return node.name;
|
||||
} else if (node is Builder) {
|
||||
return node.fullNameForErrors;
|
||||
} else if (node is ThisAccessor) {
|
||||
} else if (node is ThisAccessGenerator) {
|
||||
return node.isSuper ? "super" : "this";
|
||||
} else if (node is FastaAccessor) {
|
||||
return node.plainNameForRead;
|
||||
|
|
|
@ -1540,6 +1540,180 @@ abstract class ErroneousExpressionGenerator<Arguments>
|
|||
}
|
||||
}
|
||||
|
||||
class ThisAccessGenerator<Arguments> extends Generator<Arguments> {
|
||||
final bool isInitializer;
|
||||
|
||||
final bool isSuper;
|
||||
|
||||
ThisAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
|
||||
Token token, this.isInitializer,
|
||||
{this.isSuper: false})
|
||||
: super(helper, token);
|
||||
|
||||
String get plainNameForRead {
|
||||
return unsupported("${isSuper ? 'super' : 'this'}.plainNameForRead",
|
||||
offsetForToken(token), uri);
|
||||
}
|
||||
|
||||
String get debugName => "ThisAccessGenerator";
|
||||
|
||||
kernel.Expression buildSimpleRead() {
|
||||
if (!isSuper) {
|
||||
return forest.thisExpression(token);
|
||||
} else {
|
||||
return helper.buildCompileTimeError(messageSuperAsExpression,
|
||||
offsetForToken(token), lengthForToken(token));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
|
||||
String keyword = isSuper ? "super" : "this";
|
||||
int offset = offsetForToken(token);
|
||||
return helper.buildInvalidInitializer(
|
||||
helper.deprecated_buildCompileTimeError(
|
||||
"Can't use '$keyword' here, did you mean '$keyword()'?", offset),
|
||||
offset);
|
||||
}
|
||||
|
||||
buildPropertyAccess(
|
||||
IncompleteSend send, int operatorOffset, bool isNullAware) {
|
||||
Name name = send.name;
|
||||
Arguments arguments = send.arguments;
|
||||
int offset = offsetForToken(send.token);
|
||||
if (isInitializer && send is SendAccessor) {
|
||||
if (isNullAware) {
|
||||
helper.deprecated_addCompileTimeError(
|
||||
operatorOffset, "Expected '.'\nTry removing '?'.");
|
||||
}
|
||||
return buildConstructorInitializer(offset, name, arguments);
|
||||
}
|
||||
Member getter = helper.lookupInstanceMember(name, isSuper: isSuper);
|
||||
if (send is SendAccessor) {
|
||||
// Notice that 'this' or 'super' can't be null. So we can ignore the
|
||||
// value of [isNullAware].
|
||||
if (getter == null) {
|
||||
helper.warnUnresolvedMethod(name, offsetForToken(send.token),
|
||||
isSuper: isSuper);
|
||||
}
|
||||
return helper.buildMethodInvocation(forest.thisExpression(null), name,
|
||||
send.arguments, offsetForToken(send.token),
|
||||
isSuper: isSuper, interfaceTarget: getter);
|
||||
} else {
|
||||
Member setter =
|
||||
helper.lookupInstanceMember(name, isSuper: isSuper, isSetter: true);
|
||||
if (isSuper) {
|
||||
return new SuperPropertyAccessGenerator(
|
||||
helper, send.token, name, getter, setter);
|
||||
} else {
|
||||
return new ThisPropertyAccessGenerator(
|
||||
helper, send.token, name, getter, setter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doInvocation(int offset, Arguments arguments) {
|
||||
if (isInitializer) {
|
||||
return buildConstructorInitializer(offset, new Name(""), arguments);
|
||||
} else if (isSuper) {
|
||||
return helper.buildCompileTimeError(
|
||||
messageSuperAsExpression, offset, noLength);
|
||||
} else {
|
||||
return helper.buildMethodInvocation(
|
||||
forest.thisExpression(null), callName, arguments, offset,
|
||||
isImplicitCall: true);
|
||||
}
|
||||
}
|
||||
|
||||
Initializer buildConstructorInitializer(
|
||||
int offset, Name name, Arguments arguments) {
|
||||
Constructor constructor = helper.lookupConstructor(name, isSuper: isSuper);
|
||||
LocatedMessage argMessage;
|
||||
if (constructor != null) {
|
||||
argMessage = helper.checkArguments(
|
||||
new FunctionTypeAccessor.fromNode(constructor.function),
|
||||
arguments,
|
||||
CalleeDesignation.Constructor,
|
||||
offset, <TypeParameter>[]);
|
||||
}
|
||||
if (constructor == null || argMessage != null) {
|
||||
return helper.buildInvalidInitializer(
|
||||
buildThrowNoSuchMethodError(
|
||||
storeOffset(forest.literalNull(null), offset), arguments,
|
||||
isSuper: isSuper,
|
||||
name: name.name,
|
||||
offset: offset,
|
||||
argMessage: argMessage),
|
||||
offset);
|
||||
} else if (isSuper) {
|
||||
return helper.buildSuperInitializer(
|
||||
false, constructor, arguments, offset);
|
||||
} else {
|
||||
return helper.buildRedirectingInitializer(constructor, arguments, offset);
|
||||
}
|
||||
}
|
||||
|
||||
kernel.Expression buildAssignment(kernel.Expression value,
|
||||
{bool voidContext: false}) {
|
||||
return buildAssignmentError();
|
||||
}
|
||||
|
||||
kernel.Expression buildNullAwareAssignment(
|
||||
kernel.Expression value, DartType type, int offset,
|
||||
{bool voidContext: false}) {
|
||||
return buildAssignmentError();
|
||||
}
|
||||
|
||||
kernel.Expression buildCompoundAssignment(
|
||||
Name binaryOperator, kernel.Expression value,
|
||||
{int offset: TreeNode.noOffset,
|
||||
bool voidContext: false,
|
||||
Procedure interfaceTarget,
|
||||
bool isPreIncDec: false}) {
|
||||
return buildAssignmentError();
|
||||
}
|
||||
|
||||
kernel.Expression buildPrefixIncrement(Name binaryOperator,
|
||||
{int offset: TreeNode.noOffset,
|
||||
bool voidContext: false,
|
||||
Procedure interfaceTarget}) {
|
||||
return buildAssignmentError();
|
||||
}
|
||||
|
||||
kernel.Expression buildPostfixIncrement(Name binaryOperator,
|
||||
{int offset: TreeNode.noOffset,
|
||||
bool voidContext: false,
|
||||
Procedure interfaceTarget}) {
|
||||
return buildAssignmentError();
|
||||
}
|
||||
|
||||
kernel.Expression buildAssignmentError() {
|
||||
String message =
|
||||
isSuper ? "Can't assign to 'super'." : "Can't assign to 'this'.";
|
||||
return helper.deprecated_buildCompileTimeError(
|
||||
message, offsetForToken(token));
|
||||
}
|
||||
|
||||
@override
|
||||
kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
|
||||
return unimplemented("_makeRead", offsetForToken(token), uri);
|
||||
}
|
||||
|
||||
@override
|
||||
kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
|
||||
ShadowComplexAssignment complexAssignment) {
|
||||
return unimplemented("_makeWrite", offsetForToken(token), uri);
|
||||
}
|
||||
|
||||
@override
|
||||
void printOn(StringSink sink) {
|
||||
sink.write(", isInitializer: ");
|
||||
sink.write(isInitializer);
|
||||
sink.write(", isSuper: ");
|
||||
sink.write(isSuper);
|
||||
}
|
||||
}
|
||||
|
||||
kernel.Expression makeLet(
|
||||
VariableDeclaration variable, kernel.Expression body) {
|
||||
if (variable == null) return body;
|
||||
|
|
|
@ -277,172 +277,6 @@ abstract class GeneratorImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class ThisAccessor<Arguments> extends FastaAccessor<Arguments>
|
||||
with GeneratorImpl {
|
||||
final BuilderHelper<dynamic, dynamic, Arguments> helper;
|
||||
|
||||
final Token token;
|
||||
|
||||
final bool isInitializer;
|
||||
|
||||
final bool isSuper;
|
||||
|
||||
ThisAccessor(this.helper, this.token, this.isInitializer,
|
||||
{this.isSuper: false});
|
||||
|
||||
String get plainNameForRead {
|
||||
return unsupported("${isSuper ? 'super' : 'this'}.plainNameForRead",
|
||||
offsetForToken(token), uri);
|
||||
}
|
||||
|
||||
String get debugName => "ThisAccessor";
|
||||
|
||||
kernel.Expression buildSimpleRead() {
|
||||
if (!isSuper) {
|
||||
return forest.thisExpression(token);
|
||||
} else {
|
||||
return helper.buildCompileTimeError(messageSuperAsExpression,
|
||||
offsetForToken(token), lengthForToken(token));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
|
||||
String keyword = isSuper ? "super" : "this";
|
||||
int offset = offsetForToken(token);
|
||||
return helper.buildInvalidInitializer(
|
||||
helper.deprecated_buildCompileTimeError(
|
||||
"Can't use '$keyword' here, did you mean '$keyword()'?", offset),
|
||||
offset);
|
||||
}
|
||||
|
||||
buildPropertyAccess(
|
||||
IncompleteSend send, int operatorOffset, bool isNullAware) {
|
||||
Name name = send.name;
|
||||
Arguments arguments = send.arguments;
|
||||
int offset = offsetForToken(send.token);
|
||||
if (isInitializer && send is SendAccessor) {
|
||||
if (isNullAware) {
|
||||
helper.deprecated_addCompileTimeError(
|
||||
operatorOffset, "Expected '.'\nTry removing '?'.");
|
||||
}
|
||||
return buildConstructorInitializer(offset, name, arguments);
|
||||
}
|
||||
Member getter = helper.lookupInstanceMember(name, isSuper: isSuper);
|
||||
if (send is SendAccessor) {
|
||||
// Notice that 'this' or 'super' can't be null. So we can ignore the
|
||||
// value of [isNullAware].
|
||||
if (getter == null) {
|
||||
helper.warnUnresolvedMethod(name, offsetForToken(send.token),
|
||||
isSuper: isSuper);
|
||||
}
|
||||
return helper.buildMethodInvocation(forest.thisExpression(null), name,
|
||||
send.arguments, offsetForToken(send.token),
|
||||
isSuper: isSuper, interfaceTarget: getter);
|
||||
} else {
|
||||
Member setter =
|
||||
helper.lookupInstanceMember(name, isSuper: isSuper, isSetter: true);
|
||||
if (isSuper) {
|
||||
return new SuperPropertyAccessGenerator(
|
||||
helper, send.token, name, getter, setter);
|
||||
} else {
|
||||
return new ThisPropertyAccessGenerator(
|
||||
helper, send.token, name, getter, setter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doInvocation(int offset, Arguments arguments) {
|
||||
if (isInitializer) {
|
||||
return buildConstructorInitializer(offset, new Name(""), arguments);
|
||||
} else if (isSuper) {
|
||||
return helper.buildCompileTimeError(
|
||||
messageSuperAsExpression, offset, noLength);
|
||||
} else {
|
||||
return helper.buildMethodInvocation(
|
||||
forest.thisExpression(null), callName, arguments, offset,
|
||||
isImplicitCall: true);
|
||||
}
|
||||
}
|
||||
|
||||
Initializer buildConstructorInitializer(
|
||||
int offset, Name name, Arguments arguments) {
|
||||
Constructor constructor = helper.lookupConstructor(name, isSuper: isSuper);
|
||||
LocatedMessage argMessage;
|
||||
if (constructor != null) {
|
||||
argMessage = helper.checkArguments(
|
||||
new FunctionTypeAccessor.fromNode(constructor.function),
|
||||
arguments,
|
||||
CalleeDesignation.Constructor,
|
||||
offset, <TypeParameter>[]);
|
||||
}
|
||||
if (constructor == null || argMessage != null) {
|
||||
return helper.buildInvalidInitializer(
|
||||
buildThrowNoSuchMethodError(
|
||||
storeOffset(forest.literalNull(null), offset), arguments,
|
||||
isSuper: isSuper,
|
||||
name: name.name,
|
||||
offset: offset,
|
||||
argMessage: argMessage),
|
||||
offset);
|
||||
} else if (isSuper) {
|
||||
return helper.buildSuperInitializer(
|
||||
false, constructor, arguments, offset);
|
||||
} else {
|
||||
return helper.buildRedirectingInitializer(constructor, arguments, offset);
|
||||
}
|
||||
}
|
||||
|
||||
kernel.Expression buildAssignment(kernel.Expression value,
|
||||
{bool voidContext: false}) {
|
||||
return buildAssignmentError();
|
||||
}
|
||||
|
||||
kernel.Expression buildNullAwareAssignment(
|
||||
kernel.Expression value, DartType type, int offset,
|
||||
{bool voidContext: false}) {
|
||||
return buildAssignmentError();
|
||||
}
|
||||
|
||||
kernel.Expression buildCompoundAssignment(
|
||||
Name binaryOperator, kernel.Expression value,
|
||||
{int offset: TreeNode.noOffset,
|
||||
bool voidContext: false,
|
||||
Procedure interfaceTarget,
|
||||
bool isPreIncDec: false}) {
|
||||
return buildAssignmentError();
|
||||
}
|
||||
|
||||
kernel.Expression buildPrefixIncrement(Name binaryOperator,
|
||||
{int offset: TreeNode.noOffset,
|
||||
bool voidContext: false,
|
||||
Procedure interfaceTarget}) {
|
||||
return buildAssignmentError();
|
||||
}
|
||||
|
||||
kernel.Expression buildPostfixIncrement(Name binaryOperator,
|
||||
{int offset: TreeNode.noOffset,
|
||||
bool voidContext: false,
|
||||
Procedure interfaceTarget}) {
|
||||
return buildAssignmentError();
|
||||
}
|
||||
|
||||
kernel.Expression buildAssignmentError() {
|
||||
String message =
|
||||
isSuper ? "Can't assign to 'super'." : "Can't assign to 'this'.";
|
||||
return helper.deprecated_buildCompileTimeError(
|
||||
message, offsetForToken(token));
|
||||
}
|
||||
|
||||
@override
|
||||
void printOn(StringSink sink) {
|
||||
sink.write(", isInitializer: ");
|
||||
sink.write(isInitializer);
|
||||
sink.write(", isSuper: ");
|
||||
sink.write(isSuper);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class IncompleteSend<Arguments> extends FastaAccessor<Arguments>
|
||||
with GeneratorImpl {
|
||||
final BuilderHelper<dynamic, dynamic, Arguments> helper;
|
||||
|
|
|
@ -61,7 +61,7 @@ import 'package:front_end/src/fasta/kernel/expression_generator.dart'
|
|||
StaticAccessGenerator,
|
||||
SuperIndexedAccessGenerator,
|
||||
SuperPropertyAccessGenerator,
|
||||
ThisAccessor,
|
||||
ThisAccessGenerator,
|
||||
ThisIndexedAccessGenerator,
|
||||
ThisPropertyAccessGenerator,
|
||||
TypeDeclarationAccessor,
|
||||
|
@ -123,7 +123,8 @@ main() {
|
|||
KernelBodyBuilder helper = new KernelBodyBuilder(
|
||||
libraryBuilder, null, null, null, null, null, null, false, uri, null);
|
||||
|
||||
FastaAccessor accessor = new ThisAccessor<Arguments>(helper, token, false);
|
||||
FastaAccessor accessor =
|
||||
new ThisAccessGenerator<Arguments>(helper, token, false);
|
||||
|
||||
Library library = new Library(uri);
|
||||
Class cls = new Class();
|
||||
|
@ -193,8 +194,9 @@ main() {
|
|||
"LoadLibraryGenerator(offset: 4,"
|
||||
" builder: Instance of 'LoadLibraryBuilder')",
|
||||
new LoadLibraryGenerator<Arguments>(helper, token, loadLibraryBuilder));
|
||||
check("ThisAccessor(offset: 4, isInitializer: false, isSuper: false)",
|
||||
new ThisAccessor<Arguments>(helper, token, false));
|
||||
check(
|
||||
"ThisAccessGenerator(offset: 4, isInitializer: false, isSuper: false)",
|
||||
new ThisAccessGenerator<Arguments>(helper, token, false));
|
||||
check("IncompleteError(offset: 4, message: Unspecified)",
|
||||
new IncompleteError<Arguments>(helper, token, message));
|
||||
check("SendAccessor(offset: 4, name: bar, arguments: (\"arg\"))",
|
||||
|
@ -204,7 +206,7 @@ main() {
|
|||
check(
|
||||
"DeferredAccessGenerator(offset: 4, "
|
||||
"builder: Instance of 'PrefixBuilder',"
|
||||
" accessor: ThisAccessor(offset: 4, isInitializer: false,"
|
||||
" accessor: ThisAccessGenerator(offset: 4, isInitializer: false,"
|
||||
" isSuper: false))",
|
||||
new DeferredAccessGenerator<Arguments>(
|
||||
helper, token, prefixBuilder, accessor));
|
||||
|
|
Loading…
Reference in a new issue