Index: pkg/compiler/lib/src/resolution/scope.dart |
diff --git a/pkg/compiler/lib/src/resolution/scope.dart b/pkg/compiler/lib/src/resolution/scope.dart |
index 75c3de9b7dc0c5eda317ccbe01d97bbcb6b6f5b6..793258247c45cc783699b6c475c27d4ce03e04ce 100644 |
--- a/pkg/compiler/lib/src/resolution/scope.dart |
+++ b/pkg/compiler/lib/src/resolution/scope.dart |
@@ -9,8 +9,11 @@ import '../elements/elements.dart'; |
abstract class Scope { |
/** |
- * Adds [element] to this scope. This operation is only allowed on mutable |
- * scopes such as [MethodScope] and [BlockScope]. |
+ * If an [Element] named `element.name` has already been added to this |
+ * [Scope], return that element and make no changes. If no such element has |
+ * been added, add the given [element] to this [Scope], and return [element]. |
+ * Note that this operation is only allowed on mutable scopes such as |
+ * [MethodScope] and [BlockScope]. |
*/ |
Element add(Element element); |
@@ -123,6 +126,46 @@ abstract class MutableScope extends NestedScope { |
Element localLookup(String name) => elements[name]; |
} |
+/** |
+ * [ExtensionScope] enables the creation of an extended version of an |
+ * existing [NestedScope], received during construction and stored in |
+ * [extendee]. An [ExtensionScope] will treat an added `element` as conflicting |
+ * if an element `e` where `e.name == element.name` exists among the elements |
+ * added to this [ExtensionScope], or among the ones added to [extendee] |
+ * (according to `extendee.localLookup`). In this sense, it represents the |
+ * union of the bindings stored locally in [elements] and the bindings in |
+ * [extendee], not a new scope which is nested inside [extendee]. |
+ * |
+ * Note that it is required that no bindings are added to [extendee] during the |
+ * lifetime of this [ExtensionScope]: That would enable duplicates to be |
+ * introduced into the extended scope consisting of [this] plus [extendee] |
+ * without detection. |
+ */ |
+class ExtensionScope extends Scope { |
+ final NestedScope extendee; |
+ final Map<String, Element> elements; |
+ |
+ ExtensionScope(this.extendee) : this.elements = new Map<String, Element>() { |
+ assert(extendee != null); |
+ } |
+ |
+ Element lookup(String name) { |
+ Element result = elements[name]; |
+ if (result != null) return result; |
+ return extendee.lookup(name); |
+ } |
+ |
+ Element add(Element newElement) { |
+ if (elements.containsKey(newElement.name)) { |
+ return elements[newElement.name]; |
+ } |
+ Element existing = extendee.localLookup(newElement.name); |
+ if (existing != null) return existing; |
+ elements[newElement.name] = newElement; |
+ return newElement; |
+ } |
+} |
+ |
class MethodScope extends MutableScope { |
final Element element; |
@@ -178,6 +221,7 @@ class LibraryScope implements Scope { |
Element localLookup(String name) => library.find(name); |
Element lookup(String name) => localLookup(name); |
+ bool isDuplicate(Element element) => element == localLookup(element.name); |
Johnni Winther
2016/06/29 07:22:24
Remove this.
eernst
2016/06/29 09:28:31
Done.
|
Element add(Element newElement) { |
throw "Cannot add an element to a library scope"; |