| Index: pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
|
| diff --git a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
|
| index e229a0335ac1ae394057086ce4ed0c15d580a9d8..c69c5fa12a100040e95c5c321ea6db518ddb971f 100644
|
| --- a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
|
| +++ b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
|
| @@ -40,6 +40,7 @@ import 'kernel_builder.dart'
|
| show
|
| Builder,
|
| KernelClassBuilder,
|
| + KernelInvalidTypeBuilder,
|
| LibraryBuilder,
|
| PrefixBuilder,
|
| TypeDeclarationBuilder;
|
| @@ -102,6 +103,11 @@ abstract class BuilderHelper {
|
| Expression buildMethodInvocation(
|
| Expression receiver, Name name, Arguments arguments, int offset,
|
| {bool isConstantExpression, bool isNullAware});
|
| +
|
| + DartType validatedTypeVariableUse(
|
| + TypeParameterType type, int offset, bool nonInstanceAccessIsError);
|
| +
|
| + void warning(String message, [int charOffset]);
|
| }
|
|
|
| abstract class FastaAccessor implements Accessor {
|
| @@ -400,6 +406,8 @@ abstract class IncompleteSend extends FastaAccessor {
|
| IncompleteSend(this.helper, this.token, this.name);
|
|
|
| withReceiver(Object receiver, {bool isNullAware});
|
| +
|
| + Arguments get arguments => null;
|
| }
|
|
|
| class IncompleteError extends IncompleteSend with ErrorAccessor {
|
| @@ -420,6 +428,7 @@ class IncompleteError extends IncompleteSend with ErrorAccessor {
|
| }
|
|
|
| class SendAccessor extends IncompleteSend {
|
| + @override
|
| final Arguments arguments;
|
|
|
| SendAccessor(BuilderHelper helper, Token token, Name name, this.arguments)
|
| @@ -438,11 +447,6 @@ class SendAccessor extends IncompleteSend {
|
| }
|
|
|
| withReceiver(Object receiver, {bool isNullAware: false}) {
|
| - if (receiver is TypeDeclarationBuilder) {
|
| - /// `SomeType?.toString` is the same as `SomeType.toString`, not
|
| - /// `(SomeType).toString`.
|
| - isNullAware = false;
|
| - }
|
| if (receiver is FastaAccessor) {
|
| return receiver.buildPropertyAccess(this, isNullAware);
|
| }
|
| @@ -452,40 +456,9 @@ class SendAccessor extends IncompleteSend {
|
| isQualified: true, prefix: prefix);
|
| return helper.finishSend(receiver, arguments, offsetForToken(token));
|
| }
|
| - Expression result;
|
| - if (receiver is KernelClassBuilder) {
|
| - Builder builder = receiver.findStaticBuilder(
|
| - name.name, offsetForToken(token), uri, helper.library);
|
| - if (builder == null || builder is AccessErrorBuilder) {
|
| - return buildThrowNoSuchMethodError(arguments);
|
| - }
|
| - if (builder.hasProblem) {
|
| - result = helper.buildProblemExpression(builder, offsetForToken(token));
|
| - } else {
|
| - Member target = builder.target;
|
| - if (target != null) {
|
| - if (target is Field) {
|
| - result = helper.buildMethodInvocation(
|
| - new StaticGet(target),
|
| - callName,
|
| - arguments,
|
| - offsetForToken(token) + (target.name?.name?.length ?? 0),
|
| - isNullAware: isNullAware);
|
| - } else {
|
| - result = helper.buildStaticInvocation(target, arguments)
|
| - ..fileOffset = offsetForToken(token);
|
| - }
|
| - } else {
|
| - result = buildThrowNoSuchMethodError(arguments)
|
| - ..fileOffset = offsetForToken(token);
|
| - }
|
| - }
|
| - } else {
|
| - result = helper.buildMethodInvocation(
|
| - helper.toValue(receiver), name, arguments, offsetForToken(token),
|
| - isNullAware: isNullAware);
|
| - }
|
| - return result;
|
| + return helper.buildMethodInvocation(
|
| + helper.toValue(receiver), name, arguments, offsetForToken(token),
|
| + isNullAware: isNullAware);
|
| }
|
|
|
| Expression buildNullAwareAssignment(Expression value, DartType type,
|
| @@ -531,12 +504,6 @@ class IncompletePropertyAccessor extends IncompleteSend {
|
| }
|
|
|
| withReceiver(Object receiver, {bool isNullAware: false}) {
|
| - if (receiver is TypeDeclarationBuilder) {
|
| - /// For reasons beyond comprehension, `SomeType?.toString` is the same as
|
| - /// `SomeType.toString`, not `(SomeType).toString`. WTAF!?!
|
| - //
|
| - isNullAware = false;
|
| - }
|
| if (receiver is FastaAccessor) {
|
| return receiver.buildPropertyAccess(this, isNullAware);
|
| }
|
| @@ -545,26 +512,7 @@ class IncompletePropertyAccessor extends IncompleteSend {
|
| return helper.scopeLookup(prefix.exports, name.name, token,
|
| isQualified: true, prefix: prefix);
|
| }
|
| - if (receiver is KernelClassBuilder) {
|
| - Builder builder = receiver.findStaticBuilder(
|
| - name.name, offsetForToken(token), uri, helper.library);
|
| - if (builder == null) {
|
| - // If we find a setter, [builder] is an [AccessErrorBuilder], not null.
|
| - return buildThrowNoSuchMethodError(new Arguments.empty(),
|
| - isGetter: true);
|
| - }
|
| - Builder setter;
|
| - if (builder.isSetter) {
|
| - setter = builder;
|
| - } else if (builder.isGetter) {
|
| - setter = receiver.findStaticBuilder(
|
| - name.name, offsetForToken(token), uri, helper.library,
|
| - isSetter: true);
|
| - } else if (builder.isField && !builder.isFinal) {
|
| - setter = builder;
|
| - }
|
| - return new StaticAccessor.fromBuilder(helper, builder, token, setter);
|
| - }
|
| +
|
| return PropertyAccessor.make(
|
| helper, token, helper.toValue(receiver), name, null, null, isNullAware);
|
| }
|
| @@ -869,6 +817,93 @@ class ParenthesizedExpression extends ReadOnlyAccessor {
|
| }
|
| }
|
|
|
| +class TypeDeclarationAccessor extends ReadOnlyAccessor {
|
| + final TypeDeclarationBuilder declaration;
|
| +
|
| + TypeDeclarationAccessor(BuilderHelper helper, this.declaration,
|
| + String plainNameForRead, Token token)
|
| + : super(helper, null, plainNameForRead, token);
|
| +
|
| + Expression get expression {
|
| + if (super.expression == null) {
|
| + int offset = offsetForToken(token);
|
| + if (declaration is KernelInvalidTypeBuilder) {
|
| + KernelInvalidTypeBuilder declaration = this.declaration;
|
| + String message = declaration.message;
|
| + helper.library.addWarning(declaration.charOffset, message,
|
| + fileUri: declaration.fileUri);
|
| + helper.warning(message, offset);
|
| + super.expression = new Throw(
|
| + new StringLiteral(message)..fileOffset = offsetForToken(token))
|
| + ..fileOffset = offset;
|
| + } else {
|
| + super.expression =
|
| + new TypeLiteral(buildType(null, nonInstanceAccessIsError: true))
|
| + ..fileOffset = offsetForToken(token);
|
| + }
|
| + }
|
| + return super.expression;
|
| + }
|
| +
|
| + Expression makeInvalidWrite(Expression value) {
|
| + return buildThrowNoSuchMethodError(
|
| + new Arguments(<Expression>[value])..fileOffset = value.fileOffset,
|
| + isSetter: true);
|
| + }
|
| +
|
| + @override
|
| + buildPropertyAccess(IncompleteSend send, bool isNullAware) {
|
| + // `SomeType?.toString` is the same as `SomeType.toString`, not
|
| + // `(SomeType).toString`.
|
| + isNullAware = false;
|
| +
|
| + Name name = send.name;
|
| + Arguments arguments = send.arguments;
|
| +
|
| + if (declaration is KernelClassBuilder) {
|
| + KernelClassBuilder declaration = this.declaration;
|
| + Builder builder = declaration.findStaticBuilder(
|
| + name.name, offsetForToken(token), uri, helper.library);
|
| +
|
| + FastaAccessor accessor;
|
| + if (builder == null) {
|
| + // If we find a setter, [builder] is an [AccessErrorBuilder], not null.
|
| + accessor = new UnresolvedAccessor(helper, name, token);
|
| + } else {
|
| + Builder setter;
|
| + if (builder.isSetter) {
|
| + setter = builder;
|
| + } else if (builder.isGetter) {
|
| + setter = declaration.findStaticBuilder(
|
| + name.name, offsetForToken(token), uri, helper.library,
|
| + isSetter: true);
|
| + } else if (builder.isField && !builder.isFinal) {
|
| + setter = builder;
|
| + }
|
| + accessor =
|
| + new StaticAccessor.fromBuilder(helper, builder, send.token, setter);
|
| + }
|
| +
|
| + return arguments == null
|
| + ? accessor
|
| + : accessor.doInvocation(offsetForToken(send.token), arguments);
|
| + } else {
|
| + return super.buildPropertyAccess(send, isNullAware);
|
| + }
|
| + }
|
| +
|
| + DartType buildType(List<DartType> arguments,
|
| + {bool nonInstanceAccessIsError: false}) {
|
| + DartType type =
|
| + declaration.buildTypesWithBuiltArguments(helper.library, arguments);
|
| + if (type is TypeParameterType) {
|
| + return helper.validatedTypeVariableUse(
|
| + type, offsetForToken(token), nonInstanceAccessIsError);
|
| + }
|
| + return type;
|
| + }
|
| +}
|
| +
|
| class UnresolvedAccessor extends FastaAccessor with ErrorAccessor {
|
| @override
|
| final Token token;
|
|
|