Index: pkg/analyzer/lib/src/generated/resolver.dart |
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart |
index 6f8bfd26ebd96bc9c8e39db39721225541b8cd48..208c15c0e157c8fb14d97e9555f3e02b8399462c 100644 |
--- a/pkg/analyzer/lib/src/generated/resolver.dart |
+++ b/pkg/analyzer/lib/src/generated/resolver.dart |
@@ -6348,6 +6348,12 @@ class ResolverVisitor extends ScopedVisitor { |
@override |
void visitConstructorDeclarationInScope(ConstructorDeclaration node) { |
super.visitConstructorDeclarationInScope(node); |
+ // Because of needing a different scope for the initializer list, the |
+ // overridden implementation of this method cannot cause the visitNode |
+ // method to be invoked. As a result, we have to hard-code using the |
+ // element resolver and type analyzer to visit the constructor declaration. |
+ node.accept(elementResolver); |
+ node.accept(typeAnalyzer); |
safelyVisitComment(node.documentationComment); |
} |
@@ -7744,6 +7750,12 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> { |
LabelScope labelScope; |
/** |
+ * A flag indicating whether to enable support for allowing access to field |
+ * formal parameters in a constructor's initializer list. |
+ */ |
+ bool enableInitializingFormalAccess = false; |
+ |
+ /** |
* The class containing the AST nodes being visited, |
* or `null` if we are not in the scope of a class. |
*/ |
@@ -7774,6 +7786,8 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> { |
} else { |
this.nameScope = nameScope; |
} |
+ enableInitializingFormalAccess = |
+ definingLibrary.context.analysisOptions.enableInitializingFormalAccess; |
} |
/** |
@@ -7910,23 +7924,40 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> { |
@override |
Object visitConstructorDeclaration(ConstructorDeclaration node) { |
ConstructorElement constructorElement = node.element; |
+ if (constructorElement == null) { |
+ StringBuffer buffer = new StringBuffer(); |
+ buffer.write("Missing element for constructor "); |
+ buffer.write(node.returnType.name); |
+ if (node.name != null) { |
+ buffer.write("."); |
+ buffer.write(node.name.name); |
+ } |
+ buffer.write(" in "); |
+ buffer.write(definingLibrary.source.fullName); |
+ AnalysisEngine.instance.logger.logInformation(buffer.toString(), |
+ new CaughtException(new AnalysisException(), null)); |
+ } |
Scope outerScope = nameScope; |
try { |
- if (constructorElement == null) { |
- StringBuffer buffer = new StringBuffer(); |
- buffer.write("Missing element for constructor "); |
- buffer.write(node.returnType.name); |
- if (node.name != null) { |
- buffer.write("."); |
- buffer.write(node.name.name); |
- } |
- buffer.write(" in "); |
- buffer.write(definingLibrary.source.fullName); |
- AnalysisEngine.instance.logger.logInformation(buffer.toString(), |
- new CaughtException(new AnalysisException(), null)); |
- } else { |
+ if (constructorElement != null) { |
nameScope = new FunctionScope(nameScope, constructorElement); |
} |
+ node.documentationComment?.accept(this); |
+ node.metadata.accept(this); |
+ node.returnType?.accept(this); |
+ node.name?.accept(this); |
+ node.parameters?.accept(this); |
+ Scope functionScope = nameScope; |
+ try { |
+ if (constructorElement != null && enableInitializingFormalAccess) { |
+ nameScope = |
+ new ConstructorInitializerScope(nameScope, constructorElement); |
+ } |
+ node.initializers.accept(this); |
+ } finally { |
+ nameScope = functionScope; |
+ } |
+ node.redirectedConstructor?.accept(this); |
visitConstructorDeclarationInScope(node); |
} finally { |
nameScope = outerScope; |
@@ -7935,7 +7966,7 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> { |
} |
void visitConstructorDeclarationInScope(ConstructorDeclaration node) { |
- super.visitConstructorDeclaration(node); |
+ node.body?.accept(this); |
} |
@override |