Build elements for constructor initializers.
R=brianwilkerson@google.com
Change-Id: Ic41e6ec93571f0407184f8b8e8271517e1e1ec59
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/101000
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/summary2/declaration_splicer.dart b/pkg/analyzer/lib/src/summary2/declaration_splicer.dart
index 468fb19..7120538 100644
--- a/pkg/analyzer/lib/src/summary2/declaration_splicer.dart
+++ b/pkg/analyzer/lib/src/summary2/declaration_splicer.dart
@@ -28,10 +28,15 @@
}
FunctionBody _body(FunctionBody full) {
+ _buildLocalElements(full);
+ return full;
+ }
+
+ void _buildLocalElements(AstNode node) {
var holder = ElementHolder();
var elementBuilder = LocalElementBuilder(holder, null);
- full.accept(elementBuilder);
+ node.accept(elementBuilder);
var element = _walker.element;
if (element is ExecutableElementImpl) {
@@ -39,8 +44,6 @@
element.encloseElements(holder.labels);
element.encloseElements(holder.localVariables);
}
-
- return full;
}
void _classDeclaration(ClassDeclaration full, ClassDeclaration partial) {
@@ -74,16 +77,23 @@
_match(partial.name, element);
(partial as ConstructorDeclarationImpl).declaredElement = element;
_walk(_ElementWalker.forExecutable(element), () {
- _node(full.parameters, partial.parameters);
- // TODO(scheglov) Not very nice.
- if (full.initializers.isNotEmpty && partial.initializers.isEmpty) {
- partial.initializers.addAll(full.initializers);
- }
+ _formalParameterList(full.parameters, partial.parameters);
+ _constructorInitializers(full.initializers, partial.initializers);
partial.body = _body(full.body);
});
_metadata(partial.metadata, element);
}
+ void _constructorInitializers(
+ List<ConstructorInitializer> full,
+ List<ConstructorInitializer> partial,
+ ) {
+ if (full.isNotEmpty && partial.isEmpty) {
+ partial.addAll(full);
+ }
+ partial.forEach(_buildLocalElements);
+ }
+
void _declarations(CompilationUnit full, CompilationUnit partial) {
_walk(_ElementWalker.forCompilationUnit(_unitElement), () {
var fullList = full.declarations;
diff --git a/pkg/analyzer/test/src/dart/resolution/constructor_test.dart b/pkg/analyzer/test/src/dart/resolution/constructor_test.dart
new file mode 100644
index 0000000..b91fbda
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/constructor_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2019, 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.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConstructorResolutionTest);
+ });
+}
+
+@reflectiveTest
+class ConstructorResolutionTest extends DriverResolutionTest {
+ test_initializer_field_functionExpression_expressionBody() async {
+ addTestFile(r'''
+class C {
+ final int x;
+ C(int a) : x = (() => a + 1)();
+}
+''');
+ await resolveTestFile();
+ assertElement(findNode.simple('a + 1'), findElement.parameter('a'));
+ }
+
+ test_initializer_field_functionExpression_blockBody() async {
+ addTestFile(r'''
+class C {
+ var x;
+ C(int a) : x = (() {return a + 1;})();
+}
+''');
+ await resolveTestFile();
+ assertElement(findNode.simple('a + 1'), findElement.parameter('a'));
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index ccbc919..8c03439 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -9,6 +9,7 @@
import 'class_test.dart' as class_resolution;
import 'comment_test.dart' as comment;
import 'constant_test.dart' as constant;
+import 'constructor_test.dart' as constructor;
import 'definite_assignment_test.dart' as definite_assignment;
import 'enum_test.dart' as enum_resolution;
import 'flow_analysis_test.dart' as flow_analysis;
@@ -36,6 +37,7 @@
class_resolution.main();
comment.main();
constant.main();
+ constructor.main();
definite_assignment.main();
enum_resolution.main();
flow_analysis.main();