| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 part of resolution; | |
| 6 | |
| 7 abstract class Scope { | |
| 8 /** | |
| 9 * Adds [element] to this scope. This operation is only allowed on mutable | |
| 10 * scopes such as [MethodScope] and [BlockScope]. | |
| 11 */ | |
| 12 Element add(Element element); | |
| 13 | |
| 14 /** | |
| 15 * Looks up the [Element] for [name] in this scope. | |
| 16 */ | |
| 17 Element lookup(String name); | |
| 18 | |
| 19 static Scope buildEnclosingScope(Element element) { | |
| 20 return element.enclosingElement != null | |
| 21 ? element.enclosingElement.buildScope() : element.buildScope(); | |
| 22 } | |
| 23 } | |
| 24 | |
| 25 abstract class NestedScope extends Scope { | |
| 26 final Scope parent; | |
| 27 | |
| 28 NestedScope(this.parent); | |
| 29 | |
| 30 Element lookup(String name) { | |
| 31 Element result = localLookup(name); | |
| 32 if (result != null) return result; | |
| 33 return parent.lookup(name); | |
| 34 } | |
| 35 | |
| 36 Element localLookup(String name); | |
| 37 } | |
| 38 | |
| 39 class VariableDefinitionScope extends NestedScope { | |
| 40 final String variableName; | |
| 41 bool variableReferencedInInitializer = false; | |
| 42 | |
| 43 VariableDefinitionScope(Scope parent, this.variableName) : super(parent); | |
| 44 | |
| 45 Element localLookup(String name) { | |
| 46 if (name == variableName) { | |
| 47 variableReferencedInInitializer = true; | |
| 48 } | |
| 49 return null; | |
| 50 } | |
| 51 | |
| 52 Element add(Element newElement) { | |
| 53 throw "Cannot add element to VariableDefinitionScope"; | |
| 54 } | |
| 55 } | |
| 56 | |
| 57 /** | |
| 58 * [TypeDeclarationScope] defines the outer scope of a type declaration in | |
| 59 * which the declared type variables and the entities in the enclosing scope are | |
| 60 * available but where declared and inherited members are not available. This | |
| 61 * scope is only used for class declarations during resolution of the | |
| 62 * class hierarchy. In all other cases [ClassScope] is used. | |
| 63 */ | |
| 64 class TypeDeclarationScope extends NestedScope { | |
| 65 final TypeDeclarationElement element; | |
| 66 | |
| 67 TypeDeclarationScope(parent, this.element) | |
| 68 : super(parent) { | |
| 69 assert(parent != null); | |
| 70 } | |
| 71 | |
| 72 Element add(Element newElement) { | |
| 73 throw "Cannot add element to TypeDeclarationScope"; | |
| 74 } | |
| 75 | |
| 76 Element lookupTypeVariable(String name) { | |
| 77 List<DartType> typeVariables = element.typeVariables; | |
| 78 for (TypeVariableType type in typeVariables) { | |
| 79 if (type.name == name) { | |
| 80 return type.element; | |
| 81 } | |
| 82 } | |
| 83 return null; | |
| 84 } | |
| 85 | |
| 86 Element localLookup(String name) => lookupTypeVariable(name); | |
| 87 | |
| 88 String toString() => | |
| 89 'TypeDeclarationScope($element)'; | |
| 90 } | |
| 91 | |
| 92 abstract class MutableScope extends NestedScope { | |
| 93 final Map<String, Element> elements; | |
| 94 | |
| 95 MutableScope(Scope parent) | |
| 96 : super(parent), | |
| 97 this.elements = new Map<String, Element>() { | |
| 98 assert(parent != null); | |
| 99 } | |
| 100 | |
| 101 Element add(Element newElement) { | |
| 102 if (elements.containsKey(newElement.name)) { | |
| 103 return elements[newElement.name]; | |
| 104 } | |
| 105 elements[newElement.name] = newElement; | |
| 106 return newElement; | |
| 107 } | |
| 108 | |
| 109 Element localLookup(String name) => elements[name]; | |
| 110 } | |
| 111 | |
| 112 class MethodScope extends MutableScope { | |
| 113 final Element element; | |
| 114 | |
| 115 MethodScope(Scope parent, this.element) | |
| 116 : super(parent); | |
| 117 | |
| 118 String toString() => 'MethodScope($element${elements.keys.toList()})'; | |
| 119 } | |
| 120 | |
| 121 class BlockScope extends MutableScope { | |
| 122 BlockScope(Scope parent) : super(parent); | |
| 123 | |
| 124 String toString() => 'BlockScope(${elements.keys.toList()})'; | |
| 125 } | |
| 126 | |
| 127 /** | |
| 128 * [ClassScope] defines the inner scope of a class/interface declaration in | |
| 129 * which declared members, declared type variables, entities in the enclosing | |
| 130 * scope and inherited members are available, in the given order. | |
| 131 */ | |
| 132 class ClassScope extends TypeDeclarationScope { | |
| 133 ClassElement get element => super.element; | |
| 134 | |
| 135 ClassScope(Scope parentScope, ClassElement element) | |
| 136 : super(parentScope, element) { | |
| 137 assert(parent != null); | |
| 138 } | |
| 139 | |
| 140 Element localLookup(String name) { | |
| 141 Element result = element.lookupLocalMember(name); | |
| 142 if (result != null) return result; | |
| 143 return super.localLookup(name); | |
| 144 } | |
| 145 | |
| 146 Element lookup(String name) { | |
| 147 Element result = localLookup(name); | |
| 148 if (result != null) return result; | |
| 149 result = parent.lookup(name); | |
| 150 if (result != null) return result; | |
| 151 return element.lookupSuperMember(name); | |
| 152 } | |
| 153 | |
| 154 Element add(Element newElement) { | |
| 155 throw "Cannot add an element in a class scope"; | |
| 156 } | |
| 157 | |
| 158 String toString() => 'ClassScope($element)'; | |
| 159 } | |
| 160 | |
| 161 class LibraryScope implements Scope { | |
| 162 final LibraryElement library; | |
| 163 | |
| 164 LibraryScope(LibraryElement this.library); | |
| 165 | |
| 166 Element localLookup(String name) => library.find(name); | |
| 167 Element lookup(String name) => localLookup(name); | |
| 168 | |
| 169 Element add(Element newElement) { | |
| 170 throw "Cannot add an element to a library scope"; | |
| 171 } | |
| 172 | |
| 173 String toString() => 'LibraryScope($library)'; | |
| 174 } | |
| OLD | NEW |