Unify QualifiedName and Identifier
Change-Id: Ie7e7131c58186efd5ed4e81e2f010cc240ce8d03
Reviewed-on: https://dart-review.googlesource.com/73341
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/builder.dart b/pkg/front_end/lib/src/fasta/builder/builder.dart
index 914ee9e..2efbcb9 100644
--- a/pkg/front_end/lib/src/fasta/builder/builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/builder.dart
@@ -4,6 +4,14 @@
library fasta.builder;
+export '../identifiers.dart'
+ show
+ Identifier,
+ InitializedIdentifier,
+ QualifiedName,
+ deprecated_extractToken,
+ flattenName;
+
export '../scope.dart' show AccessErrorBuilder, Scope, ScopeBuilder;
export 'builtin_type_builder.dart' show BuiltinTypeBuilder;
@@ -44,8 +52,6 @@
export 'procedure_builder.dart' show ProcedureBuilder;
-export 'qualified_name.dart' show QualifiedName;
-
export 'type_builder.dart' show TypeBuilder;
export 'type_declaration_builder.dart' show TypeDeclarationBuilder;
diff --git a/pkg/front_end/lib/src/fasta/builder/constructor_reference_builder.dart b/pkg/front_end/lib/src/fasta/builder/constructor_reference_builder.dart
index bc7a3cb..d3f8d63 100644
--- a/pkg/front_end/lib/src/fasta/builder/constructor_reference_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/constructor_reference_builder.dart
@@ -14,7 +14,8 @@
PrefixBuilder,
QualifiedName,
Scope,
- TypeBuilder;
+ TypeBuilder,
+ flattenName;
class ConstructorReferenceBuilder {
final int charOffset;
@@ -34,14 +35,17 @@
Declaration parent, this.charOffset)
: fileUri = parent.fileUri;
- String get fullNameForErrors => "$name${suffix == null ? '' : '.$suffix'}";
+ String get fullNameForErrors {
+ return "${flattenName(name, charOffset, fileUri)}"
+ "${suffix == null ? '' : '.$suffix'}";
+ }
void resolveIn(Scope scope, LibraryBuilder accessingLibrary) {
final name = this.name;
Declaration declaration;
if (name is QualifiedName) {
- String prefix = name.prefix;
- String middle = name.suffix;
+ String prefix = name.qualifier;
+ String middle = name.name;
declaration = scope.lookup(prefix, charOffset, fileUri);
if (declaration is PrefixBuilder) {
PrefixBuilder prefix = declaration;
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index 1c3c79f..41ae499 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -10,16 +10,20 @@
templateMissingExplicitTypeArguments,
templateTypeArgumentMismatch;
+import '../problems.dart' show unhandled;
+
import 'builder.dart'
show
Declaration,
+ Identifier,
InvalidTypeBuilder,
LibraryBuilder,
PrefixBuilder,
QualifiedName,
Scope,
TypeBuilder,
- TypeDeclarationBuilder;
+ TypeDeclarationBuilder,
+ flattenName;
abstract class NamedTypeBuilder<T extends TypeBuilder, R> extends TypeBuilder {
final Object name;
@@ -45,21 +49,34 @@
final name = this.name;
Declaration member;
if (name is QualifiedName) {
- Declaration prefix = scope.lookup(name.prefix, charOffset, fileUri);
+ Object qualifier = name.qualifier;
+ String prefixName = flattenName(qualifier, charOffset, fileUri);
+ Declaration prefix = scope.lookup(prefixName, charOffset, fileUri);
if (prefix is PrefixBuilder) {
- member = prefix.lookup(name.suffix, name.charOffset, fileUri);
+ member = prefix.lookup(name.name, name.charOffset, fileUri);
}
- } else {
+ } else if (name is String) {
member = scope.lookup(name, charOffset, fileUri);
+ } else {
+ unhandled("${name.runtimeType}", "resolveIn", charOffset, fileUri);
}
if (member is TypeDeclarationBuilder) {
declaration = member.origin;
if (arguments == null && declaration.typeVariablesCount != 0) {
+ String typeName;
+ int typeNameOffset;
+ if (name is Identifier) {
+ typeName = name.name;
+ typeNameOffset = name.charOffset;
+ } else {
+ typeName = name;
+ typeNameOffset = charOffset;
+ }
library.addProblem(
templateMissingExplicitTypeArguments
.withArguments(declaration.typeVariablesCount),
- charOffset,
- "$name".length,
+ typeNameOffset,
+ typeName.length,
fileUri);
}
return;
diff --git a/pkg/front_end/lib/src/fasta/builder/qualified_name.dart b/pkg/front_end/lib/src/fasta/builder/qualified_name.dart
deleted file mode 100644
index e879e46..0000000
--- a/pkg/front_end/lib/src/fasta/builder/qualified_name.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2017, 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.qualified_name;
-
-class QualifiedName {
- final prefix;
- final String suffix;
- final int charOffset;
-
- QualifiedName(this.prefix, this.suffix, this.charOffset);
-
- toString() => "$prefix.$suffix";
-}
diff --git a/pkg/front_end/lib/src/fasta/identifiers.dart b/pkg/front_end/lib/src/fasta/identifiers.dart
new file mode 100644
index 0000000..64af67b
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/identifiers.dart
@@ -0,0 +1,144 @@
+// Copyright (c) 2017, 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.qualified_name;
+
+import 'package:kernel/ast.dart' show Expression;
+
+import 'problems.dart' show unhandled, unsupported;
+
+import 'scanner.dart' show Token;
+
+class Identifier {
+ final String name;
+ final int charOffset;
+
+ Identifier(Token token)
+ : name = token.lexeme,
+ charOffset = token.charOffset;
+
+ Identifier._(this.name, this.charOffset);
+
+ factory Identifier.preserveToken(Token token) {
+ return new _TokenIdentifier(token);
+ }
+
+ Expression get initializer => null;
+
+ QualifiedName withQualifier(Object qualifier) {
+ return new QualifiedName._(qualifier, name, charOffset);
+ }
+
+ @override
+ String toString() => "identifier($name)";
+}
+
+class _TokenIdentifier implements Identifier {
+ final Token token;
+
+ _TokenIdentifier(this.token);
+
+ @override
+ String get name => token.lexeme;
+
+ @override
+ int get charOffset => token.charOffset;
+
+ @override
+ Expression get initializer => null;
+
+ @override
+ QualifiedName withQualifier(Object qualifier) {
+ return new _TokenQualifiedName(qualifier, token);
+ }
+
+ @override
+ String toString() => "token-identifier($name)";
+}
+
+class InitializedIdentifier extends _TokenIdentifier {
+ @override
+ final Expression initializer;
+
+ InitializedIdentifier(_TokenIdentifier identifier, this.initializer)
+ : super(identifier.token);
+
+ @override
+ QualifiedName withQualifier(Object qualifier) {
+ return unsupported("withQualifier", charOffset, null);
+ }
+
+ @override
+ String toString() => "initialized-identifier($name, $initializer)";
+}
+
+class QualifiedName extends Identifier {
+ final Object qualifier;
+
+ QualifiedName(this.qualifier, Token suffix) : super(suffix);
+
+ QualifiedName._(this.qualifier, String name, int charOffset)
+ : super._(name, charOffset);
+
+ @override
+ QualifiedName withQualifier(Object qualifier) {
+ return unsupported("withQualifier", charOffset, null);
+ }
+
+ @override
+ String toString() => "qualified-name($qualifier, $name)";
+}
+
+class _TokenQualifiedName extends _TokenIdentifier implements QualifiedName {
+ @override
+ final Object qualifier;
+
+ _TokenQualifiedName(this.qualifier, Token suffix)
+ : assert(qualifier is! Identifier || qualifier is _TokenIdentifier),
+ super(suffix);
+
+ @override
+ QualifiedName withQualifier(Object qualifier) {
+ return unsupported("withQualifier", charOffset, null);
+ }
+
+ @override
+ String toString() => "token-qualified-name($qualifier, $name)";
+}
+
+void flattenQualifiedNameOn(
+ QualifiedName name, StringBuffer buffer, int charOffset, Uri fileUri) {
+ final Object qualifier = name.qualifier;
+ if (qualifier is QualifiedName) {
+ flattenQualifiedNameOn(qualifier, buffer, charOffset, fileUri);
+ } else if (qualifier is Identifier) {
+ buffer.write(qualifier.name);
+ } else if (qualifier is String) {
+ buffer.write(qualifier);
+ } else {
+ unhandled("${qualifier.runtimeType}", "flattenQualifiedNameOn", charOffset,
+ fileUri);
+ }
+ buffer.write(".");
+ buffer.write(name.name);
+}
+
+String flattenName(Object name, int charOffset, Uri fileUri) {
+ if (name is String) {
+ return name;
+ } else if (name is QualifiedName) {
+ StringBuffer buffer = new StringBuffer();
+ flattenQualifiedNameOn(name, buffer, charOffset, fileUri);
+ return "$buffer";
+ } else if (name is Identifier) {
+ return name.name;
+ } else {
+ unhandled("${name.runtimeType}", "flattenName", charOffset, fileUri);
+ }
+}
+
+Token deprecated_extractToken(Identifier identifier) {
+ _TokenIdentifier tokenIdentifier = identifier;
+ return tokenIdentifier?.token;
+}
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 b559fa4..82fcfe8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -453,7 +453,9 @@
if (expression is Identifier) {
Identifier identifier = expression;
expression = new UnresolvedNameGenerator(
- this, identifier.token, new Name(identifier.name, library.library));
+ this,
+ deprecated_extractToken(identifier),
+ new Name(identifier.name, library.library));
}
if (name?.isNotEmpty ?? false) {
Token period = periodBeforeName ?? beginToken.next.next;
@@ -1564,7 +1566,7 @@
addProblem(
fasta.messageNotAConstantExpression, token.charOffset, token.length);
}
- push(new Identifier(token));
+ push(new Identifier.preserveToken(token));
}
/// Look up [name] in [scope] using [token] as location information (both to
@@ -1703,9 +1705,9 @@
@override
void handleQualified(Token period) {
debugEvent("Qualified");
- Identifier name = pop();
- Object receiver = pop();
- push([receiver, name]);
+ Identifier identifier = pop();
+ Object qualifier = pop();
+ push(identifier.withQualifier(qualifier));
}
@override
@@ -1905,12 +1907,12 @@
bool isFinal = (currentLocalVariableModifiers & finalMask) != 0;
assert(isConst == (constantContext == ConstantContext.inferred));
push(new VariableDeclarationJudgment(identifier.name, functionNestingLevel,
- forSyntheticToken: identifier.token.isSynthetic,
+ forSyntheticToken: deprecated_extractToken(identifier).isSynthetic,
initializer: initializer,
type: currentLocalVariableType,
isFinal: isFinal,
isConst: isConst)
- ..fileOffset = offsetForToken(identifier.token)
+ ..fileOffset = identifier.charOffset
..fileEqualsOffset = offsetForToken(equalsToken));
}
@@ -2273,19 +2275,16 @@
debugEvent("Type");
List<DartType> arguments = pop();
Object name = pop();
- if (name is List<Object>) {
- List<Object> list = name;
- if (list.length != 2) {
- unexpected("${list.length}", "2", beginToken.charOffset, uri);
- }
- Object prefix = list[0];
- Identifier suffix = list[1];
+ if (name is QualifiedName) {
+ QualifiedName qualified = name;
+ Object prefix = qualified.qualifier;
+ Token suffix = deprecated_extractToken(qualified);
if (prefix is Generator) {
- name = prefix.prefixedLookup(suffix.token);
+ name = prefix.qualifiedLookup(suffix);
} else {
- String displayName = debugName(getNodeName(prefix), suffix.name);
+ String displayName = debugName(getNodeName(prefix), suffix.lexeme);
addProblem(fasta.templateNotAType.withArguments(displayName),
- offsetForToken(beginToken), lengthOfSpan(beginToken, suffix.token));
+ offsetForToken(beginToken), lengthOfSpan(beginToken, suffix));
push(const InvalidType());
return;
}
@@ -2492,14 +2491,15 @@
} else {
variable = new VariableDeclarationJudgment(
name?.name, functionNestingLevel,
- forSyntheticToken: name?.token?.isSynthetic ?? false,
+ forSyntheticToken:
+ deprecated_extractToken(name)?.isSynthetic ?? false,
type: type,
initializer: name?.initializer,
isFinal: isFinal,
isConst: isConst);
if (name != null) {
// TODO(ahe): Need an offset when name is null.
- variable.fileOffset = offsetForToken(name.token);
+ variable.fileOffset = name.charOffset;
}
}
if (annotations != null) {
@@ -2567,7 +2567,7 @@
debugEvent("ValuedFormalParameter");
Expression initializer = popForValue();
Identifier name = pop();
- push(new InitializedIdentifier(name.token, initializer));
+ push(new InitializedIdentifier(name, initializer));
}
@override
@@ -2832,21 +2832,21 @@
Identifier identifier;
List<DartType> typeArguments = pop();
Object type = pop();
- if (type is List<Object>) {
- List<Object> list = type;
- Object prefix = list[0];
- identifier = list[1];
- if (prefix is TypeUseGenerator) {
- type = prefix;
+ if (type is QualifiedName) {
+ identifier = type;
+ QualifiedName qualified = type;
+ Object qualifier = qualified.qualifier;
+ if (qualifier is TypeUseGenerator) {
+ type = qualifier;
if (typeArguments != null) {
addProblem(fasta.messageConstructorWithTypeArguments,
- identifier.token.charOffset, identifier.name.length);
+ identifier.charOffset, identifier.name.length);
}
- } else if (prefix is Generator) {
- type = prefix.prefixedLookup(identifier.token);
+ } else if (qualifier is Generator) {
+ type = qualifier.qualifiedLookup(deprecated_extractToken(identifier));
identifier = null;
} else {
- unhandled("${prefix.runtimeType}", "pushQualifiedReference",
+ unhandled("${qualifier.runtimeType}", "pushQualifiedReference",
start.charOffset, uri);
}
}
@@ -3090,7 +3090,8 @@
Token nameToken, int offset, Constness constness) {
Arguments arguments = pop();
Identifier nameLastIdentifier = pop(NullValue.Identifier);
- Token nameLastToken = nameLastIdentifier?.token ?? nameToken;
+ Token nameLastToken =
+ deprecated_extractToken(nameLastIdentifier) ?? nameToken;
String name = pop();
List<DartType> typeArguments = pop();
@@ -3263,17 +3264,18 @@
Expression value = popForValue();
Identifier identifier = pop();
push(new NamedExpressionJudgment(
- tokensSaver?.namedExpressionTokens(identifier.token, colon),
- identifier.token.lexeme,
+ tokensSaver?.namedExpressionTokens(
+ deprecated_extractToken(identifier), colon),
+ identifier.name,
value)
- ..fileOffset = offsetForToken(identifier.token));
+ ..fileOffset = identifier.charOffset);
}
@override
void endFunctionName(Token beginToken, Token token) {
debugEvent("FunctionName");
Identifier name = pop();
- Token nameToken = name.token;
+ Token nameToken = deprecated_extractToken(name);
VariableDeclaration variable = new VariableDeclarationJudgment(
name.name, functionNestingLevel,
forSyntheticToken: nameToken.isSynthetic,
@@ -3282,7 +3284,7 @@
..fileOffset = offsetForToken(nameToken);
if (scope.local[variable.name] != null) {
addProblem(fasta.templateDuplicatedName.withArguments(variable.name),
- offsetForToken(nameToken), nameToken.length);
+ name.charOffset, nameToken.length);
}
push(new FunctionDeclarationJudgment(
variable,
@@ -3555,7 +3557,7 @@
void handleLabel(Token token) {
debugEvent("Label");
Identifier identifier = pop();
- push(forest.label(identifier.token, token));
+ push(forest.label(deprecated_extractToken(identifier), token));
}
@override
@@ -3896,8 +3898,8 @@
continueKeyword.next.charOffset));
return;
}
- switchScope.forwardDeclareLabel(identifier.name,
- target = createGotoTarget(offsetForToken(identifier.token)));
+ switchScope.forwardDeclareLabel(
+ identifier.name, target = createGotoTarget(identifier.charOffset));
}
if (target.isGotoTarget &&
target.functionNestingLevel == functionNestingLevel) {
@@ -3979,7 +3981,7 @@
// Something went wrong when pre-parsing the type variables.
// Assume an error is reported elsewhere.
variable = new KernelTypeVariableBuilder(
- name.name, library, offsetForToken(name.token), null);
+ name.name, library, name.charOffset, null);
variable.binder = _typeInferrer.binderForTypeVariable(
variable, variable.charOffset, variable.name);
}
@@ -4329,7 +4331,7 @@
@override
void handleSymbolVoid(Token token) {
debugEvent("SymbolVoid");
- push(new Identifier(token));
+ push(new Identifier.preserveToken(token));
}
@override
@@ -4544,17 +4546,6 @@
}
}
-class Identifier {
- final Token token;
- String get name => token.lexeme;
-
- Identifier(this.token);
-
- Expression get initializer => null;
-
- String toString() => "identifier($name)";
-}
-
class Operator {
final Token token;
String get name => token.stringValue;
@@ -4566,14 +4557,6 @@
String toString() => "operator($name)";
}
-class InitializedIdentifier extends Identifier {
- final Expression initializer;
-
- InitializedIdentifier(Token token, this.initializer) : super(token);
-
- String toString() => "initialized-identifier($name, $initializer)";
-}
-
class JumpTarget extends Declaration {
final List<Statement> users = <Statement>[];
@@ -4835,6 +4818,8 @@
return node.isSuper ? "super" : "this";
} else if (node is Generator) {
return node.plainNameForRead;
+ } else if (node is QualifiedName) {
+ return flattenName(node, node.charOffset, null);
} else {
return unhandled("${node.runtimeType}", "getNodeName", -1, null);
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index 7a06db1..eb6b1dc 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -230,7 +230,7 @@
return const InvalidType();
}
- /* Expression | Generator */ Object prefixedLookup(Token name) {
+ /* Expression | Generator */ Object qualifiedLookup(Token name) {
return new UnexpectedQualifiedUseGenerator(helper, name, this, false);
}
@@ -882,7 +882,7 @@
}
@override
- /* Expression | Generator */ Object prefixedLookup(Token name) {
+ /* Expression | Generator */ Object qualifiedLookup(Token name) {
helper.storeUnresolved(token);
return new UnexpectedQualifiedUseGenerator(helper, name, this, true);
}
@@ -1110,7 +1110,7 @@
Expression buildSimpleRead() => makeInvalidRead();
@override
- /* Expression | Generator */ Object prefixedLookup(Token name) {
+ /* Expression | Generator */ Object qualifiedLookup(Token name) {
if (helper.constantContext != ConstantContext.none && prefix.deferred) {
helper.addProblem(
templateCantUseDeferredPrefixAsConstant.withArguments(token),
@@ -1149,7 +1149,7 @@
if (send is IncompleteSendGenerator) {
assert(send.name.name == send.token.lexeme,
"'${send.name.name}' != ${send.token.lexeme}");
- Object result = prefixedLookup(send.token);
+ Object result = qualifiedLookup(send.token);
if (send is SendAccessGenerator) {
result = helper.finishSend(
result,
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index b66c371..26da213 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -14,7 +14,7 @@
Procedure,
Statement;
-import 'body_builder.dart' show Identifier, LabelTarget;
+import 'body_builder.dart' show LabelTarget;
import 'expression_generator.dart' show Generator, PrefixUseGenerator;
@@ -22,6 +22,7 @@
import 'kernel_builder.dart'
show
+ Identifier,
LoadLibraryBuilder,
PrefixBuilder,
TypeDeclarationBuilder,
@@ -29,7 +30,7 @@
import '../scanner.dart' show Token;
-export 'body_builder.dart' show Identifier, Operator;
+export 'body_builder.dart' show Operator;
export 'constness.dart' show Constness;
@@ -39,6 +40,7 @@
export 'kernel_builder.dart'
show
+ Identifier,
LoadLibraryBuilder,
PrefixBuilder,
TypeDeclarationBuilder,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index 0ae7b46..ba6a4e2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -319,14 +319,6 @@
}
}
if (type is KernelMixinApplicationBuilder) {
- String extractName(name) {
- if (name is QualifiedName) {
- return name.suffix;
- } else {
- return name;
- }
- }
-
// Documentation below assumes the given mixin application is in one of
// these forms:
//
@@ -1306,3 +1298,5 @@
return unhandled("no library parent", "${declaration.runtimeType}",
declaration.charOffset, declaration.fileUri);
}
+
+String extractName(name) => name is QualifiedName ? name.name : name;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_named_type_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_named_type_builder.dart
index b10ffcf..cbccf69 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_named_type_builder.dart
@@ -22,7 +22,8 @@
NamedTypeBuilder,
TypeBuilder,
TypeDeclarationBuilder,
- TypeVariableBuilder;
+ TypeVariableBuilder,
+ flattenName;
class KernelNamedTypeBuilder
extends NamedTypeBuilder<KernelTypeBuilder, DartType>
@@ -34,7 +35,8 @@
[Message message]) {
// TODO(ahe): Consider if it makes sense to pass a QualifiedName to
// KernelInvalidTypeBuilder?
- return new KernelInvalidTypeBuilder("$name", charOffset, fileUri, message);
+ return new KernelInvalidTypeBuilder(
+ flattenName(name, charOffset, fileUri), charOffset, fileUri, message);
}
Supertype handleInvalidSupertype(
@@ -43,8 +45,10 @@
? templateSupertypeIsTypeVariable
: templateSupertypeIsIllegal;
library.addProblem(
- template.withArguments("$name"), charOffset, noLength, fileUri,
- severity: Severity.error);
+ template.withArguments(flattenName(name, charOffset, fileUri)),
+ charOffset,
+ noLength,
+ fileUri);
return null;
}
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index 1d0fa47..ad4a1df 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -320,7 +320,8 @@
debugEvent("handleQualified");
String suffix = pop();
var prefix = pop();
- push(new QualifiedName(prefix, suffix, period.charOffset));
+ assert(identical(suffix, period.next.lexeme));
+ push(new QualifiedName(prefix, period.next));
}
@override
@@ -823,7 +824,7 @@
Declaration declaration;
String suffix;
if (nameOrQualified is QualifiedName) {
- suffix = nameOrQualified.suffix;
+ suffix = nameOrQualified.name;
} else {
suffix = nameOrQualified == currentClass.name ? "" : nameOrQualified;
}
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 de663b7..8bbedb6 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -377,9 +377,11 @@
debugEvent("handleQualified");
int suffixOffset = pop();
String suffix = pop();
+ assert(identical(suffix, period.next.lexeme));
+ assert(suffixOffset == period.next.charOffset);
int offset = pop();
var prefix = pop();
- push(new QualifiedName(prefix, suffix, suffixOffset));
+ push(new QualifiedName(prefix, period.next));
push(offset);
}
@@ -391,7 +393,7 @@
Object name = pop();
List<MetadataBuilder> metadata = pop();
library.documentationComment = documentationComment;
- library.name = "${name}";
+ library.name = flattenName(name, offsetForToken(libraryKeyword), uri);
library.metadata = metadata;
}
@@ -1207,7 +1209,8 @@
Object containingLibrary = pop();
List<MetadataBuilder> metadata = pop();
if (hasName) {
- library.addPartOf(metadata, "$containingLibrary", null, charOffset);
+ library.addPartOf(metadata,
+ flattenName(containingLibrary, charOffset, uri), null, charOffset);
} else {
library.addPartOf(metadata, null, containingLibrary, charOffset);
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 37b6584..5923555 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -200,8 +200,8 @@
String prefix;
String suffix;
if (name is QualifiedName) {
- prefix = name.prefix;
- suffix = name.suffix;
+ prefix = name.qualifier;
+ suffix = name.name;
} else {
prefix = name;
suffix = null;
@@ -822,7 +822,7 @@
for (UnresolvedType<T> type in types) {
Object nameOrQualified = type.builder.name;
String name = nameOrQualified is QualifiedName
- ? nameOrQualified.prefix
+ ? nameOrQualified.qualifier
: nameOrQualified;
TypeVariableBuilder builder;
if (name != null) {
diff --git a/pkg/front_end/testcases/qualified.dart b/pkg/front_end/testcases/qualified.dart
index 794f6bd..397020d 100644
--- a/pkg/front_end/testcases/qualified.dart
+++ b/pkg/front_end/testcases/qualified.dart
@@ -15,6 +15,8 @@
class WithMixin extends lib.Supertype with lib.Mixin {}
+class IllegalSupertype extends lib.VoidFunction {}
+
main() {
new C<String>();
new C<String>.a();
@@ -24,4 +26,5 @@
new lib.C<String>.b();
new WithMixin().supertypeMethod();
new WithMixin().foo();
+ new IllegalSupertype();
}
diff --git a/pkg/front_end/testcases/qualified.dart.direct.expect b/pkg/front_end/testcases/qualified.dart.direct.expect
index e062fce..b5e33b4 100644
--- a/pkg/front_end/testcases/qualified.dart.direct.expect
+++ b/pkg/front_end/testcases/qualified.dart.direct.expect
@@ -7,6 +7,10 @@
// pkg/front_end/testcases/qualified.dart:11:19: Error: Type 'lib.Missing' not found.
// class Bad extends lib.Missing {
// ^
+//
+// pkg/front_end/testcases/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
+// class IllegalSupertype extends lib.VoidFunction {}
+// ^
library test.qualified.main;
import self as self;
@@ -24,6 +28,11 @@
: super lib::Supertype::•()
;
}
+class IllegalSupertype extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
class C<T extends core::Object = dynamic> extends core::Object { // from org-dartlang-testcase:///qualified_part.dart
static field dynamic _redirecting# = <dynamic>[self::C::b];
constructor •() → void
@@ -44,4 +53,5 @@
new lib::C::a<core::String>();
new self::WithMixin::•().supertypeMethod();
new self::WithMixin::•().foo();
+ new self::IllegalSupertype::•();
}
diff --git a/pkg/front_end/testcases/qualified.dart.direct.transformed.expect b/pkg/front_end/testcases/qualified.dart.direct.transformed.expect
index a9175a1..3ffad7c 100644
--- a/pkg/front_end/testcases/qualified.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/qualified.dart.direct.transformed.expect
@@ -7,6 +7,10 @@
// pkg/front_end/testcases/qualified.dart:11:19: Error: Type 'lib.Missing' not found.
// class Bad extends lib.Missing {
// ^
+//
+// pkg/front_end/testcases/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
+// class IllegalSupertype extends lib.VoidFunction {}
+// ^
library test.qualified.main;
import self as self;
@@ -30,6 +34,11 @@
: super lib::Supertype::•()
;
}
+class IllegalSupertype extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
class C<T extends core::Object = dynamic> extends core::Object { // from org-dartlang-testcase:///qualified_part.dart
static field dynamic _redirecting# = <dynamic>[self::C::b];
constructor •() → void
@@ -50,4 +59,5 @@
new lib::C::a<core::String>();
new self::WithMixin::•().supertypeMethod();
new self::WithMixin::•().foo();
+ new self::IllegalSupertype::•();
}
diff --git a/pkg/front_end/testcases/qualified.dart.outline.expect b/pkg/front_end/testcases/qualified.dart.outline.expect
index b04c33a..f72c9c6 100644
--- a/pkg/front_end/testcases/qualified.dart.outline.expect
+++ b/pkg/front_end/testcases/qualified.dart.outline.expect
@@ -15,6 +15,10 @@
synthetic constructor •() → void
;
}
+class IllegalSupertype extends core::Object {
+ synthetic constructor •() → void
+ ;
+}
class C<T extends core::Object = dynamic> extends core::Object { // from org-dartlang-testcase:///qualified_part.dart
static field dynamic _redirecting# = <dynamic>[self::C::b];
constructor •() → void
diff --git a/pkg/front_end/testcases/qualified.dart.strong.expect b/pkg/front_end/testcases/qualified.dart.strong.expect
index fa6e54e..f1a7aea 100644
--- a/pkg/front_end/testcases/qualified.dart.strong.expect
+++ b/pkg/front_end/testcases/qualified.dart.strong.expect
@@ -11,6 +11,10 @@
// pkg/front_end/testcases/qualified.dart:11:19: Error: Type 'lib.Missing' not found.
// class Bad extends lib.Missing {
// ^
+//
+// pkg/front_end/testcases/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
+// class IllegalSupertype extends lib.VoidFunction {}
+// ^
library test.qualified.main;
import self as self;
@@ -28,6 +32,11 @@
: super lib::Supertype::•()
;
}
+class IllegalSupertype extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
class C<T extends core::Object = dynamic> extends core::Object { // from org-dartlang-testcase:///qualified_part.dart
static field dynamic _redirecting# = <dynamic>[self::C::b];
constructor •() → void
@@ -48,4 +57,5 @@
new lib::C::a<core::String>();
new self::WithMixin::•().{lib::Supertype::supertypeMethod}();
new self::WithMixin::•().{lib::Mixin::foo}();
+ new self::IllegalSupertype::•();
}
diff --git a/pkg/front_end/testcases/qualified.dart.strong.transformed.expect b/pkg/front_end/testcases/qualified.dart.strong.transformed.expect
index 9894c5e..34c0697 100644
--- a/pkg/front_end/testcases/qualified.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/qualified.dart.strong.transformed.expect
@@ -11,6 +11,10 @@
// pkg/front_end/testcases/qualified.dart:11:19: Error: Type 'lib.Missing' not found.
// class Bad extends lib.Missing {
// ^
+//
+// pkg/front_end/testcases/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
+// class IllegalSupertype extends lib.VoidFunction {}
+// ^
library test.qualified.main;
import self as self;
@@ -34,6 +38,11 @@
: super lib::Supertype::•()
;
}
+class IllegalSupertype extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
class C<T extends core::Object = dynamic> extends core::Object { // from org-dartlang-testcase:///qualified_part.dart
static field dynamic _redirecting# = <dynamic>[self::C::b];
constructor •() → void
@@ -54,4 +63,5 @@
new lib::C::a<core::String>();
new self::WithMixin::•().{lib::Supertype::supertypeMethod}();
new self::WithMixin::•().{lib::Mixin::foo}();
+ new self::IllegalSupertype::•();
}
diff --git a/pkg/front_end/testcases/qualified_lib.dart b/pkg/front_end/testcases/qualified_lib.dart
index dba8057..ae00a71 100644
--- a/pkg/front_end/testcases/qualified_lib.dart
+++ b/pkg/front_end/testcases/qualified_lib.dart
@@ -23,3 +23,5 @@
print("I'm Mixin.foo");
}
}
+
+typedef VoidFunction = void Function();