Augment. Use the scope of the container - library or augmentation.
This fixes resolution of metadata in library augmentations, and brings
us a step closer to supporting JsonSerializable.
Change-Id: I8874540cb020a40f551d72b842f1e75f2d3ad118
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/347424
Reviewed-by: Phil Quitslund <pquitslund@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 97f089a..d83a096 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -796,7 +796,7 @@
unit.accept(ScopeResolverVisitor(
_libraryElement, source, _typeProvider, errorListener,
- nameScope: _libraryElement.scope));
+ nameScope: unitElement.enclosingElement.scope));
// Nothing for RESOLVED_UNIT8?
// Nothing for RESOLVED_UNIT9?
diff --git a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
index 3705301..20d1784 100644
--- a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
@@ -13,17 +13,18 @@
class MetadataResolver extends ThrowingAstVisitor<void> {
final Linker _linker;
- final Scope _libraryScope;
+ final Scope _containerScope;
final LibraryBuilder _libraryBuilder;
final CompilationUnitElementImpl _unitElement;
- Scope _scope;
+ late Scope _scope;
MetadataResolver(
this._linker,
this._unitElement,
this._libraryBuilder,
- ) : _libraryScope = _libraryBuilder.element.scope,
- _scope = _libraryBuilder.element.scope;
+ ) : _containerScope = _unitElement.enclosingElement.scope {
+ _scope = _containerScope;
+ }
@override
void visitAnnotation(covariant AnnotationImpl node) {
@@ -52,7 +53,7 @@
try {
node.members.accept(this);
} finally {
- _scope = _libraryScope;
+ _scope = _containerScope;
}
}
@@ -94,7 +95,7 @@
node.constants.accept(this);
node.members.accept(this);
} finally {
- _scope = _libraryScope;
+ _scope = _containerScope;
}
}
@@ -116,7 +117,7 @@
try {
node.members.accept(this);
} finally {
- _scope = _libraryScope;
+ _scope = _containerScope;
}
}
@@ -130,7 +131,7 @@
try {
node.members.accept(this);
} finally {
- _scope = _libraryScope;
+ _scope = _containerScope;
}
}
@@ -224,7 +225,7 @@
try {
node.members.accept(this);
} finally {
- _scope = _libraryScope;
+ _scope = _containerScope;
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/macro_test.dart b/pkg/analyzer/test/src/dart/resolution/macro_test.dart
index e0f60e3..165fc03 100644
--- a/pkg/analyzer/test/src/dart/resolution/macro_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/macro_test.dart
@@ -477,16 +477,32 @@
]);
}
- @SkippedTest(reason: r'''
-CompileTimeErrorCode.FINAL_NOT_INITIALIZED [141, 3, "The final variable 'age' must be initialized.", "Try initializing the variable."]
-CompileTimeErrorCode.FINAL_NOT_INITIALIZED [161, 4, "The final variable 'name' must be initialized.", "Try initializing the variable."]
+ @FailingTest(reason: r'''
+ResolvedLibraryResult #0
+ element: package:test/test.dart
+ units
+ ResolvedUnitResult #1
+ path: /home/test/lib/test.dart
+ uri: package:test/test.dart
+ flags: exists isLibrary
+ errors
+ 169 +3 FINAL_NOT_INITIALIZED
+ 189 +4 FINAL_NOT_INITIALIZED
+ ResolvedUnitResult #2
+ path: /home/test/lib/test.macro.dart
+ uri: package:test/test.macro.dart
+ flags: exists isAugmentation isMacroAugmentation
+ errors
+ 317 +13 DUPLICATE_CONSTRUCTOR
+ 164 +4 FINAL_NOT_INITIALIZED_CONSTRUCTOR
''')
test_example_jsonSerializable() async {
- await assertNoErrorsInCode(r'''
+ newFile(testFile.path, r'''
import 'json_serializable.dart';
void f(Map<String, Object?> json) {
- User.fromJson(json);
+ var user = User.fromJson(json);
+ user.toJson();
}
@JsonSerializable()
@@ -495,6 +511,23 @@
final String name;
}
''');
+
+ final session = contextFor(testFile).currentSession;
+ final result = await session.getResolvedLibrary(testFile.path);
+
+ assertResolvedLibraryResultText(result, r'''
+ResolvedLibraryResult #0
+ element: package:test/test.dart
+ units
+ ResolvedUnitResult #1
+ path: /home/test/lib/test.dart
+ uri: package:test/test.dart
+ flags: exists isLibrary
+ ResolvedUnitResult #2
+ path: /home/test/lib/test.macro.dart
+ uri: package:test/test.macro.dart
+ flags: exists isAugmentation isMacroAugmentation
+''');
}
test_getResolvedLibrary_macroAugmentation_hasErrors() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
index e1c2ca9..f93b07d 100644
--- a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
@@ -204,6 +204,63 @@
// No checks, as long as it does not crash.
}
+ test_location_libraryAugmentation_class() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+class A {
+ final int a;
+ const A(this.a);
+}
+''');
+
+ var b = newFile('$testPackageLibPath/b.dart', r'''
+library augment 'test.dart';
+import 'a.dart' as prefix;
+
+@prefix.A(42)
+class B {}
+''');
+
+ newFile('$testPackageLibPath/test.dart', r'''
+import augment 'b.dart';
+''');
+
+ await resolveFile2(b);
+
+ var annotation = findNode.annotation('@prefix.A(42)');
+ assertResolvedNodeText(annotation, '''
+Annotation
+ atSign: @
+ name: PrefixedIdentifier
+ prefix: SimpleIdentifier
+ token: prefix
+ staticElement: self::@augmentation::package:test/b.dart::@prefix::prefix
+ staticType: null
+ period: .
+ identifier: SimpleIdentifier
+ token: A
+ staticElement: package:test/a.dart::@class::A
+ staticType: null
+ staticElement: package:test/a.dart::@class::A
+ staticType: null
+ arguments: ArgumentList
+ leftParenthesis: (
+ arguments
+ IntegerLiteral
+ literal: 42
+ parameter: package:test/a.dart::@class::A::@constructor::new::@parameter::a
+ staticType: int
+ rightParenthesis: )
+ element: package:test/a.dart::@class::A::@constructor::new
+''');
+
+ final localVariable = findElement.class_('B');
+ final annotationOnElement = localVariable.metadata.single;
+ _assertElementAnnotationValueText(annotationOnElement, '''
+A
+ a: int 42
+''');
+ }
+
test_location_libraryAugmentationDirective() async {
newFile('$testPackageLibPath/test.dart', r'''
import augment 'a.dart';
diff --git a/pkg/analyzer/test/src/summary/elements_test.dart b/pkg/analyzer/test/src/summary/elements_test.dart
index 10a3a35..f69e885 100644
--- a/pkg/analyzer/test/src/summary/elements_test.dart
+++ b/pkg/analyzer/test/src/summary/elements_test.dart
@@ -4217,7 +4217,59 @@
''');
}
- test_augmentation_importScope_prefixed() async {
+ test_augmentation_importScope_prefixed_metadata() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+class A {
+ const A();
+}
+''');
+
+ newFile('$testPackageLibPath/b.dart', r'''
+library augment 'test.dart';
+import 'a.dart' as prefix;
+
+@prefix.A()
+void f() {}
+''');
+
+ final library = await buildLibrary(r'''
+import augment 'b.dart';
+''');
+
+ checkElementText(library, r'''
+library
+ definingUnit
+ augmentationImports
+ package:test/b.dart
+ imports
+ package:test/a.dart as prefix @48
+ definingUnit
+ functions
+ f @74
+ metadata
+ Annotation
+ atSign: @ @57
+ name: PrefixedIdentifier
+ prefix: SimpleIdentifier
+ token: prefix @58
+ staticElement: self::@augmentation::package:test/b.dart::@prefix::prefix
+ staticType: null
+ period: . @64
+ identifier: SimpleIdentifier
+ token: A @65
+ staticElement: package:test/a.dart::@class::A
+ staticType: null
+ staticElement: package:test/a.dart::@class::A
+ staticType: null
+ arguments: ArgumentList
+ leftParenthesis: ( @66
+ rightParenthesis: ) @67
+ element: package:test/a.dart::@class::A::@constructor::new
+ returnType: void
+''');
+ }
+
+ test_augmentation_importScope_prefixed_typeAnnotation() async {
newFile('$testPackageLibPath/a.dart', r'''
class A {}
''');
diff --git a/pkg/analyzer/test/src/summary/macro_test.dart b/pkg/analyzer/test/src/summary/macro_test.dart
index 64186a9..0f0364d 100644
--- a/pkg/analyzer/test/src/summary/macro_test.dart
+++ b/pkg/analyzer/test/src/summary/macro_test.dart
@@ -2372,19 +2372,19 @@
name: PrefixedIdentifier
prefix: SimpleIdentifier
token: prefix0 @73
- staticElement: <null>
+ staticElement: self::@augmentation::package:test/test.macro.dart::@prefix::prefix0
staticType: null
period: . @80
identifier: SimpleIdentifier
token: AddMethodFoo @81
- staticElement: <null>
+ staticElement: package:test/a.dart::@class::AddMethodFoo
staticType: null
- staticElement: <null>
+ staticElement: package:test/a.dart::@class::AddMethodFoo
staticType: null
arguments: ArgumentList
leftParenthesis: ( @93
rightParenthesis: ) @94
- element: <null>
+ element: package:test/a.dart::@class::AddMethodFoo::@constructor::new
augmentation: self::@augmentation::package:test/test.macro.dart::@classAugmentation::B
augmented
methods