Chromium Code Reviews| 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 bc4ef3e88d071c65df450d4e9c4b300ae57a15f5..d117e877c9a12954c2b39e3994ef4ceb07c1b67e 100644 |
| --- a/pkg/analyzer/lib/src/generated/resolver.dart |
| +++ b/pkg/analyzer/lib/src/generated/resolver.dart |
| @@ -9438,6 +9438,8 @@ class TypeResolverVisitor extends ScopedVisitor { |
| final TypeResolverMode mode; |
| + bool _visitAllInLocalMode = false; |
| + |
| /** |
| * Initialize a newly created visitor to resolve the nodes in an AST node. |
| * |
| @@ -9496,14 +9498,6 @@ class TypeResolverVisitor extends ScopedVisitor { |
| } |
| @override |
| - Object visitBlockFunctionBody(BlockFunctionBody node) { |
| - if (mode == TypeResolverMode.api) { |
| - return null; |
| - } |
| - return super.visitBlockFunctionBody(node); |
| - } |
| - |
| - @override |
| Object visitCatchClause(CatchClause node) { |
| super.visitCatchClause(node); |
| SimpleIdentifier exception = node.exceptionParameter; |
| @@ -9662,14 +9656,6 @@ class TypeResolverVisitor extends ScopedVisitor { |
| } |
| @override |
| - Object visitExpressionFunctionBody(ExpressionFunctionBody node) { |
| - if (mode == TypeResolverMode.api) { |
| - return null; |
| - } |
| - return super.visitExpressionFunctionBody(node); |
| - } |
| - |
| - @override |
| Object visitFieldFormalParameter(FieldFormalParameter node) { |
| super.visitFieldFormalParameter(node); |
| Element element = node.identifier.staticElement; |
| @@ -9782,10 +9768,14 @@ class TypeResolverVisitor extends ScopedVisitor { |
| @override |
| Object visitNode(AstNode node) { |
| - // In API mode we need to ignore: |
| + // In API mode we need to skip: |
| + // - function bodies; |
| // - default values of parameters; |
| // - initializers of top-level variables. |
| if (mode == TypeResolverMode.api) { |
| + if (node is FunctionBody) { |
| + return null; |
| + } |
| if (node is DefaultFormalParameter) { |
| node.parameter.accept(this); |
| return null; |
| @@ -9794,6 +9784,89 @@ class TypeResolverVisitor extends ScopedVisitor { |
| return null; |
| } |
| } |
| + |
| + // In local mode we need to resolve only: |
| + // - function bodies; |
| + // - default values of parameters; |
| + // - initializers of top-level variables. |
| + // So, we carefully visit only nodes that are, or contain, these nodes. |
| + // The client may choose to start visiting any node, but we still want to |
| + // resolve only type names that are local. |
| + if (mode == TypeResolverMode.local) { |
| + // We are in the state of visiting all nodes. |
| + if (_visitAllInLocalMode) { |
| + return super.visitNode(node); |
| + } |
| + |
| + /** |
| + * Visit the given [node] and all its children. |
| + */ |
| + void visitAllNodes(AstNode node) { |
| + if (node != null) { |
| + bool wasVisitAllInLocalMode = _visitAllInLocalMode; |
| + try { |
| + _visitAllInLocalMode = true; |
| + node.accept(this); |
| + } finally { |
| + _visitAllInLocalMode = wasVisitAllInLocalMode; |
| + } |
| + } |
| + } |
| + |
| + // Visit only nodes that may contain type names to resolve. |
| + if (node is FunctionBody) { |
|
Brian Wilkerson
2016/10/19 16:30:18
This like of is tests is kind of ugly, but if ther
Paul Berry
2016/10/19 16:37:49
Another possibility: create a little visitor which
scheglov
2016/10/19 16:47:10
Done.
|
| + visitAllNodes(node); |
| + return null; |
| + } |
| + if (node is DefaultFormalParameter) { |
| + visitAllNodes(node.defaultValue); |
| + return null; |
| + } |
| + if (node is CompilationUnit) { |
| + node.declarations.forEach(visitNode); |
| + return null; |
| + } |
| + if (node is ClassDeclaration) { |
| + for (ClassMember member in node.members) { |
| + visitNode(member); |
| + } |
| + return null; |
| + } |
| + if (node is FieldDeclaration) { |
| + visitNode(node.fields); |
| + return null; |
| + } |
| + if (node is FunctionDeclaration) { |
| + node.functionExpression.parameters?.accept(this); |
| + visitAllNodes(node.functionExpression.body); |
| + return null; |
| + } |
| + if (node is FormalParameterList) { |
| + node.parameters.accept(this); |
| + return null; |
| + } |
| + if (node is MethodDeclaration) { |
| + visitAllNodes(node.body); |
| + return null; |
| + } |
| + if (node is TopLevelVariableDeclaration) { |
| + visitNode(node.variables); |
| + return null; |
| + } |
| + if (node is VariableDeclaration) { |
| + visitAllNodes(node.initializer); |
| + return null; |
| + } |
| + if (node is VariableDeclarationList) { |
| + node.variables.forEach(visitNode); |
| + return null; |
| + } |
| + |
| + // Ignore all other nodes. |
| + return null; |
| + } |
| + |
| + // The mode in which we visit all nodes. |
| return super.visitNode(node); |
| } |