Chromium Code Reviews| Index: pkg/front_end/lib/src/fasta/source/outline_builder.dart |
| diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart |
| index f14505d31162da0c070381b73937e3b54d16d987..e38ba7f735ebcc630c3d8d000571f12263e51e4c 100644 |
| --- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart |
| +++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart |
| @@ -8,6 +8,8 @@ import 'package:kernel/ast.dart' show AsyncMarker, ProcedureKind; |
| import '../parser/parser.dart' show FormalParameterType, optional; |
| +import '../parser/identifier_context.dart' show IdentifierContext; |
| + |
| import '../scanner/token.dart' show Token; |
| import '../util/link.dart' show Link; |
| @@ -74,20 +76,36 @@ class OutlineBuilder extends UnhandledListener { |
| Uri get uri => library.fileUri; |
| @override |
| + int popCharOffset() => pop(); |
| + |
| + List<String> popIdentifierList(int count) { |
| + if (count == 0) return null; |
| + List<String> list = new List<String>.filled(count, null, growable: true); |
| + for (int i = count - 1; i >= 0; i--) { |
| + popCharOffset(); |
| + list[i] = pop(); |
| + } |
| + return list; |
| + } |
| + |
| + @override |
| void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { |
| debugEvent("Metadata"); |
| List arguments = pop(); |
| + popIfNotNull(periodBeforeName); // charOffset. |
| String postfix = popIfNotNull(periodBeforeName); |
| List<TypeBuilder> typeArguments = pop(); |
| if (arguments == null) { |
| + int charOffset = pop(); |
| String expression = pop(); |
| push(new MetadataBuilder.fromExpression( |
| - expression, postfix, library, beginToken.charOffset)); |
| + expression, postfix, library, charOffset)); |
| } else { |
| + int charOffset = pop(); |
| String typeName = pop(); |
| push(new MetadataBuilder.fromConstructor( |
| library.addConstructorReference( |
| - typeName, typeArguments, postfix, beginToken.next.charOffset), |
| + typeName, typeArguments, postfix, charOffset), |
| arguments, |
| library, |
| beginToken.charOffset)); |
| @@ -119,6 +137,7 @@ class OutlineBuilder extends UnhandledListener { |
| debugEvent("Export"); |
| List<Combinator> combinators = pop(); |
| Unhandled conditionalUris = pop(); |
| + popCharOffset(); |
| String uri = pop(); |
| List<MetadataBuilder> metadata = pop(); |
| if (uri != null) { |
| @@ -133,20 +152,15 @@ class OutlineBuilder extends UnhandledListener { |
| Token semicolon) { |
| debugEvent("endImport"); |
| List<Combinator> combinators = pop(); |
| + int prefixOffset = popIfNotNull(asKeyword) ?? -1; |
| String prefix = popIfNotNull(asKeyword); |
| Unhandled conditionalUris = pop(); |
| + popCharOffset(); |
| String uri = pop(); |
| List<MetadataBuilder> metadata = pop(); |
| if (uri != null) { |
| - library.addImport( |
| - metadata, |
| - uri, |
| - conditionalUris, |
| - prefix, |
| - combinators, |
| - deferredKeyword != null, |
| - importKeyword.charOffset, |
| - asKeyword?.next?.charOffset ?? -1); |
| + library.addImport(metadata, uri, conditionalUris, prefix, combinators, |
| + deferredKeyword != null, importKeyword.charOffset, prefixOffset); |
| } |
| checkEmpty(importKeyword.charOffset); |
| } |
| @@ -155,11 +169,13 @@ class OutlineBuilder extends UnhandledListener { |
| void handleRecoverExpression(Token token) { |
| debugEvent("RecoverExpression"); |
| push(NullValue.Expression); |
| + push(token.charOffset); |
| } |
| @override |
| void endPart(Token partKeyword, Token semicolon) { |
| debugEvent("Part"); |
| + popCharOffset(); |
| String uri = pop(); |
| List<MetadataBuilder> metadata = pop(); |
| if (uri != null) { |
| @@ -172,25 +188,68 @@ class OutlineBuilder extends UnhandledListener { |
| void handleOperatorName(Token operatorKeyword, Token token) { |
| debugEvent("OperatorName"); |
| push(operatorFromString(token.stringValue)); |
| + push(token.charOffset); |
| + } |
| + |
| + @override |
| + void handleIdentifier(Token token, IdentifierContext context) { |
| + super.handleIdentifier(token, context); |
| + push(token.charOffset); |
| + } |
| + |
| + @override |
| + void handleNoName(Token token) { |
| + super.handleNoName(token); |
| + push(token.charOffset); |
| + } |
| + |
| + @override |
| + void endLiteralString(int interpolationCount, Token endToken) { |
| + debugEvent("endLiteralString"); |
| + if (interpolationCount == 0) { |
| + Token token = pop(); |
| + push(unescapeString(token.lexeme)); |
| + push(token.charOffset); |
| + } else { |
| + internalError("String interpolation not implemented."); |
| + } |
| + } |
| + |
| + @override |
| + void handleStringJuxtaposition(int literalCount) { |
| + debugEvent("StringJuxtaposition"); |
| + List<String> list = |
| + new List<String>.filled(literalCount, null, growable: false); |
| + int charOffset = -1; |
| + for (int i = literalCount - 1; i >= 0; i--) { |
| + charOffset = pop(); |
| + list[i] = pop(); |
| + } |
| + push(list.join("")); |
| + push(charOffset); |
| } |
| @override |
| void endIdentifierList(int count) { |
| debugEvent("endIdentifierList"); |
| - push(popList(count) ?? NullValue.IdentifierList); |
| + push(popIdentifierList(count) ?? NullValue.IdentifierList); |
| } |
| @override |
| void handleQualified(Token period) { |
| debugEvent("handleQualified"); |
| + int charOffset = pop(); |
| String name = pop(); |
| + charOffset = pop(); // We just want the charOffset of receiver. |
| String receiver = pop(); |
| push("$receiver.$name"); |
| + push(charOffset); |
| } |
| @override |
| void endLibraryName(Token libraryKeyword, Token semicolon) { |
| debugEvent("endLibraryName"); |
| + popCharOffset(); |
| String name = pop(); |
| List<MetadataBuilder> metadata = pop(); |
| library.name = name; |
| @@ -214,6 +273,7 @@ class OutlineBuilder extends UnhandledListener { |
| List<TypeBuilder> interfaces = popList(interfacesCount); |
| TypeBuilder supertype = pop(); |
| List<TypeVariableBuilder> typeVariables = pop(); |
| + int charOffset = pop(); |
| String name = pop(); |
| if (typeVariables != null && supertype is MixinApplicationBuilder) { |
| supertype.typeVariables = typeVariables; |
| @@ -222,7 +282,7 @@ class OutlineBuilder extends UnhandledListener { |
| int modifiers = Modifier.validate(pop()); |
| List<MetadataBuilder> metadata = pop(); |
| library.addClass(metadata, modifiers, name, typeVariables, supertype, |
| - interfaces, classKeyword.next?.charOffset ?? beginToken.charOffset); |
| + interfaces, charOffset); |
| checkEmpty(beginToken.charOffset); |
| } |
| @@ -246,6 +306,7 @@ class OutlineBuilder extends UnhandledListener { |
| List<FormalParameterBuilder> formals = pop(); |
| int formalsOffset = pop(); |
| List<TypeVariableBuilder> typeVariables = pop(); |
| + int charOffset = pop(); |
| String name = pop(); |
| TypeBuilder returnType = pop(); |
| int modifiers = |
| @@ -261,7 +322,7 @@ class OutlineBuilder extends UnhandledListener { |
| formals, |
| asyncModifier, |
| computeProcedureKind(getOrSet), |
| - beginToken.charOffset, |
| + charOffset, |
| formalsOffset, |
| endToken.charOffset, |
| nativeMethodName, |
| @@ -298,6 +359,7 @@ class OutlineBuilder extends UnhandledListener { |
| List<FormalParameterBuilder> formals = pop(); |
| int formalsOffset = pop(); |
| List<TypeVariableBuilder> typeVariables = pop(); |
| + int charOffset = pop(); |
| dynamic nameOrOperator = pop(); |
| if (Operator.subtract == nameOrOperator && formals == null) { |
| nameOrOperator = Operator.unaryMinus; |
| @@ -324,7 +386,7 @@ class OutlineBuilder extends UnhandledListener { |
| formals, |
| asyncModifier, |
| kind, |
| - beginToken.charOffset, |
| + charOffset, |
| formalsOffset, |
| endToken.charOffset, |
| nativeMethodName, |
| @@ -352,6 +414,7 @@ class OutlineBuilder extends UnhandledListener { |
| List<TypeBuilder> interfaces = popIfNotNull(implementsKeyword); |
| TypeBuilder mixinApplication = pop(); |
| List<TypeVariableBuilder> typeVariables = pop(); |
| + int charOffset = pop(); |
| String name = pop(); |
| if (typeVariables != null && mixinApplication is MixinApplicationBuilder) { |
| mixinApplication.typeVariables = typeVariables; |
| @@ -360,7 +423,7 @@ class OutlineBuilder extends UnhandledListener { |
| int modifiers = Modifier.validate(pop()); |
| List<MetadataBuilder> metadata = pop(); |
| library.addNamedMixinApplication(metadata, name, typeVariables, modifiers, |
| - mixinApplication, interfaces, beginToken.charOffset); |
| + mixinApplication, interfaces, charOffset); |
| checkEmpty(beginToken.charOffset); |
| } |
| @@ -379,8 +442,9 @@ class OutlineBuilder extends UnhandledListener { |
| void handleType(Token beginToken, Token endToken) { |
| debugEvent("Type"); |
| List<TypeBuilder> arguments = pop(); |
| + int charOffset = pop(); |
| String name = pop(); |
| - push(library.addNamedType(name, arguments, beginToken.charOffset)); |
| + push(library.addNamedType(name, arguments, charOffset)); |
| } |
| @override |
| @@ -405,18 +469,14 @@ class OutlineBuilder extends UnhandledListener { |
| void endFormalParameter(Token covariantKeyword, Token thisKeyword, |
| Token nameToken, FormalParameterType kind) { |
| debugEvent("FormalParameter"); |
| + int charOffset = pop(); |
| String name = pop(); |
| TypeBuilder type = pop(); |
| int modifiers = Modifier.validate(pop()); |
| List<MetadataBuilder> metadata = pop(); |
| // TODO(ahe): Needs begin token. |
|
jensj
2017/03/24 12:49:10
Is this todo still current?
ahe
2017/03/24 14:11:50
No. I've removed it. Good catch.
|
| push(library.addFormalParameter( |
| - metadata, |
| - modifiers, |
| - type, |
| - name, |
| - thisKeyword != null, |
| - thisKeyword?.charOffset ?? nameToken?.charOffset ?? -1)); |
| + metadata, modifiers, type, name, thisKeyword != null, charOffset)); |
| } |
| @override |
| @@ -438,10 +498,12 @@ class OutlineBuilder extends UnhandledListener { |
| pop(); // Function type parameters. |
| pop(); // Formals offset |
| pop(); // Type variables. |
| + int charOffset = pop(); |
| String name = pop(); |
| pop(); // Return type. |
| push(NullValue.Type); |
| push(name); |
| + push(charOffset); |
| } |
| @override |
| @@ -502,11 +564,12 @@ class OutlineBuilder extends UnhandledListener { |
| @override |
| void endEnum(Token enumKeyword, Token endBrace, int count) { |
| - List<String> constants = popList(count); |
| + List constantNamesAndOffsets = popList(count * 2); |
| + int charOffset = pop(); |
| String name = pop(); |
| List<MetadataBuilder> metadata = pop(); |
| - library.addEnum( |
| - metadata, name, constants, enumKeyword.charOffset, endBrace.charOffset); |
| + library.addEnum(metadata, name, constantNamesAndOffsets, charOffset, |
| + endBrace.charOffset); |
| checkEmpty(enumKeyword.charOffset); |
| } |
| @@ -534,15 +597,18 @@ class OutlineBuilder extends UnhandledListener { |
| List<TypeVariableBuilder> typeVariables; |
| String name; |
| TypeBuilder returnType; |
| + int charOffset; |
| if (equals == null) { |
| formals = pop(); |
| pop(); // formals offset |
| typeVariables = pop(); |
| + charOffset = pop(); |
| name = pop(); |
| returnType = pop(); |
| } else { |
| var type = pop(); |
| typeVariables = pop(); |
| + charOffset = pop(); |
| name = pop(); |
| if (type is FunctionTypeBuilder) { |
| // TODO(ahe): We need to start a nested declaration when parsing the |
| @@ -559,19 +625,19 @@ class OutlineBuilder extends UnhandledListener { |
| } |
| } |
| List<MetadataBuilder> metadata = pop(); |
| - library.addFunctionTypeAlias(metadata, returnType, name, typeVariables, |
| - formals, typedefKeyword.charOffset); |
| + library.addFunctionTypeAlias( |
| + metadata, returnType, name, typeVariables, formals, charOffset); |
| checkEmpty(typedefKeyword.charOffset); |
| } |
| @override |
| void endTopLevelFields(int count, Token beginToken, Token endToken) { |
| debugEvent("endTopLevelFields"); |
| - List<String> names = popList(count); |
| + List namesAndOffsets = popList(count * 2); |
| TypeBuilder type = pop(); |
| int modifiers = Modifier.validate(pop()); |
| List<MetadataBuilder> metadata = pop(); |
| - library.addFields(metadata, modifiers, type, names); |
| + library.addFields(metadata, modifiers, type, namesAndOffsets); |
| checkEmpty(beginToken.charOffset); |
| } |
| @@ -579,27 +645,29 @@ class OutlineBuilder extends UnhandledListener { |
| void endFields( |
| int count, Token covariantToken, Token beginToken, Token endToken) { |
| debugEvent("Fields"); |
| - List<String> names = popList(count); |
| + List namesAndOffsets = popList(count * 2); |
| TypeBuilder type = pop(); |
| int modifiers = Modifier.validate(pop()); |
| List<MetadataBuilder> metadata = pop(); |
| - library.addFields(metadata, modifiers, type, names); |
| + library.addFields(metadata, modifiers, type, namesAndOffsets); |
| } |
| @override |
| void endTypeVariable(Token token, Token extendsOrSuper) { |
| debugEvent("endTypeVariable"); |
| TypeBuilder bound = pop(); |
| + int charOffset = pop(); |
| String name = pop(); |
| // TODO(paulberry): type variable metadata should not be ignored. See |
| // dartbug.com/28981. |
| /* List<MetadataBuilder> metadata = */ pop(); |
| - push(library.addTypeVariable(name, bound, token.charOffset)); |
| + push(library.addTypeVariable(name, bound, charOffset)); |
| } |
| @override |
| void endPartOf(Token partKeyword, Token semicolon, bool hasName) { |
| debugEvent("endPartOf"); |
| + popCharOffset(); |
| String containingLibrary = pop(); |
| List<MetadataBuilder> metadata = pop(); |
| if (hasName) { |
| @@ -613,11 +681,13 @@ class OutlineBuilder extends UnhandledListener { |
| void endConstructorReference( |
| Token start, Token periodBeforeName, Token endToken) { |
| debugEvent("ConstructorReference"); |
| + popIfNotNull(periodBeforeName); // charOffset. |
| String suffix = popIfNotNull(periodBeforeName); |
| List<TypeBuilder> typeArguments = pop(); |
| + int charOffset = pop(); |
| String name = pop(); |
| push(library.addConstructorReference( |
| - name, typeArguments, suffix, start.charOffset)); |
| + name, typeArguments, suffix, charOffset)); |
| } |
| @override |
| @@ -647,7 +717,7 @@ class OutlineBuilder extends UnhandledListener { |
| formals, |
| asyncModifier, |
| redirectionTarget, |
| - beginToken.charOffset, |
| + factoryKeyword.next.charOffset, |
| formalsOffset, |
| endToken.charOffset, |
| nativeMethodName); |