Prepare to remove expression_generator_impl.dart

Change-Id: I459ee57e95b47bf59935df32902ce19051c3e7ab
Reviewed-on: https://dart-review.googlesource.com/56105
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-22 12:23:21 +00:00 committed by commit-bot@chromium.org
parent c771e4d132
commit 5924c35640
9 changed files with 556 additions and 514 deletions

View file

@ -6,8 +6,6 @@ import 'package:analyzer/dart/ast/ast.dart' hide Identifier;
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/ast_factory.dart';
import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
import 'package:front_end/src/fasta/kernel/body_builder.dart'
show Identifier, Operator;
import 'package:front_end/src/fasta/kernel/forest.dart';
import 'package:kernel/ast.dart' as kernel;

View file

@ -21,8 +21,7 @@ import 'package:front_end/src/fasta/compiler_context.dart';
import 'package:front_end/src/fasta/constant_context.dart';
import 'package:front_end/src/fasta/dill/dill_target.dart';
import "package:front_end/src/fasta/fasta_codes.dart";
import 'package:front_end/src/fasta/kernel/body_builder.dart' hide Identifier;
import 'package:front_end/src/fasta/kernel/forest.dart';
import 'package:front_end/src/fasta/kernel/forest.dart' hide Identifier;
import 'package:front_end/src/fasta/kernel/kernel_builder.dart';
import "package:front_end/src/fasta/kernel/kernel_target.dart";
import 'package:front_end/src/fasta/modifier.dart' as Modifier;
@ -514,7 +513,7 @@ f() {
false /* strong mode */,
));
BodyBuilder builder = new AstBodyBuilder(
AstBodyBuilder builder = new AstBodyBuilder(
library,
procedureBuilder,
library.scope,

View file

@ -84,7 +84,6 @@ import 'constness.dart' show Constness;
import 'expression_generator.dart'
show
BuilderHelper,
DeferredAccessGenerator,
ErroneousExpressionGenerator,
Generator,
@ -106,6 +105,8 @@ import 'expression_generator.dart'
VariableUseGenerator,
buildIsNull;
import 'expression_generator_helper.dart' show BuilderHelper;
import 'redirecting_factory_body.dart'
show
RedirectingFactoryBody,

View file

@ -30,14 +30,14 @@ import '../parser.dart' show lengthForToken, lengthOfSpan, offsetForToken;
import '../problems.dart' show unhandled, unsupported;
import '../scope.dart' show AccessErrorBuilder, ProblemBuilder, Scope;
import '../type_inference/type_promotion.dart' show TypePromoter;
import '../scope.dart' show AccessErrorBuilder;
import 'body_builder.dart' show Identifier, noLocation;
import 'constness.dart' show Constness;
import 'expression_generator_helper.dart' show BuilderHelper;
import 'forest.dart' show Forest;
import 'kernel_builder.dart' show LoadLibraryBuilder, PrefixBuilder;
@ -49,8 +49,6 @@ import 'kernel_ast_api.dart'
Constructor,
DartType,
Field,
FunctionNode,
FunctionType,
Initializer,
InvalidType,
Let,
@ -71,7 +69,6 @@ import 'kernel_ast_api.dart'
ShadowVariableAssignment,
ShadowVariableDeclaration,
ShadowVariableGet,
StaticGet,
StaticSet,
SuperMethodInvocation,
SuperPropertySet,
@ -93,15 +90,11 @@ import 'kernel_builder.dart'
KernelClassBuilder,
KernelFunctionTypeAliasBuilder,
KernelInvalidTypeBuilder,
KernelPrefixBuilder,
KernelTypeVariableBuilder,
LibraryBuilder,
LoadLibraryBuilder,
PrefixBuilder,
TypeDeclarationBuilder;
part 'expression_generator_impl.dart';
/// A generator represents a subexpression for which we can't yet build an
/// expression because we don't yet know the context in which it's used.
///
@ -1875,6 +1868,383 @@ class UnresolvedNameGenerator<Arguments> extends Generator<Arguments>
}
}
// TODO(ahe): Rename to IncompleteErrorGenerator.
class IncompleteError<Arguments> extends IncompleteSendGenerator<Arguments>
with ErroneousExpressionGenerator<Arguments> {
final Message message;
IncompleteError(BuilderHelper<dynamic, dynamic, Arguments> helper,
Token token, this.message)
: super(helper, token, null);
String get debugName => "IncompleteError";
@override
kernel.Expression buildError(Arguments arguments,
{bool isGetter: false, bool isSetter: false, int offset}) {
int length = noLength;
if (offset == null) {
offset = offsetForToken(token);
length = lengthForToken(token);
}
return helper.buildCompileTimeError(message, offset, length);
}
@override
DartType buildErroneousTypeNotAPrefix(Identifier suffix) {
helper.addProblem(
templateNotAPrefixInTypeAnnotation.withArguments(
token.lexeme, suffix.name),
offsetForToken(token),
lengthOfSpan(token, suffix.token));
return const InvalidType();
}
@override
doInvocation(int offset, Arguments arguments) => this;
@override
void printOn(StringSink sink) {
sink.write(", message: ");
sink.write(message.code.name);
}
}
// TODO(ahe): Rename to SendAccessGenerator.
class SendAccessor<Arguments> extends IncompleteSendGenerator<Arguments> {
@override
final Arguments arguments;
SendAccessor(BuilderHelper<dynamic, dynamic, Arguments> helper, Token token,
Name name, this.arguments)
: super(helper, token, name) {
assert(arguments != null);
}
String get plainNameForRead => name.name;
String get debugName => "SendAccessor";
kernel.Expression buildSimpleRead() {
return unsupported("buildSimpleRead", offsetForToken(token), uri);
}
kernel.Expression buildAssignment(kernel.Expression value,
{bool voidContext: false}) {
return unsupported("buildAssignment", offsetForToken(token), uri);
}
withReceiver(Object receiver, int operatorOffset, {bool isNullAware: false}) {
if (receiver is Generator) {
return receiver.buildPropertyAccess(this, operatorOffset, isNullAware);
}
if (receiver is PrefixBuilder) {
PrefixBuilder prefix = receiver;
if (isNullAware) {
helper.deprecated_addCompileTimeError(
offsetForToken(token),
"Library prefix '${prefix.name}' can't be used with null-aware "
"operator.\nTry removing '?'.");
}
receiver = helper.scopeLookup(prefix.exportScope, name.name, token,
isQualified: true, prefix: prefix);
return helper.finishSend(receiver, arguments, offsetForToken(token));
}
return helper.buildMethodInvocation(
helper.toValue(receiver), name, arguments, offsetForToken(token),
isNullAware: isNullAware);
}
kernel.Expression buildNullAwareAssignment(
kernel.Expression value, DartType type, int offset,
{bool voidContext: false}) {
return unsupported("buildNullAwareAssignment", offset, uri);
}
kernel.Expression buildCompoundAssignment(
Name binaryOperator, kernel.Expression value,
{int offset,
bool voidContext: false,
Procedure interfaceTarget,
bool isPreIncDec: false}) {
return unsupported(
"buildCompoundAssignment", offset ?? offsetForToken(token), uri);
}
kernel.Expression buildPrefixIncrement(Name binaryOperator,
{int offset, bool voidContext: false, Procedure interfaceTarget}) {
return unsupported(
"buildPrefixIncrement", offset ?? offsetForToken(token), uri);
}
kernel.Expression buildPostfixIncrement(Name binaryOperator,
{int offset, bool voidContext: false, Procedure interfaceTarget}) {
return unsupported(
"buildPostfixIncrement", offset ?? offsetForToken(token), uri);
}
kernel.Expression doInvocation(int offset, Arguments arguments) {
return unsupported("doInvocation", offset, uri);
}
@override
void printOn(StringSink sink) {
super.printOn(sink);
sink.write(", arguments: ");
var node = arguments;
if (node is kernel.Node) {
printNodeOn(node, sink);
} else {
sink.write(node);
}
}
}
// TODO(ahe): Rename to IncompletePropertyAccessGenerator.
class IncompletePropertyAccessor<Arguments>
extends IncompleteSendGenerator<Arguments> {
IncompletePropertyAccessor(
BuilderHelper<dynamic, dynamic, Arguments> helper, Token token, Name name)
: super(helper, token, name);
String get plainNameForRead => name.name;
String get debugName => "IncompletePropertyAccessor";
kernel.Expression buildSimpleRead() {
return unsupported("buildSimpleRead", offsetForToken(token), uri);
}
kernel.Expression buildAssignment(kernel.Expression value,
{bool voidContext: false}) {
return unsupported("buildAssignment", offsetForToken(token), uri);
}
withReceiver(Object receiver, int operatorOffset, {bool isNullAware: false}) {
if (receiver is Generator) {
return receiver.buildPropertyAccess(this, operatorOffset, isNullAware);
}
if (receiver is PrefixBuilder) {
PrefixBuilder prefix = receiver;
if (isNullAware) {
helper.deprecated_addCompileTimeError(
offsetForToken(token),
"Library prefix '${prefix.name}' can't be used with null-aware "
"operator.\nTry removing '?'.");
}
return helper.scopeLookup(prefix.exportScope, name.name, token,
isQualified: true, prefix: prefix);
}
return PropertyAccessGenerator.make(
helper, token, helper.toValue(receiver), name, null, null, isNullAware);
}
kernel.Expression buildNullAwareAssignment(
kernel.Expression value, DartType type, int offset,
{bool voidContext: false}) {
return unsupported("buildNullAwareAssignment", offset, uri);
}
kernel.Expression buildCompoundAssignment(
Name binaryOperator, kernel.Expression value,
{int offset,
bool voidContext: false,
Procedure interfaceTarget,
bool isPreIncDec: false}) {
return unsupported(
"buildCompoundAssignment", offset ?? offsetForToken(token), uri);
}
kernel.Expression buildPrefixIncrement(Name binaryOperator,
{int offset, bool voidContext: false, Procedure interfaceTarget}) {
return unsupported(
"buildPrefixIncrement", offset ?? offsetForToken(token), uri);
}
kernel.Expression buildPostfixIncrement(Name binaryOperator,
{int offset, bool voidContext: false, Procedure interfaceTarget}) {
return unsupported(
"buildPostfixIncrement", offset ?? offsetForToken(token), uri);
}
kernel.Expression doInvocation(int offset, Arguments arguments) {
return unsupported("doInvocation", offset, uri);
}
}
// TODO(ahe): Rename to ParenthesizedExpressionGenerator.
class ParenthesizedExpression<Arguments>
extends ReadOnlyAccessGenerator<Arguments> {
ParenthesizedExpression(BuilderHelper<dynamic, dynamic, Arguments> helper,
Token token, kernel.Expression expression)
: super(helper, token, expression, null);
String get debugName => "ParenthesizedExpression";
kernel.Expression makeInvalidWrite(kernel.Expression value) {
return helper.deprecated_buildCompileTimeError(
"Can't assign to a parenthesized expression.", offsetForToken(token));
}
}
// TODO(ahe): Rename to TypeDeclarationAccessGenerator.
class TypeDeclarationAccessor<Arguments>
extends ReadOnlyAccessGenerator<Arguments> {
/// The import prefix preceding the [declaration] reference, or `null` if
/// the reference is not prefixed.
final PrefixBuilder prefix;
/// The offset at which the [declaration] is referenced by this generator,
/// or `-1` if the reference is implicit.
final int declarationReferenceOffset;
final TypeDeclarationBuilder declaration;
TypeDeclarationAccessor(
BuilderHelper<dynamic, dynamic, Arguments> helper,
Token token,
this.prefix,
this.declarationReferenceOffset,
this.declaration,
String plainNameForRead)
: super(helper, token, null, plainNameForRead);
String get debugName => "TypeDeclarationAccessor";
kernel.Expression get expression {
if (super.expression == null) {
int offset = offsetForToken(token);
if (declaration is KernelInvalidTypeBuilder) {
KernelInvalidTypeBuilder declaration = this.declaration;
helper.addProblemErrorIfConst(
declaration.message.messageObject, offset, token.length);
super.expression =
new Throw(forest.literalString(declaration.message.message, token))
..fileOffset = offset;
} else {
super.expression = forest.literalType(
buildTypeWithBuiltArguments(null, nonInstanceAccessIsError: true),
token);
}
}
return super.expression;
}
kernel.Expression makeInvalidWrite(kernel.Expression value) {
return buildThrowNoSuchMethodError(
forest.literalNull(token),
storeOffset(forest.arguments(<kernel.Expression>[value], null),
value.fileOffset),
isSetter: true);
}
@override
buildPropertyAccess(
IncompleteSendGenerator send, int operatorOffset, 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);
Generator generator;
if (builder == null) {
// If we find a setter, [builder] is an [AccessErrorBuilder], not null.
if (send is IncompletePropertyAccessor) {
generator = new UnresolvedNameGenerator(helper, send.token, name);
} else {
return helper.buildConstructorInvocation(declaration, send.token,
arguments, name.name, null, token.charOffset, Constness.implicit);
}
} 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;
}
generator = new StaticAccessGenerator.fromBuilder(
helper, builder, send.token, setter);
}
return arguments == null
? generator
: generator.doInvocation(offsetForToken(send.token), arguments);
} else {
return super.buildPropertyAccess(send, operatorOffset, isNullAware);
}
}
@override
DartType buildTypeWithBuiltArguments(List<DartType> arguments,
{bool nonInstanceAccessIsError: false}) {
if (arguments != null) {
int expected = 0;
if (declaration is KernelClassBuilder) {
expected = declaration.target.typeParameters.length;
} else if (declaration is FunctionTypeAliasBuilder) {
expected = declaration.target.typeParameters.length;
} else if (declaration is KernelTypeVariableBuilder) {
// Type arguments on a type variable - error reported elsewhere.
} else if (declaration is BuiltinTypeBuilder) {
// Type arguments on a built-in type, for example, dynamic or void.
expected = 0;
} else {
return unhandled(
"${declaration.runtimeType}",
"TypeDeclarationAccessor.buildType",
offsetForToken(token),
helper.uri);
}
if (arguments.length != expected) {
helper.warnTypeArgumentsMismatch(
declaration.name, expected, offsetForToken(token));
// We ignore the provided arguments, which will in turn return the
// raw type below.
// TODO(sigmund): change to use an InvalidType and include the raw type
// as a recovery node once the IR can represent it (Issue #29840).
arguments = null;
}
}
DartType type;
if (arguments == null) {
TypeDeclarationBuilder typeDeclaration = declaration;
if (typeDeclaration is KernelClassBuilder) {
type = typeDeclaration.buildType(helper.library, null);
} else if (typeDeclaration is KernelFunctionTypeAliasBuilder) {
type = typeDeclaration.buildType(helper.library, null);
}
}
if (type == null) {
type =
declaration.buildTypesWithBuiltArguments(helper.library, arguments);
}
if (type is TypeParameterType) {
return helper.validatedTypeVariableUse(
type, offsetForToken(token), nonInstanceAccessIsError);
}
return type;
}
@override
kernel.Expression doInvocation(int offset, Arguments arguments) {
return helper.buildConstructorInvocation(declaration, token, arguments, "",
null, token.charOffset, Constness.implicit);
}
}
kernel.Expression makeLet(
VariableDeclaration variable, kernel.Expression body) {
if (variable == null) return body;
@ -1911,3 +2281,13 @@ VariableDeclaration makeOrReuseVariable(kernel.Expression value) {
// or is fresh (hence needs a let binding).
return new VariableDeclaration.forValue(value);
}
int adjustForImplicitCall(String name, int offset) {
// Normally the offset is at the start of the token, but in this case,
// because we insert a '.call', we want it at the end instead.
return offset + (name?.length ?? 0);
}
bool isFieldOrGetter(Member member) {
return member is Field || (member is Procedure && member.isGetter);
}

View file

@ -0,0 +1,154 @@
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library fasta.expression_generator_helper;
import '../../scanner/token.dart' show Token;
import '../constant_context.dart' show ConstantContext;
import '../fasta_codes.dart' show LocatedMessage;
import '../messages.dart' show Message;
import '../scope.dart' show ProblemBuilder, Scope;
import '../type_inference/type_promotion.dart' show TypePromoter;
import 'constness.dart' show Constness;
import 'forest.dart' show Forest;
import 'kernel_builder.dart' show PrefixBuilder;
import 'kernel_ast_api.dart'
show
Constructor,
DartType,
FunctionNode,
FunctionType,
Initializer,
Member,
Name,
Procedure,
StaticGet,
TypeParameter,
TypeParameterType;
import 'kernel_builder.dart'
show
KernelPrefixBuilder,
LibraryBuilder,
PrefixBuilder,
TypeDeclarationBuilder;
// TODO(ahe): Rename to ExpressionGeneratorHelper.
abstract class BuilderHelper<Expression, Statement, Arguments> {
LibraryBuilder get library;
Uri get uri;
TypePromoter get typePromoter;
int get functionNestingLevel;
ConstantContext get constantContext;
Forest<Expression, Statement, Token, Arguments> get forest;
Constructor lookupConstructor(Name name, {bool isSuper});
Expression toValue(node);
Member lookupInstanceMember(Name name, {bool isSetter, bool isSuper});
scopeLookup(Scope scope, String name, Token token,
{bool isQualified: false, PrefixBuilder prefix});
finishSend(Object receiver, Arguments arguments, int offset);
Expression buildCompileTimeError(Message message, int charOffset, int length,
{List<LocatedMessage> context});
Expression wrapInCompileTimeError(Expression expression, Message message);
Expression deprecated_buildCompileTimeError(String error, [int offset]);
Initializer buildInvalidInitializer(Expression expression, [int offset]);
Initializer buildFieldInitializer(
bool isSynthetic, String name, int offset, Expression expression);
Initializer buildSuperInitializer(
bool isSynthetic, Constructor constructor, Arguments arguments,
[int offset]);
Initializer buildRedirectingInitializer(
Constructor constructor, Arguments arguments,
[int charOffset = -1]);
Expression buildStaticInvocation(Procedure target, Arguments arguments,
{Constness constness, int charOffset, Member initialTarget});
Expression buildProblemExpression(
ProblemBuilder builder, int offset, int length);
Expression throwNoSuchMethodError(
Expression receiver, String name, Arguments arguments, int offset,
{Member candidate,
bool isSuper,
bool isGetter,
bool isSetter,
bool isStatic,
LocatedMessage argMessage});
LocatedMessage checkArgumentsForFunction(FunctionNode function,
Arguments arguments, int offset, List<TypeParameter> typeParameters);
LocatedMessage checkArgumentsForType(
FunctionType function, Arguments arguments, int offset);
StaticGet makeStaticGet(Member readTarget, Token token);
Expression wrapInDeferredCheck(
Expression expression, KernelPrefixBuilder prefix, int charOffset);
dynamic deprecated_addCompileTimeError(int charOffset, String message);
bool isIdentical(Member member);
Expression buildMethodInvocation(
Expression receiver, Name name, Arguments arguments, int offset,
{bool isConstantExpression,
bool isNullAware,
bool isImplicitCall,
bool isSuper,
Member interfaceTarget});
Expression buildConstructorInvocation(
TypeDeclarationBuilder type,
Token nameToken,
Arguments arguments,
String name,
List<DartType> typeArguments,
int charOffset,
Constness constness);
DartType validatedTypeVariableUse(
TypeParameterType type, int offset, bool nonInstanceAccessIsError);
void addProblem(Message message, int charOffset, int length);
void addProblemErrorIfConst(Message message, int charOffset, int length);
Message warnUnresolvedGet(Name name, int charOffset, {bool isSuper});
Message warnUnresolvedSet(Name name, int charOffset, {bool isSuper});
Message warnUnresolvedMethod(Name name, int charOffset, {bool isSuper});
void warnTypeArgumentsMismatch(String name, int expected, int charOffset);
T storeOffset<T>(T node, int offset);
}

View file

@ -1,496 +0,0 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of 'expression_generator.dart';
abstract class BuilderHelper<Expression, Statement, Arguments> {
LibraryBuilder get library;
Uri get uri;
TypePromoter get typePromoter;
int get functionNestingLevel;
ConstantContext get constantContext;
Forest<Expression, Statement, Token, Arguments> get forest;
Constructor lookupConstructor(Name name, {bool isSuper});
Expression toValue(node);
Member lookupInstanceMember(Name name, {bool isSetter, bool isSuper});
scopeLookup(Scope scope, String name, Token token,
{bool isQualified: false, PrefixBuilder prefix});
finishSend(Object receiver, Arguments arguments, int offset);
Expression buildCompileTimeError(Message message, int charOffset, int length,
{List<LocatedMessage> context});
Expression wrapInCompileTimeError(Expression expression, Message message);
Expression deprecated_buildCompileTimeError(String error, [int offset]);
Initializer buildInvalidInitializer(Expression expression, [int offset]);
Initializer buildFieldInitializer(
bool isSynthetic, String name, int offset, Expression expression);
Initializer buildSuperInitializer(
bool isSynthetic, Constructor constructor, Arguments arguments,
[int offset]);
Initializer buildRedirectingInitializer(
Constructor constructor, Arguments arguments,
[int charOffset = -1]);
Expression buildStaticInvocation(Procedure target, Arguments arguments,
{Constness constness, int charOffset, Member initialTarget});
Expression buildProblemExpression(
ProblemBuilder builder, int offset, int length);
Expression throwNoSuchMethodError(
Expression receiver, String name, Arguments arguments, int offset,
{Member candidate,
bool isSuper,
bool isGetter,
bool isSetter,
bool isStatic,
LocatedMessage argMessage});
LocatedMessage checkArgumentsForFunction(FunctionNode function,
Arguments arguments, int offset, List<TypeParameter> typeParameters);
LocatedMessage checkArgumentsForType(
FunctionType function, Arguments arguments, int offset);
StaticGet makeStaticGet(Member readTarget, Token token);
Expression wrapInDeferredCheck(
Expression expression, KernelPrefixBuilder prefix, int charOffset);
dynamic deprecated_addCompileTimeError(int charOffset, String message);
bool isIdentical(Member member);
Expression buildMethodInvocation(
Expression receiver, Name name, Arguments arguments, int offset,
{bool isConstantExpression,
bool isNullAware,
bool isImplicitCall,
bool isSuper,
Member interfaceTarget});
Expression buildConstructorInvocation(
TypeDeclarationBuilder type,
Token nameToken,
Arguments arguments,
String name,
List<DartType> typeArguments,
int charOffset,
Constness constness);
DartType validatedTypeVariableUse(
TypeParameterType type, int offset, bool nonInstanceAccessIsError);
void addProblem(Message message, int charOffset, int length);
void addProblemErrorIfConst(Message message, int charOffset, int length);
Message warnUnresolvedGet(Name name, int charOffset, {bool isSuper});
Message warnUnresolvedSet(Name name, int charOffset, {bool isSuper});
Message warnUnresolvedMethod(Name name, int charOffset, {bool isSuper});
void warnTypeArgumentsMismatch(String name, int expected, int charOffset);
T storeOffset<T>(T node, int offset);
}
class IncompleteError<Arguments> extends IncompleteSendGenerator<Arguments>
with ErroneousExpressionGenerator<Arguments> {
final Message message;
IncompleteError(BuilderHelper<dynamic, dynamic, Arguments> helper,
Token token, this.message)
: super(helper, token, null);
String get debugName => "IncompleteError";
@override
kernel.Expression buildError(Arguments arguments,
{bool isGetter: false, bool isSetter: false, int offset}) {
int length = noLength;
if (offset == null) {
offset = offsetForToken(token);
length = lengthForToken(token);
}
return helper.buildCompileTimeError(message, offset, length);
}
@override
DartType buildErroneousTypeNotAPrefix(Identifier suffix) {
helper.addProblem(
templateNotAPrefixInTypeAnnotation.withArguments(
token.lexeme, suffix.name),
offsetForToken(token),
lengthOfSpan(token, suffix.token));
return const InvalidType();
}
@override
doInvocation(int offset, Arguments arguments) => this;
@override
void printOn(StringSink sink) {
sink.write(", message: ");
sink.write(message.code.name);
}
}
class SendAccessor<Arguments> extends IncompleteSendGenerator<Arguments> {
@override
final Arguments arguments;
SendAccessor(BuilderHelper<dynamic, dynamic, Arguments> helper, Token token,
Name name, this.arguments)
: super(helper, token, name) {
assert(arguments != null);
}
String get plainNameForRead => name.name;
String get debugName => "SendAccessor";
kernel.Expression buildSimpleRead() {
return unsupported("buildSimpleRead", offsetForToken(token), uri);
}
kernel.Expression buildAssignment(kernel.Expression value,
{bool voidContext: false}) {
return unsupported("buildAssignment", offsetForToken(token), uri);
}
withReceiver(Object receiver, int operatorOffset, {bool isNullAware: false}) {
if (receiver is Generator) {
return receiver.buildPropertyAccess(this, operatorOffset, isNullAware);
}
if (receiver is PrefixBuilder) {
PrefixBuilder prefix = receiver;
if (isNullAware) {
helper.deprecated_addCompileTimeError(
offsetForToken(token),
"Library prefix '${prefix.name}' can't be used with null-aware "
"operator.\nTry removing '?'.");
}
receiver = helper.scopeLookup(prefix.exportScope, name.name, token,
isQualified: true, prefix: prefix);
return helper.finishSend(receiver, arguments, offsetForToken(token));
}
return helper.buildMethodInvocation(
helper.toValue(receiver), name, arguments, offsetForToken(token),
isNullAware: isNullAware);
}
kernel.Expression buildNullAwareAssignment(
kernel.Expression value, DartType type, int offset,
{bool voidContext: false}) {
return unsupported("buildNullAwareAssignment", offset, uri);
}
kernel.Expression buildCompoundAssignment(
Name binaryOperator, kernel.Expression value,
{int offset,
bool voidContext: false,
Procedure interfaceTarget,
bool isPreIncDec: false}) {
return unsupported(
"buildCompoundAssignment", offset ?? offsetForToken(token), uri);
}
kernel.Expression buildPrefixIncrement(Name binaryOperator,
{int offset, bool voidContext: false, Procedure interfaceTarget}) {
return unsupported(
"buildPrefixIncrement", offset ?? offsetForToken(token), uri);
}
kernel.Expression buildPostfixIncrement(Name binaryOperator,
{int offset, bool voidContext: false, Procedure interfaceTarget}) {
return unsupported(
"buildPostfixIncrement", offset ?? offsetForToken(token), uri);
}
kernel.Expression doInvocation(int offset, Arguments arguments) {
return unsupported("doInvocation", offset, uri);
}
@override
void printOn(StringSink sink) {
super.printOn(sink);
sink.write(", arguments: ");
var node = arguments;
if (node is kernel.Node) {
printNodeOn(node, sink);
} else {
sink.write(node);
}
}
}
class IncompletePropertyAccessor<Arguments>
extends IncompleteSendGenerator<Arguments> {
IncompletePropertyAccessor(
BuilderHelper<dynamic, dynamic, Arguments> helper, Token token, Name name)
: super(helper, token, name);
String get plainNameForRead => name.name;
String get debugName => "IncompletePropertyAccessor";
kernel.Expression buildSimpleRead() {
return unsupported("buildSimpleRead", offsetForToken(token), uri);
}
kernel.Expression buildAssignment(kernel.Expression value,
{bool voidContext: false}) {
return unsupported("buildAssignment", offsetForToken(token), uri);
}
withReceiver(Object receiver, int operatorOffset, {bool isNullAware: false}) {
if (receiver is Generator) {
return receiver.buildPropertyAccess(this, operatorOffset, isNullAware);
}
if (receiver is PrefixBuilder) {
PrefixBuilder prefix = receiver;
if (isNullAware) {
helper.deprecated_addCompileTimeError(
offsetForToken(token),
"Library prefix '${prefix.name}' can't be used with null-aware "
"operator.\nTry removing '?'.");
}
return helper.scopeLookup(prefix.exportScope, name.name, token,
isQualified: true, prefix: prefix);
}
return PropertyAccessGenerator.make(
helper, token, helper.toValue(receiver), name, null, null, isNullAware);
}
kernel.Expression buildNullAwareAssignment(
kernel.Expression value, DartType type, int offset,
{bool voidContext: false}) {
return unsupported("buildNullAwareAssignment", offset, uri);
}
kernel.Expression buildCompoundAssignment(
Name binaryOperator, kernel.Expression value,
{int offset,
bool voidContext: false,
Procedure interfaceTarget,
bool isPreIncDec: false}) {
return unsupported(
"buildCompoundAssignment", offset ?? offsetForToken(token), uri);
}
kernel.Expression buildPrefixIncrement(Name binaryOperator,
{int offset, bool voidContext: false, Procedure interfaceTarget}) {
return unsupported(
"buildPrefixIncrement", offset ?? offsetForToken(token), uri);
}
kernel.Expression buildPostfixIncrement(Name binaryOperator,
{int offset, bool voidContext: false, Procedure interfaceTarget}) {
return unsupported(
"buildPostfixIncrement", offset ?? offsetForToken(token), uri);
}
kernel.Expression doInvocation(int offset, Arguments arguments) {
return unsupported("doInvocation", offset, uri);
}
}
int adjustForImplicitCall(String name, int offset) {
// Normally the offset is at the start of the token, but in this case,
// because we insert a '.call', we want it at the end instead.
return offset + (name?.length ?? 0);
}
class ParenthesizedExpression<Arguments>
extends ReadOnlyAccessGenerator<Arguments> {
ParenthesizedExpression(BuilderHelper<dynamic, dynamic, Arguments> helper,
Token token, kernel.Expression expression)
: super(helper, token, expression, null);
String get debugName => "ParenthesizedExpression";
kernel.Expression makeInvalidWrite(kernel.Expression value) {
return helper.deprecated_buildCompileTimeError(
"Can't assign to a parenthesized expression.", offsetForToken(token));
}
}
class TypeDeclarationAccessor<Arguments>
extends ReadOnlyAccessGenerator<Arguments> {
/// The import prefix preceding the [declaration] reference, or `null` if
/// the reference is not prefixed.
final PrefixBuilder prefix;
/// The offset at which the [declaration] is referenced by this generator,
/// or `-1` if the reference is implicit.
final int declarationReferenceOffset;
final TypeDeclarationBuilder declaration;
TypeDeclarationAccessor(
BuilderHelper<dynamic, dynamic, Arguments> helper,
Token token,
this.prefix,
this.declarationReferenceOffset,
this.declaration,
String plainNameForRead)
: super(helper, token, null, plainNameForRead);
String get debugName => "TypeDeclarationAccessor";
kernel.Expression get expression {
if (super.expression == null) {
int offset = offsetForToken(token);
if (declaration is KernelInvalidTypeBuilder) {
KernelInvalidTypeBuilder declaration = this.declaration;
helper.addProblemErrorIfConst(
declaration.message.messageObject, offset, token.length);
super.expression =
new Throw(forest.literalString(declaration.message.message, token))
..fileOffset = offset;
} else {
super.expression = forest.literalType(
buildTypeWithBuiltArguments(null, nonInstanceAccessIsError: true),
token);
}
}
return super.expression;
}
kernel.Expression makeInvalidWrite(kernel.Expression value) {
return buildThrowNoSuchMethodError(
forest.literalNull(token),
storeOffset(forest.arguments(<kernel.Expression>[value], null),
value.fileOffset),
isSetter: true);
}
@override
buildPropertyAccess(
IncompleteSendGenerator send, int operatorOffset, 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);
Generator generator;
if (builder == null) {
// If we find a setter, [builder] is an [AccessErrorBuilder], not null.
if (send is IncompletePropertyAccessor) {
generator = new UnresolvedNameGenerator(helper, send.token, name);
} else {
return helper.buildConstructorInvocation(declaration, send.token,
arguments, name.name, null, token.charOffset, Constness.implicit);
}
} 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;
}
generator = new StaticAccessGenerator.fromBuilder(
helper, builder, send.token, setter);
}
return arguments == null
? generator
: generator.doInvocation(offsetForToken(send.token), arguments);
} else {
return super.buildPropertyAccess(send, operatorOffset, isNullAware);
}
}
@override
DartType buildTypeWithBuiltArguments(List<DartType> arguments,
{bool nonInstanceAccessIsError: false}) {
if (arguments != null) {
int expected = 0;
if (declaration is KernelClassBuilder) {
expected = declaration.target.typeParameters.length;
} else if (declaration is FunctionTypeAliasBuilder) {
expected = declaration.target.typeParameters.length;
} else if (declaration is KernelTypeVariableBuilder) {
// Type arguments on a type variable - error reported elsewhere.
} else if (declaration is BuiltinTypeBuilder) {
// Type arguments on a built-in type, for example, dynamic or void.
expected = 0;
} else {
return unhandled(
"${declaration.runtimeType}",
"TypeDeclarationAccessor.buildType",
offsetForToken(token),
helper.uri);
}
if (arguments.length != expected) {
helper.warnTypeArgumentsMismatch(
declaration.name, expected, offsetForToken(token));
// We ignore the provided arguments, which will in turn return the
// raw type below.
// TODO(sigmund): change to use an InvalidType and include the raw type
// as a recovery node once the IR can represent it (Issue #29840).
arguments = null;
}
}
DartType type;
if (arguments == null) {
TypeDeclarationBuilder typeDeclaration = declaration;
if (typeDeclaration is KernelClassBuilder) {
type = typeDeclaration.buildType(helper.library, null);
} else if (typeDeclaration is KernelFunctionTypeAliasBuilder) {
type = typeDeclaration.buildType(helper.library, null);
}
}
if (type == null) {
type =
declaration.buildTypesWithBuiltArguments(helper.library, arguments);
}
if (type is TypeParameterType) {
return helper.validatedTypeVariableUse(
type, offsetForToken(token), nonInstanceAccessIsError);
}
return type;
}
@override
kernel.Expression doInvocation(int offset, Arguments arguments) {
return helper.buildConstructorInvocation(declaration, token, arguments, "",
null, token.charOffset, Constness.implicit);
}
}
bool isFieldOrGetter(Member member) {
return member is Field || (member is Procedure && member.isGetter);
}

View file

@ -9,6 +9,8 @@ import 'package:kernel/ast.dart' as kernel show Arguments, DartType;
import 'body_builder.dart' show Identifier;
export 'body_builder.dart' show Identifier, Operator;
/// A tree factory.
///
/// For now, the [Location] is always a token.

View file

@ -67,7 +67,9 @@ import '../type_inference/type_schema_environment.dart'
import 'body_builder.dart' show combineStatements;
import 'expression_generator.dart' show BuilderHelper, makeLet;
import 'expression_generator.dart' show makeLet;
import 'expression_generator_helper.dart' show BuilderHelper;
/// Indicates whether type inference involving conditional expressions should
/// always use least upper bound.

View file

@ -62,7 +62,9 @@ import '../../base/instrumentation.dart'
import '../fasta_codes.dart';
import '../kernel/expression_generator.dart' show BuilderHelper, buildIsNull;
import '../kernel/expression_generator.dart' show buildIsNull;
import '../kernel/expression_generator_helper.dart' show BuilderHelper;
import '../kernel/kernel_shadow_ast.dart'
show