OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012, the Dart project authors. | 2 * Copyright (c) 2012, the Dart project authors. |
3 * | 3 * |
4 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u
se this file except | 4 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u
se this file except |
5 * in compliance with the License. You may obtain a copy of the License at | 5 * in compliance with the License. You may obtain a copy of the License at |
6 * | 6 * |
7 * http://www.eclipse.org/legal/epl-v10.html | 7 * http://www.eclipse.org/legal/epl-v10.html |
8 * | 8 * |
9 * Unless required by applicable law or agreed to in writing, software distribut
ed under the License | 9 * Unless required by applicable law or agreed to in writing, software distribut
ed under the License |
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K
IND, either express | 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K
IND, either express |
11 * or implied. See the License for the specific language governing permissions a
nd limitations under | 11 * or implied. See the License for the specific language governing permissions a
nd limitations under |
12 * the License. | 12 * the License. |
13 */ | 13 */ |
14 package com.google.dart.engine.internal.scope; | 14 package com.google.dart.engine.internal.scope; |
15 | 15 |
16 import com.google.dart.engine.ast.Identifier; | 16 import com.google.dart.engine.ast.Identifier; |
17 import com.google.dart.engine.element.Element; | 17 import com.google.dart.engine.element.Element; |
18 import com.google.dart.engine.element.LibraryElement; | 18 import com.google.dart.engine.element.LibraryElement; |
19 import com.google.dart.engine.error.AnalysisError; | 19 import com.google.dart.engine.error.AnalysisError; |
20 import com.google.dart.engine.error.AnalysisErrorListener; | 20 import com.google.dart.engine.error.AnalysisErrorListener; |
21 import com.google.dart.engine.error.CompileTimeErrorCode; | 21 import com.google.dart.engine.error.CompileTimeErrorCode; |
22 | 22 |
23 import java.util.HashSet; | 23 import java.util.HashMap; |
24 import java.util.Set; | |
25 | 24 |
26 /** | 25 /** |
27 * Instances of the class {@code EnclosedScope} implement a scope that is lexica
lly enclosed in | 26 * Instances of the class {@code EnclosedScope} implement a scope that is lexica
lly enclosed in |
28 * another scope. | 27 * another scope. |
29 * | 28 * |
30 * @coverage dart.engine.resolver | 29 * @coverage dart.engine.resolver |
31 */ | 30 */ |
32 public class EnclosedScope extends Scope { | 31 public class EnclosedScope extends Scope { |
33 /** | 32 /** |
34 * The scope in which this scope is lexically enclosed. | 33 * The scope in which this scope is lexically enclosed. |
35 */ | 34 */ |
36 private Scope enclosingScope; | 35 private Scope enclosingScope; |
37 | 36 |
38 /** | 37 /** |
39 * A set of names that will be defined in this scope, but right now are not de
fined. However | 38 * A table mapping names that will be defined in this scope, but right now are
not initialized. |
40 * according to the scoping rules these names are hidden, even if they were de
fined in an outer | 39 * According to the scoping rules these names are hidden, even if they were de
fined in an outer |
41 * scope. | 40 * scope. |
42 */ | 41 */ |
43 private Set<String> hiddenNames = new HashSet<String>(); | 42 private HashMap<String, Element> hiddenElements = new HashMap<String, Element>
(); |
44 | 43 |
45 /** | 44 /** |
46 * Initialize a newly created scope enclosed within another scope. | 45 * Initialize a newly created scope enclosed within another scope. |
47 * | 46 * |
48 * @param enclosingScope the scope in which this scope is lexically enclosed | 47 * @param enclosingScope the scope in which this scope is lexically enclosed |
49 */ | 48 */ |
50 public EnclosedScope(Scope enclosingScope) { | 49 public EnclosedScope(Scope enclosingScope) { |
51 this.enclosingScope = enclosingScope; | 50 this.enclosingScope = enclosingScope; |
52 } | 51 } |
53 | 52 |
54 @Override | 53 @Override |
55 public Scope getEnclosingScope() { | 54 public Scope getEnclosingScope() { |
56 return enclosingScope; | 55 return enclosingScope; |
57 } | 56 } |
58 | 57 |
59 @Override | 58 @Override |
60 public AnalysisErrorListener getErrorListener() { | 59 public AnalysisErrorListener getErrorListener() { |
61 return enclosingScope.getErrorListener(); | 60 return enclosingScope.getErrorListener(); |
62 } | 61 } |
63 | 62 |
64 /** | 63 /** |
65 * Hides the name of the given element in this scope. If there is already an e
lement with the | 64 * Record that given element is declared in this scope, but hasn't been initia
lized yet, so it is |
66 * given name defined in an outer scope, then it will become unavailable. | 65 * error to use. If there is already an element with the given name defined in
an outer scope, |
| 66 * then it will become unavailable. |
67 * | 67 * |
68 * @param element the element to be hidden in this scope | 68 * @param element the element declared, but not initialized in this scope |
69 */ | 69 */ |
70 public void hide(Element element) { | 70 public void hide(Element element) { |
71 if (element != null) { | 71 if (element != null) { |
72 String name = element.getName(); | 72 String name = element.getName(); |
73 if (name != null && !name.isEmpty()) { | 73 if (name != null && !name.isEmpty()) { |
74 hiddenNames.add(name); | 74 hiddenElements.put(name, element); |
75 } | 75 } |
76 } | 76 } |
77 } | 77 } |
78 | 78 |
79 @Override | 79 @Override |
80 protected Element lookup(Identifier identifier, String name, LibraryElement re
ferencingLibrary) { | 80 protected Element lookup(Identifier identifier, String name, LibraryElement re
ferencingLibrary) { |
81 Element element = localLookup(name, referencingLibrary); | 81 Element element = localLookup(name, referencingLibrary); |
82 if (element != null) { | 82 if (element != null) { |
83 return element; | 83 return element; |
84 } | 84 } |
85 if (hiddenNames.contains(name)) { | 85 // May be there is a hidden Element. |
| 86 Element hiddenElement = hiddenElements.get(name); |
| 87 if (hiddenElement != null) { |
86 getErrorListener().onError( | 88 getErrorListener().onError( |
87 new AnalysisError( | 89 new AnalysisError( |
88 getSource(identifier), | 90 getSource(identifier), |
89 identifier.getOffset(), | 91 identifier.getOffset(), |
90 identifier.getLength(), | 92 identifier.getLength(), |
91 CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION)); | 93 CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION)); |
92 //return null; | 94 return hiddenElement; |
93 } | 95 } |
| 96 // Check enclosing scope. |
94 return enclosingScope.lookup(identifier, name, referencingLibrary); | 97 return enclosingScope.lookup(identifier, name, referencingLibrary); |
95 } | 98 } |
96 } | 99 } |
OLD | NEW |