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:
Peter von der Ahé 2018-05-19 06:29:19 +00:00 committed by commit-bot@chromium.org
parent cb9bf910f9
commit 4610daa1c1
4 changed files with 189 additions and 179 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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));