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..88acba4b52b609ae9af5c009b072948bc9f30e02 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,13 @@ 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. |
push(library.addFormalParameter( |
- metadata, |
- modifiers, |
- type, |
- name, |
- thisKeyword != null, |
- thisKeyword?.charOffset ?? nameToken?.charOffset ?? -1)); |
+ metadata, modifiers, type, name, thisKeyword != null, charOffset)); |
} |
@override |
@@ -438,10 +497,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 +563,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 +596,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 +624,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 +644,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 +680,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 +716,7 @@ class OutlineBuilder extends UnhandledListener { |
formals, |
asyncModifier, |
redirectionTarget, |
- beginToken.charOffset, |
+ factoryKeyword.next.charOffset, |
formalsOffset, |
endToken.charOffset, |
nativeMethodName); |