Index: pkg/analyzer/lib/src/dart/resolver/scope.dart |
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart |
index b514b224044e57f52856c8e7350f225862c413de..9c6ece23fe6bc25e4db3d15b065c1ac631da95f0 100644 |
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart |
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart |
@@ -16,6 +16,49 @@ import 'package:analyzer/src/generated/java_engine.dart'; |
import 'package:analyzer/src/generated/source.dart'; |
/** |
+ * The scope defined by a block. |
+ */ |
+class BlockScope extends EnclosedScope { |
+ /** |
+ * Initialize a newly created scope, enclosed within the [enclosingScope], |
+ * based on the given [classElement]. |
+ */ |
+ BlockScope(Scope enclosingScope, Block block) : super(enclosingScope) { |
+ if (block == null) { |
+ throw new IllegalArgumentException("block cannot be null"); |
+ } |
+ _defineElements(block); |
+ } |
+ |
+ void _defineElements(block) { |
scheglov
2016/09/02 23:46:50
Type for "block"?
Brian Wilkerson
2016/09/03 17:12:37
Done
|
+ for (var element in elementsInBlock(block)) { |
+ define(element); |
+ } |
scheglov
2016/09/02 23:46:50
This could be written as:
elementsInBlock(block).f
Brian Wilkerson
2016/09/03 17:12:37
Leaving it as is.
|
+ } |
+ |
+ /** |
+ * Return the elements that are declared directly in the given [block]. This |
+ * does not include elements declared in nested blocks. |
+ */ |
+ static Iterable<Element> elementsInBlock(Block block) sync* { |
+ NodeList<Statement> statements = block.statements; |
+ int statementCount = statements.length; |
+ for (int i = 0; i < statementCount; i++) { |
+ Statement statement = statements[i]; |
+ if (statement is VariableDeclarationStatement) { |
+ NodeList<VariableDeclaration> variables = statement.variables.variables; |
+ int variableCount = variables.length; |
+ for (int j = 0; j < variableCount; j++) { |
+ yield variables[j].element; |
+ } |
+ } else if (statement is FunctionDeclarationStatement) { |
+ yield statement.functionDeclaration.element; |
+ } |
+ } |
+ } |
+} |
+ |
+/** |
* The scope defined by a class. |
*/ |
class ClassScope extends EnclosedScope { |
@@ -81,13 +124,6 @@ class EnclosedScope extends Scope { |
final Scope enclosingScope; |
/** |
- * A table mapping names that will be defined in this scope, but right now are |
- * not initialized. According to the scoping rules these names are hidden, |
- * even if they were defined in an outer scope. |
- */ |
- HashMap<String, Element> _hiddenElements = null; |
- |
- /** |
* Initialize a newly created scope, enclosed within the [enclosingScope]. |
*/ |
EnclosedScope(this.enclosingScope); |
@@ -95,21 +131,6 @@ class EnclosedScope extends Scope { |
@override |
AnalysisErrorListener get errorListener => enclosingScope.errorListener; |
- /** |
- * Record that given [element] is declared in this scope, but hasn't been |
- * initialized yet, so it is error to use. If there is already an element with |
- * the given name defined in an outer scope, then it will become unavailable. |
- */ |
- void hide(Element element) { |
- if (element != null) { |
- String name = element.name; |
- if (name != null && !name.isEmpty) { |
- _hiddenElements ??= new HashMap<String, Element>(); |
- _hiddenElements[name] = element; |
- } |
- } |
- } |
- |
@override |
Element internalLookup( |
Identifier identifier, String name, LibraryElement referencingLibrary) { |
@@ -117,19 +138,6 @@ class EnclosedScope extends Scope { |
if (element != null) { |
return element; |
} |
- // May be there is a hidden Element. |
- if (_hiddenElements != null) { |
- Element hiddenElement = _hiddenElements[name]; |
- if (hiddenElement != null) { |
- errorListener.onError(new AnalysisError( |
- getSource(identifier), |
- identifier.offset, |
- identifier.length, |
- CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, |
- [name])); |
- return hiddenElement; |
- } |
- } |
// Check enclosing scope. |
return enclosingScope.internalLookup(identifier, name, referencingLibrary); |
} |