| Index: pkg/front_end/lib/src/fasta/kernel/body_builder.dart
|
| diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
|
| index 21e00f59580a008ed96a87404c6527c78fbffda0..3c752468826ce82d7294b461f4611afc65aadd76 100644
|
| --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
|
| +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
|
| @@ -30,7 +30,7 @@ import '../errors.dart' show formatUnexpected, internalError;
|
| import '../source/scope_listener.dart'
|
| show JumpTargetKind, NullValue, ScopeListener;
|
|
|
| -import '../builder/scope.dart' show AccessErrorBuilder, AmbiguousBuilder, Scope;
|
| +import '../builder/scope.dart' show ProblemBuilder, Scope;
|
|
|
| import '../source/outline_builder.dart' show asyncMarkerFromTokens;
|
|
|
| @@ -110,8 +110,6 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|
|
| Scope formalParameterScope;
|
|
|
| - bool isFirstIdentifier = false;
|
| -
|
| bool inInitializer = false;
|
|
|
| bool inCatchClause = false;
|
| @@ -153,7 +151,6 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|
|
| @override
|
| void push(Object node) {
|
| - isFirstIdentifier = false;
|
| inInitializer = false;
|
| super.push(node);
|
| }
|
| @@ -197,6 +194,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| return node;
|
| } else if (node is PrefixBuilder) {
|
| return buildCompileTimeError("A library can't be used as an expression.");
|
| + } else if (node is ProblemBuilder) {
|
| + return buildProblemExpression(node, -1);
|
| } else {
|
| return internalError("Unhandled: ${node.runtimeType}");
|
| }
|
| @@ -713,23 +712,10 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| }
|
|
|
| @override
|
| - void beginExpression(Token token) {
|
| - debugEvent("beginExpression");
|
| - isFirstIdentifier = true;
|
| - }
|
| -
|
| - Builder computeSetter(
|
| - Builder builder, Scope scope, String name, int charOffset) {
|
| - if (builder.isSetter) return builder;
|
| - if (builder.isGetter) return scope.lookupSetter(name, charOffset, uri);
|
| - return builder.isField ? (builder.isFinal ? null : builder) : null;
|
| - }
|
| -
|
| - @override
|
| void handleIdentifier(Token token, IdentifierContext context) {
|
| debugEvent("handleIdentifier");
|
| String name = token.lexeme;
|
| - if (isFirstIdentifier) {
|
| + if (context.isScopeReference) {
|
| assert(!inInitializer ||
|
| this.scope == enclosingScope ||
|
| this.scope.parent == enclosingScope);
|
| @@ -772,17 +758,16 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| return new StaticAccessor(
|
| this, charOffset, builder.getter.target, builder.setter.target);
|
| } else {
|
| - if (builder is AccessErrorBuilder) {
|
| - AccessErrorBuilder error = builder;
|
| - builder = error.builder;
|
| - }
|
| - if (builder.target == null) {
|
| - return internalError("Unhandled: ${builder}");
|
| + if (builder.hasProblem && builder is! AccessErrorBuilder) return builder;
|
| + Builder setter;
|
| + if (builder.isSetter) {
|
| + setter = builder;
|
| + } else if (builder.isGetter) {
|
| + setter = scope.lookupSetter(name, charOffset, uri);
|
| + } else if (builder.isField && !builder.isFinal) {
|
| + setter = builder;
|
| }
|
| - Member getter = builder.target.hasGetter ? builder.target : null;
|
| - Member setter = builder.target.hasSetter ? builder.target : null;
|
| - setter ??= computeSetter(builder, scope, name, charOffset)?.target;
|
| - return new StaticAccessor(this, charOffset, getter, setter);
|
| + return new StaticAccessor.fromBuilder(this, builder, charOffset, setter);
|
| }
|
| }
|
|
|
| @@ -820,8 +805,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| List<Expression> expressions = <Expression>[];
|
| // Contains more than just \' or \".
|
| if (first.lexeme.length > 1) {
|
| - expressions
|
| - .add(new StringLiteral(unescapeFirstStringPart(first.lexeme, quote)));
|
| + expressions.add(
|
| + new StringLiteral(unescapeFirstStringPart(first.lexeme, quote)));
|
| }
|
| for (int i = 1; i < parts.length - 1; i++) {
|
| var part = parts[i];
|
| @@ -836,7 +821,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| // Contains more than just \' or \".
|
| if (last.lexeme.length > 1) {
|
| expressions
|
| - .add(new StringLiteral(unescapeLastStringPart(last.lexeme, quote)));
|
| + .add(new StringLiteral(unescapeLastStringPart(last.lexeme, quote)));
|
| }
|
| push(new StringConcatenation(expressions)
|
| ..fileOffset = endToken.charOffset);
|
| @@ -997,6 +982,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| push(wrapInvalid(new TypeLiteral(
|
| accessor.buildTypesWithBuiltArguments(library, null))));
|
| } else if (accessor is! BuilderAccessor) {
|
| + print(accessor);
|
| push(buildCompileTimeError("Can't assign to this.", token.charOffset));
|
| } else {
|
| push(new DelayedAssignment(
|
| @@ -1159,11 +1145,6 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| push(new MapEntry(key, value));
|
| }
|
|
|
| - @override
|
| - void beginLiteralSymbol(Token token) {
|
| - isFirstIdentifier = false;
|
| - }
|
| -
|
| String symbolPartToString(name) {
|
| if (name is Identifier) {
|
| return name.name;
|
| @@ -1190,17 +1171,28 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| push(new SymbolLiteral(value));
|
| }
|
|
|
| - DartType toKernelType(String name, List<DartType> arguments, int charOffset) {
|
| + DartType kernelTypeFromString(
|
| + String name, List<DartType> arguments, int charOffset) {
|
| if (identical(name, "void")) return const VoidType();
|
| if (identical(name, "dynamic")) return const DynamicType();
|
| Builder builder = scope.lookup(name, charOffset, uri);
|
| - if (builder is TypeDeclarationBuilder) {
|
| - return builder.buildTypesWithBuiltArguments(library, arguments);
|
| - }
|
| if (builder == null) {
|
| warning("Type not found: '$name'.", charOffset);
|
| + return const DynamicType();
|
| } else {
|
| - warning("Not a type: '$name'.", charOffset);
|
| + return kernelTypeFromBuilder(builder, arguments, charOffset);
|
| + }
|
| + }
|
| +
|
| + DartType kernelTypeFromBuilder(
|
| + Builder builder, List<DartType> arguments, int charOffset) {
|
| + if (builder is TypeDeclarationBuilder) {
|
| + return builder.buildTypesWithBuiltArguments(library, arguments);
|
| + } else if (builder.hasProblem) {
|
| + ProblemBuilder problem = builder;
|
| + addCompileTimeError(charOffset, problem.message);
|
| + } else {
|
| + warning("Not a type: '${builder.fullNameForErrors}'.", charOffset);
|
| }
|
| // TODO(ahe): Create an error somehow.
|
| return const DynamicType();
|
| @@ -1231,7 +1223,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| builder = scope.lookup(prefix, beginToken.charOffset, uri);
|
| }
|
| if (builder is PrefixBuilder) {
|
| - name = builder.exports[suffix];
|
| + name = builderToFirstExpression(builder.exports[suffix], suffix, beginToken.charOffset, isPrefix: true);
|
| } else {
|
| push(const DynamicType());
|
| addCompileTimeError(beginToken.charOffset,
|
| @@ -1254,8 +1246,12 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| push(name.buildTypesWithBuiltArguments(library, arguments));
|
| } else if (name is TypeBuilder) {
|
| push(name.build(library));
|
| + } else if (name is Builder) {
|
| + push(kernelTypeFromBuilder(name, arguments, beginToken.charOffset));
|
| + } else if (name is String) {
|
| + push(kernelTypeFromString(name, arguments, beginToken.charOffset));
|
| } else {
|
| - push(toKernelType(name, arguments, beginToken.charOffset));
|
| + internalError("Unhandled: '${name.runtimeType}'.");
|
| }
|
| if (peek() is TypeParameterType) {
|
| TypeParameterType type = peek();
|
| @@ -1634,7 +1630,6 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|
|
| bool checkArguments(FunctionNode function, Arguments arguments,
|
| List<TypeParameter> typeParameters) {
|
| -
|
| if (arguments.positional.length < function.requiredParameterCount ||
|
| arguments.positional.length > function.positionalParameters.length) {
|
| return false;
|
| @@ -1731,9 +1726,9 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| }
|
|
|
| @override
|
| - void handleThisExpression(Token token) {
|
| + void handleThisExpression(Token token, IdentifierContext context) {
|
| debugEvent("ThisExpression");
|
| - if (isFirstIdentifier && isInstanceContext) {
|
| + if (context.isScopeReference && isInstanceContext) {
|
| push(new ThisAccessor(this, token.charOffset, inInitializer));
|
| } else {
|
| push(new IncompleteError(
|
| @@ -1742,9 +1737,9 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| }
|
|
|
| @override
|
| - void handleSuperExpression(Token token) {
|
| + void handleSuperExpression(Token token, IdentifierContext context) {
|
| debugEvent("SuperExpression");
|
| - if (isFirstIdentifier && isInstanceContext) {
|
| + if (context.isScopeReference && isInstanceContext) {
|
| Member member = this.member.target;
|
| member.transformerFlags |= TransformerFlag.superCalls;
|
| push(new ThisAccessor(this, token.charOffset, inInitializer,
|
| @@ -2268,14 +2263,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| }
|
|
|
| @override
|
| - Expression buildProblemExpression(Builder builder, String name) {
|
| - if (builder is AmbiguousBuilder) {
|
| - return buildCompileTimeError("Duplicated named: '$name'.");
|
| - } else if (builder is AccessErrorBuilder) {
|
| - return buildCompileTimeError("Access error: '$name'.");
|
| - } else {
|
| - return internalError("Unhandled: ${builder.runtimeType}");
|
| - }
|
| + Expression buildProblemExpression(ProblemBuilder builder, int charOffset) {
|
| + return buildCompileTimeError(builder.message, charOffset);
|
| }
|
|
|
| @override
|
| @@ -2395,8 +2384,7 @@ abstract class ContextAccessor extends BuilderAccessor {
|
| String get plainNameForRead => internalError("Unsupported operation.");
|
|
|
| Expression doInvocation(int charOffset, Arguments arguments) {
|
| - print("$uri:$charOffset: Internal error: Unhandled: ${runtimeType}");
|
| - return internalError("Unhandled: ${runtimeType}");
|
| + return internalError("Unhandled: ${runtimeType}", uri, charOffset);
|
| }
|
|
|
| Expression buildSimpleRead();
|
| @@ -2591,6 +2579,9 @@ class JumpTarget extends Builder {
|
| }
|
| users.clear();
|
| }
|
| +
|
| + @override
|
| + String get fullNameForErrors => "<jump-target>";
|
| }
|
|
|
| class LabelTarget extends Builder implements JumpTarget {
|
| @@ -2642,6 +2633,9 @@ class LabelTarget extends Builder implements JumpTarget {
|
| void resolveGotos(SwitchCase target) {
|
| internalError("Unsupported operation.");
|
| }
|
| +
|
| + @override
|
| + String get fullNameForErrors => "<label-target>";
|
| }
|
|
|
| class OptionalFormals {
|
|
|