Resolve namespace combinators.
R=brianwilkerson@google.com, paulberry@google.com
Bug: https://github.com/dart-lang/sdk/issues/33636
Change-Id: I4f16eec2dcb5805663c0118d221f8ad8710cf3f8
Reviewed-on: https://dart-review.googlesource.com/71220
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/frontend_resolution.dart b/pkg/analyzer/lib/src/dart/analysis/frontend_resolution.dart
index 578c149..2d056ef 100644
--- a/pkg/analyzer/lib/src/dart/analysis/frontend_resolution.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/frontend_resolution.dart
@@ -443,12 +443,16 @@
@override
void store(int offset, bool isSynthetic,
- {int importIndex, Node reference, DartType type}) {
+ {int importIndex,
+ bool isNamespaceCombinatorReference = false,
+ Node reference,
+ DartType type}) {
// if (fileUri.toString().endsWith('test.dart')) {
// print('[store][offset: $offset][reference: $reference][type: $type]');
// }
var encodedLocation = 2 * offset + (isSynthetic ? 1 : 0);
resolution.kernelData[encodedLocation] = new ResolutionData(
+ isNamespaceCombinatorReference: isNamespaceCombinatorReference,
isOutline: true,
prefixInfo: importIndex,
reference: reference,
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 487f11f..d5a934b 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -741,6 +741,9 @@
if (directive.metadata.isNotEmpty) {
applier.applyToAnnotations(directive);
}
+ if (directive is NamespaceDirective) {
+ directive.combinators.accept(applier);
+ }
}
for (var declaration in unit.declarations) {
if (declaration is ClassDeclaration) {
@@ -1133,8 +1136,9 @@
@override
Element translateReference(kernel.Node referencedNode,
- {bool isWriteReference = false,
+ {bool isNamespaceCombinatorReference = false,
bool isTypeReference = false,
+ bool isWriteReference = false,
kernel.DartType inferredType,
kernel.DartType receiverType}) {
if (referencedNode == null) {
@@ -1169,6 +1173,9 @@
throw new UnimplementedError(
'TODO(paulberry): ${referencedNode.runtimeType}');
}
+ if (isNamespaceCombinatorReference) {
+ return element;
+ }
if (element is PropertyInducingElement) {
PropertyInducingElement property = element;
element = isWriteReference ? property.setter : property.getter;
diff --git a/pkg/analyzer/lib/src/fasta/resolution_applier.dart b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
index 6a416b6..3c913ce 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_applier.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
@@ -919,8 +919,9 @@
return _translatePrefixInfo(data.prefixInfo);
}
return _typeContext.translateReference(data.reference,
- isWriteReference: data.isWriteReference,
+ isNamespaceCombinatorReference: data.isNamespaceCombinatorReference,
isTypeReference: data.isTypeReference,
+ isWriteReference: data.isWriteReference,
inferredType: data.inferredType,
receiverType: data.receiverType);
}
@@ -977,8 +978,9 @@
/// Return the analyzer [Element] for the given kernel node.
Element translateReference(kernel.Node referencedNode,
- {bool isWriteReference = false,
+ {bool isNamespaceCombinatorReference = false,
bool isTypeReference = false,
+ bool isWriteReference = false,
kernel.DartType inferredType,
kernel.DartType receiverType});
diff --git a/pkg/analyzer/lib/src/fasta/resolution_storer.dart b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
index 4301ba0..04e1c84 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_storer.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
@@ -18,6 +18,7 @@
final DartType invokeType;
final bool isExplicitCall;
final bool isImplicitCall;
+ final bool isNamespaceCombinatorReference;
final bool isOutline;
final bool isPrefixReference;
final bool isTypeReference;
@@ -36,6 +37,7 @@
this.invokeType,
this.isExplicitCall = false,
this.isImplicitCall = false,
+ this.isNamespaceCombinatorReference = false,
this.isOutline = false,
this.isPrefixReference = false,
this.isTypeReference = false,
diff --git a/pkg/analyzer/test/generated/hint_code_kernel_test.dart b/pkg/analyzer/test/generated/hint_code_kernel_test.dart
index 3e9f85c..ebc8fb6 100644
--- a/pkg/analyzer/test/generated/hint_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_kernel_test.dart
@@ -83,18 +83,6 @@
return super.test_deprecatedFunction_mixin2();
}
- @failingTest
- @override
- test_duplicateShownHiddenName_hidden() {
- return super.test_duplicateShownHiddenName_hidden();
- }
-
- @failingTest
- @override
- test_duplicateShownHiddenName_shown() {
- return super.test_duplicateShownHiddenName_shown();
- }
-
@override
@failingTest
test_invalidRequiredParam_on_named_parameter_with_default() async {
@@ -184,28 +172,4 @@
test_unusedImport_inComment_libraryDirective() async {
return super.test_unusedImport_inComment_libraryDirective();
}
-
- @failingTest
- @override
- test_unusedShownName() async {
- return super.test_unusedShownName();
- }
-
- @failingTest
- @override
- test_unusedShownName_as() async {
- return super.test_unusedShownName_as();
- }
-
- @failingTest
- @override
- test_unusedShownName_duplicates() async {
- return super.test_unusedShownName_duplicates();
- }
-
- @failingTest
- @override
- test_unusedShownName_topLevelVariable() async {
- return super.test_unusedShownName_topLevelVariable();
- }
}
diff --git a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
index 844dfeb..0c3c7dc 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
@@ -40,13 +40,6 @@
@override
@failingTest
- @AnalyzerProblem('https://github.com/dart-lang/sdk/issues/33636')
- test_ambiguousImport_showCombinator() async {
- return super.test_ambiguousImport_showCombinator();
- }
-
- @override
- @failingTest
@FastaProblem('https://github.com/dart-lang/sdk/issues/31604')
test_commentReference_beforeConstructor() async {
return super.test_commentReference_beforeConstructor();
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 454fd79..11ab373 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -2533,7 +2533,6 @@
main() {
a.loadLibrary();
}
-
''');
await resolveTestFile();
var import = findElement.import('package:test/a.dart');
@@ -2561,7 +2560,6 @@
main() {
a.loadLibrary(b, c);
}
-
''');
await resolveTestFile();
var import = findElement.import('package:test/a.dart');
@@ -2595,7 +2593,6 @@
main() {
a.loadLibrary;
}
-
''');
await resolveTestFile();
var import = findElement.import('package:test/a.dart');
@@ -2621,7 +2618,6 @@
a.v;
a.v = 1;
}
-
''');
await resolveTestFile();
var import = findElement.import('package:test/a.dart');
@@ -2654,6 +2650,153 @@
}
}
+ test_directive_export() async {
+ var a = _p('/test/lib/a.dart');
+ provider.newFile(a, r'''
+class MyClass {}
+int myVar;
+int get myGetter => 0;
+int set mySetter(_) {}
+''');
+ addTestFile(r'''
+export 'a.dart' show MyClass, myVar, myGetter, mySetter, Unresolved;
+''');
+ await resolveTestFile();
+ var export = findElement.export('package:test/a.dart');
+ var namespace = export.exportedLibrary.exportNamespace;
+
+ {
+ var ref = findNode.simple('MyClass');
+ assertElement(ref, namespace.get('MyClass'));
+ assertType(ref, null);
+ }
+
+ {
+ var ref = findNode.simple('myVar');
+ PropertyAccessorElement getter = namespace.get('myVar');
+ assertElement(ref, getter.variable);
+ assertType(ref, null);
+ }
+
+ {
+ var ref = findNode.simple('myGetter');
+ PropertyAccessorElement getter = namespace.get('myGetter');
+ assertElement(ref, getter.variable);
+ assertType(ref, null);
+ }
+
+ {
+ var ref = findNode.simple('mySetter');
+ PropertyAccessorElement getter = namespace.get('mySetter=');
+ assertElement(ref, getter.variable);
+ assertType(ref, null);
+ }
+
+ {
+ var ref = findNode.simple('Unresolved');
+ assertElementNull(ref);
+ assertType(ref, null);
+ }
+ }
+
+ test_directive_import_hide() async {
+ var a = _p('/test/lib/a.dart');
+ provider.newFile(a, r'''
+class MyClass {}
+int myVar;
+int get myGetter => 0;
+int set mySetter(_) {}
+''');
+ addTestFile(r'''
+import 'a.dart' hide MyClass, myVar, myGetter, mySetter, Unresolved;
+''');
+ await resolveTestFile();
+ var import = findElement.import('package:test/a.dart');
+ var namespace = import.importedLibrary.exportNamespace;
+
+ {
+ var ref = findNode.simple('MyClass');
+ assertElement(ref, namespace.get('MyClass'));
+ assertType(ref, null);
+ }
+
+ {
+ var ref = findNode.simple('myVar');
+ PropertyAccessorElement getter = namespace.get('myVar');
+ assertElement(ref, getter.variable);
+ assertType(ref, null);
+ }
+
+ {
+ var ref = findNode.simple('myGetter');
+ PropertyAccessorElement getter = namespace.get('myGetter');
+ assertElement(ref, getter.variable);
+ assertType(ref, null);
+ }
+
+ {
+ var ref = findNode.simple('mySetter');
+ PropertyAccessorElement getter = namespace.get('mySetter=');
+ assertElement(ref, getter.variable);
+ assertType(ref, null);
+ }
+
+ {
+ var ref = findNode.simple('Unresolved');
+ assertElementNull(ref);
+ assertType(ref, null);
+ }
+ }
+
+ test_directive_import_show() async {
+ var a = _p('/test/lib/a.dart');
+ provider.newFile(a, r'''
+class MyClass {}
+int myVar;
+int get myGetter => 0;
+int set mySetter(_) {}
+''');
+ addTestFile(r'''
+import 'a.dart' show MyClass, myVar, myGetter, mySetter, Unresolved;
+''');
+ await resolveTestFile();
+ var import = findElement.import('package:test/a.dart');
+ var namespace = import.importedLibrary.exportNamespace;
+
+ {
+ var ref = findNode.simple('MyClass');
+ assertElement(ref, namespace.get('MyClass'));
+ assertType(ref, null);
+ }
+
+ {
+ var ref = findNode.simple('myVar');
+ PropertyAccessorElement getter = namespace.get('myVar');
+ assertElement(ref, getter.variable);
+ assertType(ref, null);
+ }
+
+ {
+ var ref = findNode.simple('myGetter');
+ PropertyAccessorElement getter = namespace.get('myGetter');
+ assertElement(ref, getter.variable);
+ assertType(ref, null);
+ }
+
+ {
+ var ref = findNode.simple('mySetter');
+ PropertyAccessorElement getter = namespace.get('mySetter=');
+ assertElement(ref, getter.variable);
+ assertType(ref, null);
+ }
+
+ {
+ var ref = findNode.simple('Unresolved');
+ assertElementNull(ref);
+ assertType(ref, null);
+ }
+ }
+
test_enum_toString() async {
addTestFile(r'''
enum MyEnum { A, B, C }
@@ -10353,6 +10496,23 @@
fail('Not found class: $name');
}
+ ExportElement export(String targetUri) {
+ ExportElement exportElement;
+ for (var export in unitElement.library.exports) {
+ var exportedUri = export.exportedLibrary.source.uri.toString();
+ if (exportedUri == targetUri) {
+ if (exportElement != null) {
+ throw new StateError('Not unique $targetUri export.');
+ }
+ exportElement = export;
+ }
+ }
+ if (exportElement != null) {
+ return exportElement;
+ }
+ fail('Not found export: $targetUri');
+ }
+
FieldElement field(String name) {
for (var type in unitElement.types) {
for (var field in type.fields) {
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index 7a7e093..53e073e 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -1994,11 +1994,6 @@
@failingTest
@override
- test_searchReferences_TopLevelVariableElement() =>
- super.test_searchReferences_TopLevelVariableElement();
-
- @failingTest
- @override
test_subtypes_partWithoutLibrary() =>
super.test_subtypes_partWithoutLibrary();
}
diff --git a/pkg/front_end/lib/src/fasta/combinator.dart b/pkg/front_end/lib/src/fasta/combinator.dart
index 9f97607..5dfcf91 100644
--- a/pkg/front_end/lib/src/fasta/combinator.dart
+++ b/pkg/front_end/lib/src/fasta/combinator.dart
@@ -7,15 +7,30 @@
class Combinator {
final bool isShow;
+ final List<CombinatorIdentifier> identifiers;
+
final Set<String> names;
- Combinator(this.isShow, this.names, int charOffset, Uri fileUri);
+ Combinator(
+ this.isShow, this.identifiers, this.names, int charOffset, Uri fileUri);
- Combinator.show(Iterable<String> names, int charOffset, Uri fileUri)
- : this(true, new Set<String>.from(names), charOffset, fileUri);
+ Combinator.hide(List<CombinatorIdentifier> identifiers,
+ Iterable<String> names, int charOffset, Uri fileUri)
+ : this(false, identifiers, new Set<String>.from(names), charOffset,
+ fileUri);
- Combinator.hide(Iterable<String> names, int charOffset, Uri fileUri)
- : this(false, new Set<String>.from(names), charOffset, fileUri);
+ Combinator.show(List<CombinatorIdentifier> identifiers,
+ Iterable<String> names, int charOffset, Uri fileUri)
+ : this(true, identifiers, new Set<String>.from(names), charOffset,
+ fileUri);
bool get isHide => !isShow;
}
+
+class CombinatorIdentifier {
+ final int offset;
+ final String name;
+ final bool isSynthetic;
+
+ CombinatorIdentifier(this.offset, this.name, this.isSynthetic);
+}
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 476c2da..399112b 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -469,10 +469,10 @@
combinators ??= <Combinator>[];
combinators.add(combinator.isShow
- ? new Combinator.show(
- combinator.names, combinator.fileOffset, library.fileUri)
- : new Combinator.hide(
- combinator.names, combinator.fileOffset, library.fileUri));
+ ? new Combinator.show(null, combinator.names,
+ combinator.fileOffset, library.fileUri)
+ : new Combinator.hide(null, combinator.names,
+ combinator.fileOffset, library.fileUri));
}
debugLibrary.addImport(
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 11ed95df..5d79c08 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
@@ -65,8 +65,6 @@
import '../problems.dart' show unexpected, unhandled;
-import '../source/outline_listener.dart' show OutlineListener;
-
import '../source/source_class_builder.dart' show SourceClassBuilder;
import '../source/source_library_builder.dart'
@@ -150,13 +148,10 @@
/// the error message is the corresponding value in the map.
Map<String, String> unserializableExports;
- final OutlineListener outlineListener;
-
KernelLibraryBuilder(Uri uri, Uri fileUri, Loader loader, this.actualOrigin,
[Scope scope, Library target])
: library = target ??
(actualOrigin?.library ?? new Library(uri, fileUri: fileUri)),
- outlineListener = loader.createOutlineListener(fileUri),
super(loader, fileUri, scope);
@override
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
index 460fec9..83d9acd 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
@@ -240,6 +240,9 @@
/// expressions are required.
final bool allowedInConstantExpression;
+ /// Indicated whether the `isSynthetic` flag is required for the identifier.
+ final bool requiresSyntheticFlag;
+
final Template<_MessageWithArgument<Token>> recoveryTemplate;
const IdentifierContext(this._name,
@@ -249,6 +252,7 @@
this.isContinuation: false,
this.isScopeReference: false,
this.isBuiltInIdentifierAllowed: true,
+ this.requiresSyntheticFlag: false,
bool allowedInConstantExpression,
this.recoveryTemplate: templateExpectedIdentifier})
: this.allowedInConstantExpression =
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
index 9814c3b..078f2d6 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
@@ -81,7 +81,8 @@
/// See [IdentifierContext.combinator].
class CombinatorIdentifierContext extends IdentifierContext {
- const CombinatorIdentifierContext() : super('combinator');
+ const CombinatorIdentifierContext()
+ : super('combinator', requiresSyntheticFlag: true);
@override
Token ensureIdentifier(Token token, Parser parser) {
@@ -154,10 +155,12 @@
/// See [IdentifierContext.dottedName].
class DottedNameIdentifierContext extends IdentifierContext {
- const DottedNameIdentifierContext() : super('dottedName');
+ const DottedNameIdentifierContext()
+ : super('dottedName', requiresSyntheticFlag: true);
const DottedNameIdentifierContext.continuation()
- : super('dottedNameContinuation', isContinuation: true);
+ : super('dottedNameContinuation',
+ isContinuation: true, requiresSyntheticFlag: true);
@override
Token ensureIdentifier(Token token, Parser parser) {
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 d487929..6fc54ed 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -14,7 +14,7 @@
import '../builder/metadata_builder.dart' show ExpressionMetadataBuilder;
-import '../combinator.dart' show Combinator;
+import '../combinator.dart' show Combinator, CombinatorIdentifier;
import '../fasta_codes.dart'
show
@@ -113,12 +113,14 @@
int popCharOffset() => pop();
- List<String> popIdentifierList(int count) {
+ List<CombinatorIdentifier> popIdentifierList(int count) {
if (count == 0) return null;
- List<String> list = new List<String>.filled(count, null, growable: true);
+ var list = new List<CombinatorIdentifier>.filled(count, null);
for (int i = count - 1; i >= 0; i--) {
- popCharOffset();
- list[i] = pop();
+ bool isSynthetic = pop();
+ int offset = popCharOffset();
+ String name = pop();
+ list[i] = new CombinatorIdentifier(offset, name, isSynthetic);
}
return list;
}
@@ -177,15 +179,21 @@
@override
void endHide(Token hideKeyword) {
debugEvent("Hide");
- List<String> names = pop();
- push(new Combinator.hide(names, hideKeyword.charOffset, library.fileUri));
+ List<CombinatorIdentifier> identifiers = pop();
+ List<String> names =
+ identifiers.map((identifier) => identifier.name).toList();
+ push(new Combinator.hide(
+ identifiers, names, hideKeyword.charOffset, library.fileUri));
}
@override
void endShow(Token showKeyword) {
debugEvent("Show");
- List<String> names = pop();
- push(new Combinator.show(names, showKeyword.charOffset, library.fileUri));
+ List<CombinatorIdentifier> identifiers = pop();
+ List<String> names =
+ identifiers.map((identifier) => identifier.name).toList();
+ push(new Combinator.show(
+ identifiers, names, showKeyword.charOffset, library.fileUri));
}
@override
@@ -270,7 +278,9 @@
@override
void handleDottedName(int count, Token firstIdentifier) {
debugEvent("DottedName");
- push(popIdentifierList(count).join('.'));
+ push(popIdentifierList(count)
+ .map((identifier) => identifier.name)
+ .join('.'));
}
@override
@@ -319,6 +329,9 @@
super.handleIdentifier(token, context);
push(token.charOffset);
}
+ if (context.requiresSyntheticFlag) {
+ push(token.isSynthetic);
+ }
if (inConstructor && context == IdentifierContext.methodDeclaration) {
inConstructorName = true;
}
diff --git a/pkg/front_end/lib/src/fasta/source/outline_listener.dart b/pkg/front_end/lib/src/fasta/source/outline_listener.dart
index 4728332..0f77d6c 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_listener.dart
@@ -22,5 +22,8 @@
/// `List<int>` will have a reference to `List` and type `List<int>`, i.e.
/// with type arguments applied.
void store(int offset, bool isSynthetic,
- {int importIndex, Node reference, DartType type}) {}
+ {int importIndex,
+ bool isNamespaceCombinatorReference,
+ Node reference,
+ DartType type}) {}
}
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 e6a127e..75ee308 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
@@ -65,6 +65,8 @@
import '../problems.dart' show unhandled;
+import '../source/outline_listener.dart' show OutlineListener;
+
import 'source_loader.dart' show SourceLoader;
abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
@@ -113,6 +115,8 @@
bool canAddImplementationBuilders = false;
+ final OutlineListener outlineListener;
+
SourceLibraryBuilder(SourceLoader loader, Uri fileUri, Scope scope)
: this.fromScopes(loader, fileUri, new DeclarationBuilder<T>.library(),
scope ?? new Scope.top());
@@ -121,6 +125,7 @@
this.loader, this.fileUri, this.libraryDeclaration, this.importScope)
: disableTypeInference = loader.target.disableTypeInference,
currentDeclaration = libraryDeclaration,
+ outlineListener = loader.createOutlineListener(fileUri),
super(
fileUri, libraryDeclaration.toScope(importScope), new Scope.top());
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 16e03ba..9c65335 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -45,6 +45,8 @@
NamedTypeBuilder,
TypeBuilder;
+import '../combinator.dart';
+
import '../deprecated_problems.dart' show deprecated_inputError;
import '../export.dart' show Export;
@@ -102,6 +104,8 @@
import 'outline_builder.dart' show OutlineBuilder;
+import 'outline_listener.dart' show OutlineListener;
+
import 'source_class_builder.dart' show SourceClassBuilder;
import 'source_library_builder.dart' show SourceLibraryBuilder;
@@ -344,6 +348,21 @@
// and can lead to memory leaks.
exportee.exporters.clear();
}
+ for (var library in builders.values) {
+ if (library is SourceLibraryBuilder) {
+ OutlineListener outlineListener = library.outlineListener;
+ if (outlineListener != null) {
+ for (var import in library.imports) {
+ storeCombinatorIdentifiersResolution(
+ outlineListener, import.imported, import.combinators);
+ }
+ for (var export in library.exports) {
+ storeCombinatorIdentifiersResolution(
+ outlineListener, export.exported, export.combinators);
+ }
+ }
+ }
+ }
ticker.logMs("Computed library scopes");
// debugPrintExports();
}
@@ -953,4 +972,19 @@
hierarchy = null;
typeInferenceEngine = null;
}
+
+ void storeCombinatorIdentifiersResolution(OutlineListener outlineListener,
+ LibraryBuilder consumed, List<Combinator> combinators) {
+ if (combinators != null) {
+ for (var combinator in combinators) {
+ for (var identifier in combinator.identifiers) {
+ var declaration = consumed.exportScope.local[identifier.name];
+ declaration ??= consumed.exportScope.setters[identifier.name];
+ outlineListener.store(identifier.offset, identifier.isSynthetic,
+ isNamespaceCombinatorReference: true,
+ reference: declaration?.target);
+ }
+ }
+ }
+ }
}