| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library elements.modelx; | 5 library elements.modelx; |
| 6 | 6 |
| 7 import 'elements.dart'; | 7 import 'elements.dart'; |
| 8 import '../helpers/helpers.dart'; | 8 import '../helpers/helpers.dart'; |
| 9 import '../tree/tree.dart'; | 9 import '../tree/tree.dart'; |
| 10 import '../util/util.dart'; | 10 import '../util/util.dart'; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 abstract class ElementX implements Element { | 37 abstract class ElementX implements Element { |
| 38 static int elementHashCode = 0; | 38 static int elementHashCode = 0; |
| 39 | 39 |
| 40 final String name; | 40 final String name; |
| 41 final ElementKind kind; | 41 final ElementKind kind; |
| 42 final Element enclosingElement; | 42 final Element enclosingElement; |
| 43 final int hashCode = ++elementHashCode; | 43 final int hashCode = ++elementHashCode; |
| 44 Link<MetadataAnnotation> metadata = const Link<MetadataAnnotation>(); | 44 Link<MetadataAnnotation> metadata = const Link<MetadataAnnotation>(); |
| 45 | 45 |
| 46 ElementX(this.name, this.kind, this.enclosingElement) { | 46 ElementX(this.name, this.kind, this.enclosingElement) { |
| 47 assert(isErroneous() || getImplementationLibrary() != null); | 47 assert(isErroneous || implementationLibrary != null); |
| 48 } | 48 } |
| 49 | 49 |
| 50 Modifiers get modifiers => Modifiers.EMPTY; | 50 Modifiers get modifiers => Modifiers.EMPTY; |
| 51 | 51 |
| 52 Node parseNode(DiagnosticListener listener) { | 52 Node parseNode(DiagnosticListener listener) { |
| 53 listener.internalError(this, 'Not implemented.'); | 53 listener.internalError(this, 'Not implemented.'); |
| 54 return null; | 54 return null; |
| 55 } | 55 } |
| 56 | 56 |
| 57 DartType computeType(Compiler compiler) { | 57 DartType computeType(Compiler compiler) { |
| 58 compiler.internalError(this, "$this.computeType."); | 58 compiler.internalError(this, "$this.computeType."); |
| 59 return null; | 59 return null; |
| 60 } | 60 } |
| 61 | 61 |
| 62 void addMetadata(MetadataAnnotation annotation) { | 62 void addMetadata(MetadataAnnotation annotation) { |
| 63 assert(annotation.annotatedElement == null); | 63 assert(annotation.annotatedElement == null); |
| 64 annotation.annotatedElement = this; | 64 annotation.annotatedElement = this; |
| 65 addMetadataInternal(annotation); | 65 addMetadataInternal(annotation); |
| 66 } | 66 } |
| 67 | 67 |
| 68 void addMetadataInternal(MetadataAnnotation annotation) { | 68 void addMetadataInternal(MetadataAnnotation annotation) { |
| 69 metadata = metadata.prepend(annotation); | 69 metadata = metadata.prepend(annotation); |
| 70 } | 70 } |
| 71 | 71 |
| 72 | 72 |
| 73 bool isFunction() => identical(kind, ElementKind.FUNCTION); | 73 bool get isFunction => identical(kind, ElementKind.FUNCTION); |
| 74 bool isConstructor() => isFactoryConstructor() || isGenerativeConstructor(); | 74 bool get isConstructor => isFactoryConstructor || isGenerativeConstructor; |
| 75 bool isClosure() => false; | 75 bool get isClosure => false; |
| 76 bool isMember() { | 76 bool get isMember { |
| 77 // Check that this element is defined in the scope of a Class. | 77 // Check that this element is defined in the scope of a Class. |
| 78 return enclosingElement != null && enclosingElement.isClass(); | 78 return enclosingElement != null && enclosingElement.isClass; |
| 79 } | 79 } |
| 80 bool isInstanceMember() => false; | 80 bool get isInstanceMember => false; |
| 81 bool isDeferredLoaderGetter() => false; | 81 bool get isDeferredLoaderGetter => false; |
| 82 | 82 |
| 83 bool isFactoryConstructor() => modifiers.isFactory(); | 83 bool get isFactoryConstructor => modifiers.isFactory; |
| 84 bool isGenerativeConstructor() => | 84 bool get isGenerativeConstructor => |
| 85 identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR); | 85 identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR); |
| 86 bool isGenerativeConstructorBody() => | 86 bool get isGenerativeConstructorBody => |
| 87 identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR_BODY); | 87 identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR_BODY); |
| 88 bool isCompilationUnit() => identical(kind, ElementKind.COMPILATION_UNIT); | 88 bool get isCompilationUnit => identical(kind, ElementKind.COMPILATION_UNIT); |
| 89 bool isClass() => identical(kind, ElementKind.CLASS); | 89 bool get isClass => identical(kind, ElementKind.CLASS); |
| 90 bool isPrefix() => identical(kind, ElementKind.PREFIX); | 90 bool get isPrefix => identical(kind, ElementKind.PREFIX); |
| 91 bool isVariable() => identical(kind, ElementKind.VARIABLE); | 91 bool get isVariable => identical(kind, ElementKind.VARIABLE); |
| 92 bool isParameter() => identical(kind, ElementKind.PARAMETER); | 92 bool get isParameter => identical(kind, ElementKind.PARAMETER); |
| 93 bool isStatement() => identical(kind, ElementKind.STATEMENT); | 93 bool get isStatement => identical(kind, ElementKind.STATEMENT); |
| 94 bool isTypedef() => identical(kind, ElementKind.TYPEDEF); | 94 bool get isTypedef => identical(kind, ElementKind.TYPEDEF); |
| 95 bool isTypeVariable() => identical(kind, ElementKind.TYPE_VARIABLE); | 95 bool get isTypeVariable => identical(kind, ElementKind.TYPE_VARIABLE); |
| 96 bool isField() => identical(kind, ElementKind.FIELD); | 96 bool get isField => identical(kind, ElementKind.FIELD); |
| 97 bool isFieldParameter() => identical(kind, ElementKind.FIELD_PARAMETER); | 97 bool get isFieldParameter => identical(kind, ElementKind.FIELD_PARAMETER); |
| 98 bool isAbstractField() => identical(kind, ElementKind.ABSTRACT_FIELD); | 98 bool get isAbstractField => identical(kind, ElementKind.ABSTRACT_FIELD); |
| 99 bool isGetter() => identical(kind, ElementKind.GETTER); | 99 bool get isGetter => identical(kind, ElementKind.GETTER); |
| 100 bool isSetter() => identical(kind, ElementKind.SETTER); | 100 bool get isSetter => identical(kind, ElementKind.SETTER); |
| 101 bool isAccessor() => isGetter() || isSetter(); | 101 bool get isAccessor => isGetter || isSetter; |
| 102 bool isLibrary() => identical(kind, ElementKind.LIBRARY); | 102 bool get isLibrary => identical(kind, ElementKind.LIBRARY); |
| 103 bool impliesType() => (kind.category & ElementCategory.IMPLIES_TYPE) != 0; | 103 bool get impliesType => (kind.category & ElementCategory.IMPLIES_TYPE) != 0; |
| 104 | 104 |
| 105 /** See [ErroneousElement] for documentation. */ | 105 /** See [ErroneousElement] for documentation. */ |
| 106 bool isErroneous() => false; | 106 bool get isErroneous => false; |
| 107 | 107 |
| 108 /** See [AmbiguousElement] for documentation. */ | 108 /** See [AmbiguousElement] for documentation. */ |
| 109 bool isAmbiguous() => false; | 109 bool get isAmbiguous => false; |
| 110 | 110 |
| 111 /** See [WarnOnUseElement] for documentation. */ | 111 /** See [WarnOnUseElement] for documentation. */ |
| 112 bool isWarnOnUse() => false; | 112 bool get isWarnOnUse => false; |
| 113 | 113 |
| 114 bool get isPatched => false; | 114 bool get isPatched => false; |
| 115 | 115 |
| 116 bool get isPatch => false; | 116 bool get isPatch => false; |
| 117 | 117 |
| 118 bool get isImplementation => true; | 118 bool get isImplementation => true; |
| 119 | 119 |
| 120 bool get isDeclaration => true; | 120 bool get isDeclaration => true; |
| 121 | 121 |
| 122 Element get implementation => this; | 122 Element get implementation => this; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 134 bool get isSynthesized => false; | 134 bool get isSynthesized => false; |
| 135 | 135 |
| 136 bool get isForwardingConstructor => false; | 136 bool get isForwardingConstructor => false; |
| 137 | 137 |
| 138 bool get isMixinApplication => false; | 138 bool get isMixinApplication => false; |
| 139 | 139 |
| 140 // TODO(johnniwinther): This breaks for libraries (for which enclosing | 140 // TODO(johnniwinther): This breaks for libraries (for which enclosing |
| 141 // elements are null) and is invalid for top level variable declarations for | 141 // elements are null) and is invalid for top level variable declarations for |
| 142 // which the enclosing element is a VariableDeclarations and not a compilation | 142 // which the enclosing element is a VariableDeclarations and not a compilation |
| 143 // unit. | 143 // unit. |
| 144 bool isTopLevel() { | 144 bool get isTopLevel { |
| 145 return enclosingElement != null && enclosingElement.isCompilationUnit(); | 145 return enclosingElement != null && enclosingElement.isCompilationUnit; |
| 146 } | 146 } |
| 147 | 147 |
| 148 bool isAssignable() { | 148 bool get isAssignable { |
| 149 if (modifiers.isFinalOrConst()) return false; | 149 if (modifiers.isFinalOrConst) return false; |
| 150 if (isFunction() || isGenerativeConstructor()) return false; | 150 if (isFunction || isGenerativeConstructor) return false; |
| 151 return true; | 151 return true; |
| 152 } | 152 } |
| 153 | 153 |
| 154 Token position() => null; | 154 Token get position => null; |
| 155 | 155 |
| 156 Token findMyName(Token token) { | 156 Token findMyName(Token token) { |
| 157 return findNameToken(token, isConstructor(), name, enclosingElement.name); | 157 return findNameToken(token, isConstructor, name, enclosingElement.name); |
| 158 } | 158 } |
| 159 | 159 |
| 160 static Token findNameToken(Token token, bool isConstructor, String name, | 160 static Token findNameToken(Token token, bool isConstructor, String name, |
| 161 String enclosingClassName) { | 161 String enclosingClassName) { |
| 162 // We search for the token that has the name of this element. | 162 // We search for the token that has the name of this element. |
| 163 // For constructors, that doesn't work because they may have | 163 // For constructors, that doesn't work because they may have |
| 164 // named formed out of multiple tokens (named constructors) so | 164 // named formed out of multiple tokens (named constructors) so |
| 165 // for those we search for the class name instead. | 165 // for those we search for the class name instead. |
| 166 String needle = isConstructor ? enclosingClassName : name; | 166 String needle = isConstructor ? enclosingClassName : name; |
| 167 // The unary '-' operator has a special element name (specified). | 167 // The unary '-' operator has a special element name (specified). |
| 168 if (needle == 'unary-') needle = '-'; | 168 if (needle == 'unary-') needle = '-'; |
| 169 for (Token t = token; EOF_TOKEN != t.kind; t = t.next) { | 169 for (Token t = token; EOF_TOKEN != t.kind; t = t.next) { |
| 170 if (needle == t.value) return t; | 170 if (needle == t.value) return t; |
| 171 } | 171 } |
| 172 return token; | 172 return token; |
| 173 } | 173 } |
| 174 | 174 |
| 175 CompilationUnitElement getCompilationUnit() { | 175 CompilationUnitElement get compilationUnit { |
| 176 Element element = this; | 176 Element element = this; |
| 177 while (!element.isCompilationUnit()) { | 177 while (!element.isCompilationUnit) { |
| 178 element = element.enclosingElement; | 178 element = element.enclosingElement; |
| 179 } | 179 } |
| 180 return element; | 180 return element; |
| 181 } | 181 } |
| 182 | 182 |
| 183 LibraryElement getLibrary() => enclosingElement.getLibrary(); | 183 LibraryElement get library => enclosingElement.library; |
| 184 | 184 |
| 185 LibraryElement getImplementationLibrary() { | 185 LibraryElement get implementationLibrary { |
| 186 Element element = this; | 186 Element element = this; |
| 187 while (!identical(element.kind, ElementKind.LIBRARY)) { | 187 while (!identical(element.kind, ElementKind.LIBRARY)) { |
| 188 element = element.enclosingElement; | 188 element = element.enclosingElement; |
| 189 } | 189 } |
| 190 return element; | 190 return element; |
| 191 } | 191 } |
| 192 | 192 |
| 193 ClassElement getEnclosingClass() { | 193 ClassElement get enclosingClass { |
| 194 for (Element e = this; e != null; e = e.enclosingElement) { | 194 for (Element e = this; e != null; e = e.enclosingElement) { |
| 195 if (e.isClass()) return e; | 195 if (e.isClass) return e; |
| 196 } | 196 } |
| 197 return null; | 197 return null; |
| 198 } | 198 } |
| 199 | 199 |
| 200 Element getEnclosingClassOrCompilationUnit() { | 200 Element get enclosingClassOrCompilationUnit { |
| 201 for (Element e = this; e != null; e = e.enclosingElement) { | 201 for (Element e = this; e != null; e = e.enclosingElement) { |
| 202 if (e.isClass() || e.isCompilationUnit()) return e; | 202 if (e.isClass || e.isCompilationUnit) return e; |
| 203 } | 203 } |
| 204 return null; | 204 return null; |
| 205 } | 205 } |
| 206 | 206 |
| 207 /** | 207 /** |
| 208 * Returns the member enclosing this element or the element itself if it is a | 208 * Returns the member enclosing this element or the element itself if it is a |
| 209 * member. If no enclosing element is found, [:null:] is returned. | 209 * member. If no enclosing element is found, [:null:] is returned. |
| 210 */ | 210 */ |
| 211 Element getEnclosingMember() { | 211 Element get enclosingMember { |
| 212 for (Element e = this; e != null; e = e.enclosingElement) { | 212 for (Element e = this; e != null; e = e.enclosingElement) { |
| 213 if (e.isMember()) return e; | 213 if (e.isMember) return e; |
| 214 } | 214 } |
| 215 return null; | 215 return null; |
| 216 } | 216 } |
| 217 | 217 |
| 218 Element getOutermostEnclosingMemberOrTopLevel() { | 218 Element get outermostEnclosingMemberOrTopLevel { |
| 219 // TODO(lrn): Why is this called "Outermost"? | 219 // TODO(lrn): Why is this called "Outermost"? |
| 220 for (Element e = this; e != null; e = e.enclosingElement) { | 220 for (Element e = this; e != null; e = e.enclosingElement) { |
| 221 if (e.isMember() || e.isTopLevel()) { | 221 if (e.isMember || e.isTopLevel) { |
| 222 return e; | 222 return e; |
| 223 } | 223 } |
| 224 } | 224 } |
| 225 return null; | 225 return null; |
| 226 } | 226 } |
| 227 | 227 |
| 228 /** | 228 /** |
| 229 * Creates the scope for this element. | 229 * Creates the scope for this element. |
| 230 */ | 230 */ |
| 231 Scope buildScope() => enclosingElement.buildScope(); | 231 Scope buildScope() => enclosingElement.buildScope(); |
| 232 | 232 |
| 233 String toString() { | 233 String toString() { |
| 234 // TODO(johnniwinther): Test for nullness of name, or make non-nullness an | 234 // TODO(johnniwinther): Test for nullness of name, or make non-nullness an |
| 235 // invariant for all element types? | 235 // invariant for all element types? |
| 236 var nameText = name != null ? name : '?'; | 236 var nameText = name != null ? name : '?'; |
| 237 if (enclosingElement != null && !isTopLevel()) { | 237 if (enclosingElement != null && !isTopLevel) { |
| 238 String holderName = enclosingElement.name != null | 238 String holderName = enclosingElement.name != null |
| 239 ? enclosingElement.name | 239 ? enclosingElement.name |
| 240 : '${enclosingElement.kind}?'; | 240 : '${enclosingElement.kind}?'; |
| 241 return '$kind($holderName#${nameText})'; | 241 return '$kind($holderName#${nameText})'; |
| 242 } else { | 242 } else { |
| 243 return '$kind(${nameText})'; | 243 return '$kind(${nameText})'; |
| 244 } | 244 } |
| 245 } | 245 } |
| 246 | 246 |
| 247 String _fixedBackendName = null; | 247 String _fixedBackendName = null; |
| 248 bool _isNative = false; | 248 bool _isNative = false; |
| 249 bool isNative() => _isNative; | 249 bool get isNative => _isNative; |
| 250 bool hasFixedBackendName() => _fixedBackendName != null; | 250 bool get hasFixedBackendName => _fixedBackendName != null; |
| 251 String fixedBackendName() => _fixedBackendName; | 251 String get fixedBackendName => _fixedBackendName; |
| 252 // Marks this element as a native element. | 252 // Marks this element as a native element. |
| 253 void setNative(String name) { | 253 void setNative(String name) { |
| 254 _isNative = true; | 254 _isNative = true; |
| 255 _fixedBackendName = name; | 255 _fixedBackendName = name; |
| 256 } | 256 } |
| 257 void setFixedBackendName(String name) { | 257 void setFixedBackendName(String name) { |
| 258 _fixedBackendName = name; | 258 _fixedBackendName = name; |
| 259 } | 259 } |
| 260 | 260 |
| 261 FunctionElement asFunctionElement() => null; | 261 FunctionElement asFunctionElement() => null; |
| 262 | 262 |
| 263 bool get isAbstract => modifiers.isAbstract(); | 263 bool get isAbstract => modifiers.isAbstract; |
| 264 bool isForeign(Compiler compiler) => getLibrary() == compiler.foreignLibrary; | 264 bool isForeign(Compiler compiler) => library == compiler.foreignLibrary; |
| 265 | 265 |
| 266 FunctionElement get targetConstructor => null; | 266 FunctionElement get targetConstructor => null; |
| 267 | 267 |
| 268 void diagnose(Element context, DiagnosticListener listener) {} | 268 void diagnose(Element context, DiagnosticListener listener) {} |
| 269 | 269 |
| 270 TreeElements get treeElements => enclosingElement.treeElements; | 270 TreeElements get treeElements => enclosingElement.treeElements; |
| 271 } | 271 } |
| 272 | 272 |
| 273 /** | 273 /** |
| 274 * Represents an unresolvable or duplicated element. | 274 * Represents an unresolvable or duplicated element. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 288 * [: element == null :]. | 288 * [: element == null :]. |
| 289 */ | 289 */ |
| 290 class ErroneousElementX extends ElementX implements ErroneousElement { | 290 class ErroneousElementX extends ElementX implements ErroneousElement { |
| 291 final MessageKind messageKind; | 291 final MessageKind messageKind; |
| 292 final Map messageArguments; | 292 final Map messageArguments; |
| 293 | 293 |
| 294 ErroneousElementX(this.messageKind, this.messageArguments, | 294 ErroneousElementX(this.messageKind, this.messageArguments, |
| 295 String name, Element enclosing) | 295 String name, Element enclosing) |
| 296 : super(name, ElementKind.ERROR, enclosing); | 296 : super(name, ElementKind.ERROR, enclosing); |
| 297 | 297 |
| 298 isErroneous() => true; | 298 bool get isErroneous => true; |
| 299 | 299 |
| 300 AbstractFieldElement abstractField; | 300 AbstractFieldElement abstractField; |
| 301 | 301 |
| 302 unsupported() { | 302 unsupported() { |
| 303 throw 'unsupported operation on erroneous element'; | 303 throw 'unsupported operation on erroneous element'; |
| 304 } | 304 } |
| 305 | 305 |
| 306 Link<MetadataAnnotation> get metadata => unsupported(); | 306 Link<MetadataAnnotation> get metadata => unsupported(); |
| 307 get node => unsupported(); | 307 get node => unsupported(); |
| 308 get type => unsupported(); | 308 get type => unsupported(); |
| 309 get cachedNode => unsupported(); | 309 get cachedNode => unsupported(); |
| 310 get functionSignature => unsupported(); | 310 get functionSignature => unsupported(); |
| 311 get patch => null; | 311 get patch => null; |
| 312 get origin => this; | 312 get origin => this; |
| 313 get defaultImplementation => unsupported(); | 313 get defaultImplementation => unsupported(); |
| 314 get nestedClosures => unsupported(); | 314 get nestedClosures => unsupported(); |
| 315 | 315 |
| 316 bool get isRedirectingFactory => unsupported(); | 316 bool get isRedirectingFactory => unsupported(); |
| 317 | 317 |
| 318 computeSignature(compiler) => unsupported(); | 318 computeSignature(compiler) => unsupported(); |
| 319 | 319 |
| 320 // TODO(kasperl): These seem unnecessary. | 320 // TODO(kasperl): These seem unnecessary. |
| 321 set defaultImplementation(value) => unsupported(); | 321 set defaultImplementation(value) => unsupported(); |
| 322 | 322 |
| 323 get redirectionTarget => this; | 323 get redirectionTarget => this; |
| 324 | 324 |
| 325 getLibrary() => enclosingElement.getLibrary(); | |
| 326 | |
| 327 computeTargetType(InterfaceType newType) => unsupported(); | 325 computeTargetType(InterfaceType newType) => unsupported(); |
| 328 | 326 |
| 329 String get message => '${messageKind.message(messageArguments)}'; | 327 String get message => '${messageKind.message(messageArguments)}'; |
| 330 | 328 |
| 331 String toString() => '<$name: $message>'; | 329 String toString() => '<$name: $message>'; |
| 332 | 330 |
| 333 accept(ElementVisitor visitor) => visitor.visitErroneousElement(this); | 331 accept(ElementVisitor visitor) => visitor.visitErroneousElement(this); |
| 334 } | 332 } |
| 335 | 333 |
| 336 /// A message attached to a [WarnOnUseElementX]. | 334 /// A message attached to a [WarnOnUseElementX]. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 363 final WrappedMessage info; | 361 final WrappedMessage info; |
| 364 | 362 |
| 365 /// The element whose usage cause a warning. | 363 /// The element whose usage cause a warning. |
| 366 final Element wrappedElement; | 364 final Element wrappedElement; |
| 367 | 365 |
| 368 WarnOnUseElementX(WrappedMessage this.warning, WrappedMessage this.info, | 366 WarnOnUseElementX(WrappedMessage this.warning, WrappedMessage this.info, |
| 369 Element enclosingElement, Element wrappedElement) | 367 Element enclosingElement, Element wrappedElement) |
| 370 : this.wrappedElement = wrappedElement, | 368 : this.wrappedElement = wrappedElement, |
| 371 super(wrappedElement.name, ElementKind.WARN_ON_USE, enclosingElement); | 369 super(wrappedElement.name, ElementKind.WARN_ON_USE, enclosingElement); |
| 372 | 370 |
| 373 bool isWarnOnUse() => true; | 371 bool get isWarnOnUse => true; |
| 374 | 372 |
| 375 Element unwrap(DiagnosticListener listener, Spannable usageSpannable) { | 373 Element unwrap(DiagnosticListener listener, Spannable usageSpannable) { |
| 376 var unwrapped = wrappedElement; | 374 var unwrapped = wrappedElement; |
| 377 if (warning != null) { | 375 if (warning != null) { |
| 378 Spannable spannable = warning.spannable; | 376 Spannable spannable = warning.spannable; |
| 379 if (spannable == null) spannable = usageSpannable; | 377 if (spannable == null) spannable = usageSpannable; |
| 380 listener.reportWarning( | 378 listener.reportWarning( |
| 381 spannable, warning.messageKind, warning.messageArguments); | 379 spannable, warning.messageKind, warning.messageArguments); |
| 382 } | 380 } |
| 383 if (info != null) { | 381 if (info != null) { |
| 384 Spannable spannable = info.spannable; | 382 Spannable spannable = info.spannable; |
| 385 if (spannable == null) spannable = usageSpannable; | 383 if (spannable == null) spannable = usageSpannable; |
| 386 listener.reportInfo( | 384 listener.reportInfo( |
| 387 spannable, info.messageKind, info.messageArguments); | 385 spannable, info.messageKind, info.messageArguments); |
| 388 } | 386 } |
| 389 if (unwrapped.isWarnOnUse()) { | 387 if (unwrapped.isWarnOnUse) { |
| 390 unwrapped = unwrapped.unwrap(listener, usageSpannable); | 388 unwrapped = unwrapped.unwrap(listener, usageSpannable); |
| 391 } | 389 } |
| 392 return unwrapped; | 390 return unwrapped; |
| 393 } | 391 } |
| 394 | 392 |
| 395 accept(ElementVisitor visitor) => visitor.visitWarnOnUseElement(this); | 393 accept(ElementVisitor visitor) => visitor.visitWarnOnUseElement(this); |
| 396 } | 394 } |
| 397 | 395 |
| 398 /** | 396 /** |
| 399 * An ambiguous element represents multiple elements accessible by the same name
. | 397 * An ambiguous element represents multiple elements accessible by the same name
. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 422 * The second element that this ambiguous element might refer to. | 420 * The second element that this ambiguous element might refer to. |
| 423 */ | 421 */ |
| 424 final Element newElement; | 422 final Element newElement; |
| 425 | 423 |
| 426 AmbiguousElementX(this.messageKind, this.messageArguments, | 424 AmbiguousElementX(this.messageKind, this.messageArguments, |
| 427 Element enclosingElement, Element existingElement, Element newElement) | 425 Element enclosingElement, Element existingElement, Element newElement) |
| 428 : this.existingElement = existingElement, | 426 : this.existingElement = existingElement, |
| 429 this.newElement = newElement, | 427 this.newElement = newElement, |
| 430 super(existingElement.name, ElementKind.AMBIGUOUS, enclosingElement); | 428 super(existingElement.name, ElementKind.AMBIGUOUS, enclosingElement); |
| 431 | 429 |
| 432 bool isAmbiguous() => true; | 430 bool get isAmbiguous => true; |
| 433 | 431 |
| 434 Setlet flatten() { | 432 Setlet flatten() { |
| 435 Element element = this; | 433 Element element = this; |
| 436 var set = new Setlet(); | 434 var set = new Setlet(); |
| 437 while (element.isAmbiguous()) { | 435 while (element.isAmbiguous) { |
| 438 AmbiguousElement ambiguous = element; | 436 AmbiguousElement ambiguous = element; |
| 439 set.add(ambiguous.newElement); | 437 set.add(ambiguous.newElement); |
| 440 element = ambiguous.existingElement; | 438 element = ambiguous.existingElement; |
| 441 } | 439 } |
| 442 set.add(element); | 440 set.add(element); |
| 443 return set; | 441 return set; |
| 444 } | 442 } |
| 445 | 443 |
| 446 void diagnose(Element context, DiagnosticListener listener) { | 444 void diagnose(Element context, DiagnosticListener listener) { |
| 447 Setlet ambiguousElements = flatten(); | 445 Setlet ambiguousElements = flatten(); |
| 448 MessageKind code = (ambiguousElements.length == 1) | 446 MessageKind code = (ambiguousElements.length == 1) |
| 449 ? MessageKind.AMBIGUOUS_REEXPORT : MessageKind.AMBIGUOUS_LOCATION; | 447 ? MessageKind.AMBIGUOUS_REEXPORT : MessageKind.AMBIGUOUS_LOCATION; |
| 450 LibraryElementX importer = context.getLibrary(); | 448 LibraryElementX importer = context.library; |
| 451 for (Element element in ambiguousElements) { | 449 for (Element element in ambiguousElements) { |
| 452 var arguments = {'name': element.name}; | 450 var arguments = {'name': element.name}; |
| 453 listener.reportInfo(element, code, arguments); | 451 listener.reportInfo(element, code, arguments); |
| 454 Link<Import> importers = importer.importers.getImports(element); | 452 Link<Import> importers = importer.importers.getImports(element); |
| 455 listener.withCurrentElement(importer, () { | 453 listener.withCurrentElement(importer, () { |
| 456 for (; !importers.isEmpty; importers = importers.tail) { | 454 for (; !importers.isEmpty; importers = importers.tail) { |
| 457 listener.reportInfo( | 455 listener.reportInfo( |
| 458 importers.head, MessageKind.IMPORTED_HERE, arguments); | 456 importers.head, MessageKind.IMPORTED_HERE, arguments); |
| 459 } | 457 } |
| 460 }); | 458 }); |
| 461 } | 459 } |
| 462 } | 460 } |
| 463 | 461 |
| 464 accept(ElementVisitor visitor) => visitor.visitAmbiguousElement(this); | 462 accept(ElementVisitor visitor) => visitor.visitAmbiguousElement(this); |
| 465 } | 463 } |
| 466 | 464 |
| 467 class ScopeX { | 465 class ScopeX { |
| 468 final Map<String, Element> contents = new Map<String, Element>(); | 466 final Map<String, Element> contents = new Map<String, Element>(); |
| 469 | 467 |
| 470 bool get isEmpty => contents.isEmpty; | 468 bool get isEmpty => contents.isEmpty; |
| 471 Iterable<Element> get values => contents.values; | 469 Iterable<Element> get values => contents.values; |
| 472 | 470 |
| 473 Element lookup(String name) { | 471 Element lookup(String name) { |
| 474 return contents[name]; | 472 return contents[name]; |
| 475 } | 473 } |
| 476 | 474 |
| 477 void add(Element element, DiagnosticListener listener) { | 475 void add(Element element, DiagnosticListener listener) { |
| 478 String name = element.name; | 476 String name = element.name; |
| 479 if (element.isAccessor()) { | 477 if (element.isAccessor) { |
| 480 addAccessor(element, contents[name], listener); | 478 addAccessor(element, contents[name], listener); |
| 481 } else { | 479 } else { |
| 482 Element existing = contents.putIfAbsent(name, () => element); | 480 Element existing = contents.putIfAbsent(name, () => element); |
| 483 if (!identical(existing, element)) { | 481 if (!identical(existing, element)) { |
| 484 listener.reportError( | 482 listener.reportError( |
| 485 element, MessageKind.DUPLICATE_DEFINITION, {'name': name}); | 483 element, MessageKind.DUPLICATE_DEFINITION, {'name': name}); |
| 486 listener.reportInfo(existing, | 484 listener.reportInfo(existing, |
| 487 MessageKind.EXISTING_DEFINITION, {'name': name}); | 485 MessageKind.EXISTING_DEFINITION, {'name': name}); |
| 488 } | 486 } |
| 489 } | 487 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 514 MessageKind.EXISTING_DEFINITION, | 512 MessageKind.EXISTING_DEFINITION, |
| 515 {'name': accessor.name}); | 513 {'name': accessor.name}); |
| 516 } | 514 } |
| 517 | 515 |
| 518 if (existing != null) { | 516 if (existing != null) { |
| 519 if (!identical(existing.kind, ElementKind.ABSTRACT_FIELD)) { | 517 if (!identical(existing.kind, ElementKind.ABSTRACT_FIELD)) { |
| 520 reportError(existing); | 518 reportError(existing); |
| 521 } else { | 519 } else { |
| 522 AbstractFieldElementX field = existing; | 520 AbstractFieldElementX field = existing; |
| 523 accessor.abstractField = field; | 521 accessor.abstractField = field; |
| 524 if (accessor.isGetter()) { | 522 if (accessor.isGetter) { |
| 525 if (field.getter != null && field.getter != accessor) { | 523 if (field.getter != null && field.getter != accessor) { |
| 526 reportError(field.getter); | 524 reportError(field.getter); |
| 527 } | 525 } |
| 528 field.getter = accessor; | 526 field.getter = accessor; |
| 529 } else { | 527 } else { |
| 530 assert(accessor.isSetter()); | 528 assert(accessor.isSetter); |
| 531 if (field.setter != null && field.setter != accessor) { | 529 if (field.setter != null && field.setter != accessor) { |
| 532 reportError(field.setter); | 530 reportError(field.setter); |
| 533 } | 531 } |
| 534 field.setter = accessor; | 532 field.setter = accessor; |
| 535 } | 533 } |
| 536 } | 534 } |
| 537 } else { | 535 } else { |
| 538 Element container = accessor.getEnclosingClassOrCompilationUnit(); | 536 Element container = accessor.enclosingClassOrCompilationUnit; |
| 539 AbstractFieldElementX field = | 537 AbstractFieldElementX field = |
| 540 new AbstractFieldElementX(accessor.name, container); | 538 new AbstractFieldElementX(accessor.name, container); |
| 541 accessor.abstractField = field; | 539 accessor.abstractField = field; |
| 542 if (accessor.isGetter()) { | 540 if (accessor.isGetter) { |
| 543 field.getter = accessor; | 541 field.getter = accessor; |
| 544 } else { | 542 } else { |
| 545 field.setter = accessor; | 543 field.setter = accessor; |
| 546 } | 544 } |
| 547 add(field, listener); | 545 add(field, listener); |
| 548 } | 546 } |
| 549 } | 547 } |
| 550 } | 548 } |
| 551 | 549 |
| 552 class CompilationUnitElementX extends ElementX with AnalyzableElement | 550 class CompilationUnitElementX extends ElementX with AnalyzableElement |
| (...skipping 12 matching lines...) Expand all Loading... |
| 565 | 563 |
| 566 void forEachLocalMember(f(Element element)) { | 564 void forEachLocalMember(f(Element element)) { |
| 567 localMembers.forEach(f); | 565 localMembers.forEach(f); |
| 568 } | 566 } |
| 569 | 567 |
| 570 void addMember(Element element, DiagnosticListener listener) { | 568 void addMember(Element element, DiagnosticListener listener) { |
| 571 // Keep a list of top level members. | 569 // Keep a list of top level members. |
| 572 localMembers = localMembers.prepend(element); | 570 localMembers = localMembers.prepend(element); |
| 573 // Provide the member to the library to build scope. | 571 // Provide the member to the library to build scope. |
| 574 if (enclosingElement.isPatch) { | 572 if (enclosingElement.isPatch) { |
| 575 getImplementationLibrary().addMember(element, listener); | 573 implementationLibrary.addMember(element, listener); |
| 576 } else { | 574 } else { |
| 577 getLibrary().addMember(element, listener); | 575 library.addMember(element, listener); |
| 578 } | 576 } |
| 579 } | 577 } |
| 580 | 578 |
| 581 void setPartOf(PartOf tag, DiagnosticListener listener) { | 579 void setPartOf(PartOf tag, DiagnosticListener listener) { |
| 582 LibraryElementX library = enclosingElement; | 580 LibraryElementX library = enclosingElement; |
| 583 if (library.entryCompilationUnit == this) { | 581 if (library.entryCompilationUnit == this) { |
| 584 listener.reportError(tag, MessageKind.ILLEGAL_DIRECTIVE); | 582 listener.reportError(tag, MessageKind.ILLEGAL_DIRECTIVE); |
| 585 return; | 583 return; |
| 586 } | 584 } |
| 587 if (!localMembers.isEmpty) { | 585 if (!localMembers.isEmpty) { |
| 588 listener.reportError(tag, MessageKind.BEFORE_TOP_LEVEL); | 586 listener.reportError(tag, MessageKind.BEFORE_TOP_LEVEL); |
| 589 return; | 587 return; |
| 590 } | 588 } |
| 591 if (partTag != null) { | 589 if (partTag != null) { |
| 592 listener.reportWarning(tag, MessageKind.DUPLICATED_PART_OF); | 590 listener.reportWarning(tag, MessageKind.DUPLICATED_PART_OF); |
| 593 return; | 591 return; |
| 594 } | 592 } |
| 595 partTag = tag; | 593 partTag = tag; |
| 596 LibraryName libraryTag = getLibrary().libraryTag; | 594 LibraryName libraryTag = library.libraryTag; |
| 597 String actualName = tag.name.toString(); | 595 String actualName = tag.name.toString(); |
| 598 if (libraryTag != null) { | 596 if (libraryTag != null) { |
| 599 String expectedName = libraryTag.name.toString(); | 597 String expectedName = libraryTag.name.toString(); |
| 600 if (expectedName != actualName) { | 598 if (expectedName != actualName) { |
| 601 listener.reportWarning(tag.name, | 599 listener.reportWarning(tag.name, |
| 602 MessageKind.LIBRARY_NAME_MISMATCH, | 600 MessageKind.LIBRARY_NAME_MISMATCH, |
| 603 {'libraryName': expectedName}); | 601 {'libraryName': expectedName}); |
| 604 } | 602 } |
| 605 } else { | 603 } else { |
| 606 listener.reportWarning(getLibrary(), | 604 listener.reportWarning(library, |
| 607 MessageKind.MISSING_LIBRARY_NAME, | 605 MessageKind.MISSING_LIBRARY_NAME, |
| 608 {'libraryName': actualName}); | 606 {'libraryName': actualName}); |
| 609 listener.reportInfo(tag.name, | 607 listener.reportInfo(tag.name, |
| 610 MessageKind.THIS_IS_THE_PART_OF_TAG); | 608 MessageKind.THIS_IS_THE_PART_OF_TAG); |
| 611 } | 609 } |
| 612 } | 610 } |
| 613 | 611 |
| 614 bool get hasMembers => !localMembers.isEmpty; | 612 bool get hasMembers => !localMembers.isEmpty; |
| 615 | 613 |
| 616 int compareTo(CompilationUnitElement other) { | 614 int compareTo(CompilationUnitElement other) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 * Adds [element] to the import scope of this library. | 652 * Adds [element] to the import scope of this library. |
| 655 * | 653 * |
| 656 * If an element by the same name is already in the imported scope, an | 654 * If an element by the same name is already in the imported scope, an |
| 657 * [ErroneousElement] will be put in the imported scope, allowing for | 655 * [ErroneousElement] will be put in the imported scope, allowing for |
| 658 * detection of ambiguous uses of imported names. | 656 * detection of ambiguous uses of imported names. |
| 659 */ | 657 */ |
| 660 void addImport(Element enclosingElement, | 658 void addImport(Element enclosingElement, |
| 661 Element element, | 659 Element element, |
| 662 Import import, | 660 Import import, |
| 663 DiagnosticListener listener) { | 661 DiagnosticListener listener) { |
| 664 LibraryElementX library = enclosingElement.getLibrary(); | 662 LibraryElementX library = enclosingElement.library; |
| 665 Importers importers = library.importers; | 663 Importers importers = library.importers; |
| 666 | 664 |
| 667 String name = element.name; | 665 String name = element.name; |
| 668 | 666 |
| 669 // The loadLibrary function always shadows existing bindings to that name. | 667 // The loadLibrary function always shadows existing bindings to that name. |
| 670 if (element.isDeferredLoaderGetter()) { | 668 if (element.isDeferredLoaderGetter) { |
| 671 importScope.remove(name); | 669 importScope.remove(name); |
| 672 // TODO(sigurdm): Print a hint. | 670 // TODO(sigurdm): Print a hint. |
| 673 } | 671 } |
| 674 Element existing = importScope.putIfAbsent(name, () => element); | 672 Element existing = importScope.putIfAbsent(name, () => element); |
| 675 importers.registerImport(element, import); | 673 importers.registerImport(element, import); |
| 676 | 674 |
| 677 void registerWarnOnUseElement(Import import, | 675 void registerWarnOnUseElement(Import import, |
| 678 MessageKind messageKind, | 676 MessageKind messageKind, |
| 679 Element hidingElement, | 677 Element hidingElement, |
| 680 Element hiddenElement) { | 678 Element hiddenElement) { |
| 681 Uri hiddenUri = hiddenElement.getLibrary().canonicalUri; | 679 Uri hiddenUri = hiddenElement.library.canonicalUri; |
| 682 Uri hidingUri = hidingElement.getLibrary().canonicalUri; | 680 Uri hidingUri = hidingElement.library.canonicalUri; |
| 683 Element element = new WarnOnUseElementX( | 681 Element element = new WarnOnUseElementX( |
| 684 new WrappedMessage( | 682 new WrappedMessage( |
| 685 null, // Report on reference to [hidingElement]. | 683 null, // Report on reference to [hidingElement]. |
| 686 messageKind, | 684 messageKind, |
| 687 {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}), | 685 {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}), |
| 688 new WrappedMessage( | 686 new WrappedMessage( |
| 689 listener.spanFromSpannable(import), | 687 listener.spanFromSpannable(import), |
| 690 MessageKind.IMPORTED_HERE, | 688 MessageKind.IMPORTED_HERE, |
| 691 {'name': name}), | 689 {'name': name}), |
| 692 enclosingElement, hidingElement); | 690 enclosingElement, hidingElement); |
| 693 importScope[name] = element; | 691 importScope[name] = element; |
| 694 importers.registerImport(element, import); | 692 importers.registerImport(element, import); |
| 695 } | 693 } |
| 696 | 694 |
| 697 if (existing != element) { | 695 if (existing != element) { |
| 698 Import existingImport = importers.getImport(existing); | 696 Import existingImport = importers.getImport(existing); |
| 699 Element newElement; | 697 Element newElement; |
| 700 if (existing.getLibrary().isPlatformLibrary && | 698 if (existing.library.isPlatformLibrary && |
| 701 !element.getLibrary().isPlatformLibrary) { | 699 !element.library.isPlatformLibrary) { |
| 702 // [existing] is implicitly hidden. | 700 // [existing] is implicitly hidden. |
| 703 registerWarnOnUseElement( | 701 registerWarnOnUseElement( |
| 704 import, MessageKind.HIDDEN_IMPORT, element, existing); | 702 import, MessageKind.HIDDEN_IMPORT, element, existing); |
| 705 } else if (!existing.getLibrary().isPlatformLibrary && | 703 } else if (!existing.library.isPlatformLibrary && |
| 706 element.getLibrary().isPlatformLibrary) { | 704 element.library.isPlatformLibrary) { |
| 707 // [element] is implicitly hidden. | 705 // [element] is implicitly hidden. |
| 708 if (import == null) { | 706 if (import == null) { |
| 709 // [element] is imported implicitly (probably through dart:core). | 707 // [element] is imported implicitly (probably through dart:core). |
| 710 registerWarnOnUseElement( | 708 registerWarnOnUseElement( |
| 711 existingImport, MessageKind.HIDDEN_IMPLICIT_IMPORT, | 709 existingImport, MessageKind.HIDDEN_IMPLICIT_IMPORT, |
| 712 existing, element); | 710 existing, element); |
| 713 } else { | 711 } else { |
| 714 registerWarnOnUseElement( | 712 registerWarnOnUseElement( |
| 715 import, MessageKind.HIDDEN_IMPORT, existing, element); | 713 import, MessageKind.HIDDEN_IMPORT, existing, element); |
| 716 } | 714 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 | 769 |
| 772 Link<MetadataAnnotation> get metadata { | 770 Link<MetadataAnnotation> get metadata { |
| 773 return (libraryTag == null) ? super.metadata : libraryTag.metadata; | 771 return (libraryTag == null) ? super.metadata : libraryTag.metadata; |
| 774 } | 772 } |
| 775 | 773 |
| 776 set metadata(value) { | 774 set metadata(value) { |
| 777 // The metadata is stored on [libraryTag]. | 775 // The metadata is stored on [libraryTag]. |
| 778 throw new SpannableAssertionFailure(this, 'Cannot set metadata on Library'); | 776 throw new SpannableAssertionFailure(this, 'Cannot set metadata on Library'); |
| 779 } | 777 } |
| 780 | 778 |
| 781 CompilationUnitElement getCompilationUnit() => entryCompilationUnit; | 779 CompilationUnitElement get compilationUnit => entryCompilationUnit; |
| 782 | 780 |
| 783 void addCompilationUnit(CompilationUnitElement element) { | 781 void addCompilationUnit(CompilationUnitElement element) { |
| 784 compilationUnits = compilationUnits.prepend(element); | 782 compilationUnits = compilationUnits.prepend(element); |
| 785 } | 783 } |
| 786 | 784 |
| 787 void addTag(LibraryTag tag, DiagnosticListener listener) { | 785 void addTag(LibraryTag tag, DiagnosticListener listener) { |
| 788 tags = tags.prepend(tag); | 786 tags = tags.prepend(tag); |
| 789 } | 787 } |
| 790 | 788 |
| 791 void recordResolvedTag(LibraryDependency tag, LibraryElement library) { | 789 void recordResolvedTag(LibraryDependency tag, LibraryElement library) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 842 assert(invariant(this, !exportsHandled, | 840 assert(invariant(this, !exportsHandled, |
| 843 message: 'Exports already set to $slotForExports on $this')); | 841 message: 'Exports already set to $slotForExports on $this')); |
| 844 assert(invariant(this, exportedElements != null)); | 842 assert(invariant(this, exportedElements != null)); |
| 845 var builder = new LinkBuilder<Element>(); | 843 var builder = new LinkBuilder<Element>(); |
| 846 for (Element export in exportedElements) { | 844 for (Element export in exportedElements) { |
| 847 builder.addLast(export); | 845 builder.addLast(export); |
| 848 } | 846 } |
| 849 slotForExports = builder.toLink(); | 847 slotForExports = builder.toLink(); |
| 850 } | 848 } |
| 851 | 849 |
| 852 LibraryElement getLibrary() => isPatch ? origin : this; | 850 LibraryElement get library => isPatch ? origin : this; |
| 853 | 851 |
| 854 /** | 852 /** |
| 855 * Look up a top-level element in this library. The element could | 853 * Look up a top-level element in this library. The element could |
| 856 * potentially have been imported from another library. Returns | 854 * potentially have been imported from another library. Returns |
| 857 * null if no such element exist and an [ErroneousElement] if multiple | 855 * null if no such element exist and an [ErroneousElement] if multiple |
| 858 * elements have been imported. | 856 * elements have been imported. |
| 859 */ | 857 */ |
| 860 Element find(String elementName) { | 858 Element find(String elementName) { |
| 861 Element result = localScope.lookup(elementName); | 859 Element result = localScope.lookup(elementName); |
| 862 if (result != null) return result; | 860 if (result != null) return result; |
| 863 if (origin != null) { | 861 if (origin != null) { |
| 864 result = origin.localScope.lookup(elementName); | 862 result = origin.localScope.lookup(elementName); |
| 865 if (result != null) return result; | 863 if (result != null) return result; |
| 866 } | 864 } |
| 867 result = importScope[elementName]; | 865 result = importScope[elementName]; |
| 868 if (result != null) return result; | 866 if (result != null) return result; |
| 869 if (origin != null) { | 867 if (origin != null) { |
| 870 result = origin.importScope[elementName]; | 868 result = origin.importScope[elementName]; |
| 871 if (result != null) return result; | 869 if (result != null) return result; |
| 872 } | 870 } |
| 873 return null; | 871 return null; |
| 874 } | 872 } |
| 875 | 873 |
| 876 /** Look up a top-level element in this library, but only look for | 874 /** Look up a top-level element in this library, but only look for |
| 877 * non-imported elements. Returns null if no such element exist. */ | 875 * non-imported elements. Returns null if no such element exist. */ |
| 878 Element findLocal(String elementName) { | 876 Element findLocal(String elementName) { |
| 879 // TODO(johnniwinther): How to handle injected elements in the patch | 877 // TODO(johnniwinther): How to handle injected elements in the patch |
| 880 // library? | 878 // library? |
| 881 Element result = localScope.lookup(elementName); | 879 Element result = localScope.lookup(elementName); |
| 882 if (result == null || result.getLibrary() != this) return null; | 880 if (result == null || result.library != this) return null; |
| 883 return result; | 881 return result; |
| 884 } | 882 } |
| 885 | 883 |
| 886 Element findExported(String elementName) { | 884 Element findExported(String elementName) { |
| 887 for (Link link = exports; !link.isEmpty; link = link.tail) { | 885 for (Link link = exports; !link.isEmpty; link = link.tail) { |
| 888 Element element = link.head; | 886 Element element = link.head; |
| 889 if (element.name == elementName) return element; | 887 if (element.name == elementName) return element; |
| 890 } | 888 } |
| 891 return null; | 889 return null; |
| 892 } | 890 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 993 Import _deferredImport; | 991 Import _deferredImport; |
| 994 Import get deferredImport => _deferredImport; | 992 Import get deferredImport => _deferredImport; |
| 995 | 993 |
| 996 PrefixElementX(String prefix, Element enclosing, this.firstPosition) | 994 PrefixElementX(String prefix, Element enclosing, this.firstPosition) |
| 997 : super(prefix, ElementKind.PREFIX, enclosing); | 995 : super(prefix, ElementKind.PREFIX, enclosing); |
| 998 | 996 |
| 999 Element lookupLocalMember(String memberName) => importScope[memberName]; | 997 Element lookupLocalMember(String memberName) => importScope[memberName]; |
| 1000 | 998 |
| 1001 DartType computeType(Compiler compiler) => compiler.types.dynamicType; | 999 DartType computeType(Compiler compiler) => compiler.types.dynamicType; |
| 1002 | 1000 |
| 1003 Token position() => firstPosition; | 1001 Token get position => firstPosition; |
| 1004 | 1002 |
| 1005 void addImport(Element element, Import import, DiagnosticListener listener) { | 1003 void addImport(Element element, Import import, DiagnosticListener listener) { |
| 1006 importScope.addImport(this, element, import, listener); | 1004 importScope.addImport(this, element, import, listener); |
| 1007 } | 1005 } |
| 1008 | 1006 |
| 1009 accept(ElementVisitor visitor) => visitor.visitPrefixElement(this); | 1007 accept(ElementVisitor visitor) => visitor.visitPrefixElement(this); |
| 1010 | 1008 |
| 1011 void markAsDeferred(Import deferredImport) { | 1009 void markAsDeferred(Import deferredImport) { |
| 1012 _deferredImport = deferredImport; | 1010 _deferredImport = deferredImport; |
| 1013 } | 1011 } |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1177 }); | 1175 }); |
| 1178 return variables.computeType(this, compiler); | 1176 return variables.computeType(this, compiler); |
| 1179 } | 1177 } |
| 1180 | 1178 |
| 1181 DartType get type { | 1179 DartType get type { |
| 1182 assert(invariant(this, variables.type != null, | 1180 assert(invariant(this, variables.type != null, |
| 1183 message: "Type has not been computed for $this.")); | 1181 message: "Type has not been computed for $this.")); |
| 1184 return variables.type; | 1182 return variables.type; |
| 1185 } | 1183 } |
| 1186 | 1184 |
| 1187 bool isInstanceMember() => isMember() && !modifiers.isStatic(); | 1185 bool get isInstanceMember => isMember && !modifiers.isStatic; |
| 1188 | 1186 |
| 1189 // Note: cachedNode.getBeginToken() will not be correct in all | 1187 // Note: cachedNode.beginToken will not be correct in all |
| 1190 // cases, for example, for function typed parameters. | 1188 // cases, for example, for function typed parameters. |
| 1191 Token position() => token; | 1189 Token get position => token; |
| 1192 | 1190 |
| 1193 accept(ElementVisitor visitor) => visitor.visitVariableElement(this); | 1191 accept(ElementVisitor visitor) => visitor.visitVariableElement(this); |
| 1194 } | 1192 } |
| 1195 | 1193 |
| 1196 class FieldElementX extends VariableElementX implements FieldElement { | 1194 class FieldElementX extends VariableElementX implements FieldElement { |
| 1197 List<FunctionElement> nestedClosures = new List<FunctionElement>(); | 1195 List<FunctionElement> nestedClosures = new List<FunctionElement>(); |
| 1198 | 1196 |
| 1199 FieldElementX(Identifier name, | 1197 FieldElementX(Identifier name, |
| 1200 Element enclosingElement, | 1198 Element enclosingElement, |
| 1201 VariableList variables) | 1199 VariableList variables) |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 ParameterElementX(ElementKind elementKind, | 1245 ParameterElementX(ElementKind elementKind, |
| 1248 Element enclosingElement, | 1246 Element enclosingElement, |
| 1249 this.definitions, | 1247 this.definitions, |
| 1250 Identifier identifier, | 1248 Identifier identifier, |
| 1251 this.initializer) | 1249 this.initializer) |
| 1252 : this.identifier = identifier, | 1250 : this.identifier = identifier, |
| 1253 super(identifier.source, elementKind, enclosingElement); | 1251 super(identifier.source, elementKind, enclosingElement); |
| 1254 | 1252 |
| 1255 Modifiers get modifiers => definitions.modifiers; | 1253 Modifiers get modifiers => definitions.modifiers; |
| 1256 | 1254 |
| 1257 Token position() => identifier.getBeginToken(); | 1255 Token get position => identifier.getBeginToken(); |
| 1258 | 1256 |
| 1259 Node parseNode(DiagnosticListener listener) => definitions; | 1257 Node parseNode(DiagnosticListener listener) => definitions; |
| 1260 | 1258 |
| 1261 DartType computeType(Compiler compiler) { | 1259 DartType computeType(Compiler compiler) { |
| 1262 assert(invariant(this, type != null, | 1260 assert(invariant(this, type != null, |
| 1263 message: "Parameter type has not been set for $this.")); | 1261 message: "Parameter type has not been set for $this.")); |
| 1264 return type; | 1262 return type; |
| 1265 } | 1263 } |
| 1266 | 1264 |
| 1267 DartType get type { | 1265 DartType get type { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1291 : super(name, ElementKind.ABSTRACT_FIELD, enclosing); | 1289 : super(name, ElementKind.ABSTRACT_FIELD, enclosing); |
| 1292 | 1290 |
| 1293 DartType computeType(Compiler compiler) { | 1291 DartType computeType(Compiler compiler) { |
| 1294 throw "internal error: AbstractFieldElement has no type"; | 1292 throw "internal error: AbstractFieldElement has no type"; |
| 1295 } | 1293 } |
| 1296 | 1294 |
| 1297 Node parseNode(DiagnosticListener listener) { | 1295 Node parseNode(DiagnosticListener listener) { |
| 1298 throw "internal error: AbstractFieldElement has no node"; | 1296 throw "internal error: AbstractFieldElement has no node"; |
| 1299 } | 1297 } |
| 1300 | 1298 |
| 1301 Token position() { | 1299 Token get position { |
| 1302 // The getter and setter may be defined in two different | 1300 // The getter and setter may be defined in two different |
| 1303 // compilation units. However, we know that one of them is | 1301 // compilation units. However, we know that one of them is |
| 1304 // non-null and defined in the same compilation unit as the | 1302 // non-null and defined in the same compilation unit as the |
| 1305 // abstract element. | 1303 // abstract element. |
| 1306 // TODO(lrn): No we don't know that if the element from the same | 1304 // TODO(lrn): No we don't know that if the element from the same |
| 1307 // compilation unit is patched. | 1305 // compilation unit is patched. |
| 1308 // | 1306 // |
| 1309 // We need to make sure that the position returned is relative to | 1307 // We need to make sure that the position returned is relative to |
| 1310 // the compilation unit of the abstract element. | 1308 // the compilation unit of the abstract element. |
| 1311 if (getter != null | 1309 if (getter != null |
| 1312 && identical(getter.getCompilationUnit(), getCompilationUnit())) { | 1310 && identical(getter.compilationUnit, compilationUnit)) { |
| 1313 return getter.position(); | 1311 return getter.position; |
| 1314 } else { | 1312 } else { |
| 1315 return setter.position(); | 1313 return setter.position; |
| 1316 } | 1314 } |
| 1317 } | 1315 } |
| 1318 | 1316 |
| 1319 Modifiers get modifiers { | 1317 Modifiers get modifiers { |
| 1320 // The resolver ensures that the flags match (ignoring abstract). | 1318 // The resolver ensures that the flags match (ignoring abstract). |
| 1321 if (getter != null) { | 1319 if (getter != null) { |
| 1322 return new Modifiers.withFlags( | 1320 return new Modifiers.withFlags( |
| 1323 getter.modifiers.nodes, | 1321 getter.modifiers.nodes, |
| 1324 getter.modifiers.flags | Modifiers.FLAG_ABSTRACT); | 1322 getter.modifiers.flags | Modifiers.FLAG_ABSTRACT); |
| 1325 } else { | 1323 } else { |
| 1326 return new Modifiers.withFlags( | 1324 return new Modifiers.withFlags( |
| 1327 setter.modifiers.nodes, | 1325 setter.modifiers.nodes, |
| 1328 setter.modifiers.flags | Modifiers.FLAG_ABSTRACT); | 1326 setter.modifiers.flags | Modifiers.FLAG_ABSTRACT); |
| 1329 } | 1327 } |
| 1330 } | 1328 } |
| 1331 | 1329 |
| 1332 bool isInstanceMember() { | 1330 bool get isInstanceMember { |
| 1333 return isMember() && !modifiers.isStatic(); | 1331 return isMember && !modifiers.isStatic; |
| 1334 } | 1332 } |
| 1335 | 1333 |
| 1336 accept(ElementVisitor visitor) => visitor.visitAbstractFieldElement(this); | 1334 accept(ElementVisitor visitor) => visitor.visitAbstractFieldElement(this); |
| 1337 | 1335 |
| 1338 bool get isAbstract { | 1336 bool get isAbstract { |
| 1339 return getter != null && getter.isAbstract | 1337 return getter != null && getter.isAbstract |
| 1340 || setter != null && setter.isAbstract; | 1338 || setter != null && setter.isAbstract; |
| 1341 } | 1339 } |
| 1342 } | 1340 } |
| 1343 | 1341 |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1499 } | 1497 } |
| 1500 | 1498 |
| 1501 InterfaceType computeTargetType(InterfaceType newType) { | 1499 InterfaceType computeTargetType(InterfaceType newType) { |
| 1502 if (!isRedirectingFactory) return newType; | 1500 if (!isRedirectingFactory) return newType; |
| 1503 assert(invariant(this, redirectionTargetType != null, | 1501 assert(invariant(this, redirectionTargetType != null, |
| 1504 message: 'Redirection target type has not yet been computed for ' | 1502 message: 'Redirection target type has not yet been computed for ' |
| 1505 '$this.')); | 1503 '$this.')); |
| 1506 return redirectionTargetType.substByContext(newType); | 1504 return redirectionTargetType.substByContext(newType); |
| 1507 } | 1505 } |
| 1508 | 1506 |
| 1509 bool isInstanceMember() { | 1507 bool get isInstanceMember { |
| 1510 return isMember() | 1508 return isMember |
| 1511 && !isConstructor() | 1509 && !isConstructor |
| 1512 && !modifiers.isStatic(); | 1510 && !modifiers.isStatic; |
| 1513 } | 1511 } |
| 1514 | 1512 |
| 1515 FunctionSignature computeSignature(Compiler compiler) { | 1513 FunctionSignature computeSignature(Compiler compiler) { |
| 1516 if (functionSignatureCache != null) return functionSignatureCache; | 1514 if (functionSignatureCache != null) return functionSignatureCache; |
| 1517 compiler.withCurrentElement(this, () { | 1515 compiler.withCurrentElement(this, () { |
| 1518 functionSignatureCache = compiler.resolveSignature(this); | 1516 functionSignatureCache = compiler.resolveSignature(this); |
| 1519 }); | 1517 }); |
| 1520 return functionSignatureCache; | 1518 return functionSignatureCache; |
| 1521 } | 1519 } |
| 1522 | 1520 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1533 } | 1531 } |
| 1534 | 1532 |
| 1535 FunctionType get type { | 1533 FunctionType get type { |
| 1536 assert(invariant(this, typeCache != null, | 1534 assert(invariant(this, typeCache != null, |
| 1537 message: "Type has not been computed for $this.")); | 1535 message: "Type has not been computed for $this.")); |
| 1538 return typeCache; | 1536 return typeCache; |
| 1539 } | 1537 } |
| 1540 | 1538 |
| 1541 FunctionExpression parseNode(DiagnosticListener listener) { | 1539 FunctionExpression parseNode(DiagnosticListener listener) { |
| 1542 if (patch == null) { | 1540 if (patch == null) { |
| 1543 if (modifiers.isExternal()) { | 1541 if (modifiers.isExternal) { |
| 1544 listener.internalError(this, | 1542 listener.internalError(this, |
| 1545 "Compiling external function with no implementation."); | 1543 "Compiling external function with no implementation."); |
| 1546 } | 1544 } |
| 1547 } | 1545 } |
| 1548 return cachedNode; | 1546 return cachedNode; |
| 1549 } | 1547 } |
| 1550 | 1548 |
| 1551 FunctionExpression get node { | 1549 FunctionExpression get node { |
| 1552 assert(invariant(this, cachedNode != null, | 1550 assert(invariant(this, cachedNode != null, |
| 1553 message: "Node has not been computed for $this.")); | 1551 message: "Node has not been computed for $this.")); |
| 1554 return cachedNode; | 1552 return cachedNode; |
| 1555 } | 1553 } |
| 1556 | 1554 |
| 1557 Token position() { | 1555 Token get position { |
| 1558 // Use the name as position if this is not an unnamed closure. | 1556 // Use the name as position if this is not an unnamed closure. |
| 1559 if (cachedNode.name != null) { | 1557 if (cachedNode.name != null) { |
| 1560 return cachedNode.name.getBeginToken(); | 1558 return cachedNode.name.getBeginToken(); |
| 1561 } else { | 1559 } else { |
| 1562 return cachedNode.getBeginToken(); | 1560 return cachedNode.getBeginToken(); |
| 1563 } | 1561 } |
| 1564 } | 1562 } |
| 1565 | 1563 |
| 1566 FunctionElement asFunctionElement() => this; | 1564 FunctionElement asFunctionElement() => this; |
| 1567 | 1565 |
| 1568 String toString() { | 1566 String toString() { |
| 1569 if (isPatch) { | 1567 if (isPatch) { |
| 1570 return 'patch ${super.toString()}'; | 1568 return 'patch ${super.toString()}'; |
| 1571 } else if (isPatched) { | 1569 } else if (isPatched) { |
| 1572 return 'origin ${super.toString()}'; | 1570 return 'origin ${super.toString()}'; |
| 1573 } else { | 1571 } else { |
| 1574 return super.toString(); | 1572 return super.toString(); |
| 1575 } | 1573 } |
| 1576 } | 1574 } |
| 1577 | 1575 |
| 1578 bool get isAbstract { | 1576 bool get isAbstract { |
| 1579 return !modifiers.isExternal() && | 1577 return !modifiers.isExternal && |
| 1580 (isFunction() || isAccessor()) && | 1578 (isFunction || isAccessor) && |
| 1581 _hasNoBody; | 1579 _hasNoBody; |
| 1582 } | 1580 } |
| 1583 | 1581 |
| 1584 accept(ElementVisitor visitor) => visitor.visitFunctionElement(this); | 1582 accept(ElementVisitor visitor) => visitor.visitFunctionElement(this); |
| 1585 } | 1583 } |
| 1586 | 1584 |
| 1587 class SynthesizedCallMethodElementX extends FunctionElementX { | 1585 class SynthesizedCallMethodElementX extends FunctionElementX { |
| 1588 final FunctionElement expression; | 1586 final FunctionElement expression; |
| 1589 | 1587 |
| 1590 SynthesizedCallMethodElementX(String name, | 1588 SynthesizedCallMethodElementX(String name, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1611 FunctionSignature computeSignature(Compiler compiler) { | 1609 FunctionSignature computeSignature(Compiler compiler) { |
| 1612 if (functionSignatureCache != null) return functionSignature; | 1610 if (functionSignatureCache != null) return functionSignature; |
| 1613 compiler.withCurrentElement(this, () { | 1611 compiler.withCurrentElement(this, () { |
| 1614 DartType inner = new FunctionType(this, compiler.types.dynamicType); | 1612 DartType inner = new FunctionType(this, compiler.types.dynamicType); |
| 1615 functionSignatureCache = new FunctionSignatureX(const Link(), | 1613 functionSignatureCache = new FunctionSignatureX(const Link(), |
| 1616 const Link(), 0, 0, false, [], inner); | 1614 const Link(), 0, 0, false, [], inner); |
| 1617 }); | 1615 }); |
| 1618 return functionSignatureCache; | 1616 return functionSignatureCache; |
| 1619 } | 1617 } |
| 1620 | 1618 |
| 1621 bool isMember() => false; | 1619 bool get isMember => false; |
| 1622 | 1620 |
| 1623 bool isForeign(Compiler compiler) => true; | 1621 bool isForeign(Compiler compiler) => true; |
| 1624 | 1622 |
| 1625 bool get isSynthesized => true; | 1623 bool get isSynthesized => true; |
| 1626 | 1624 |
| 1627 bool isFunction() => false; | 1625 bool get isFunction => false; |
| 1628 | 1626 |
| 1629 bool isDeferredLoaderGetter() => true; | 1627 bool get isDeferredLoaderGetter => true; |
| 1630 | 1628 |
| 1631 bool isGetter() => true; | 1629 bool get isGetter => true; |
| 1632 | 1630 |
| 1633 // By having position null, the enclosing elements location is printed in | 1631 // By having position null, the enclosing elements location is printed in |
| 1634 // error messages. | 1632 // error messages. |
| 1635 Token position() => null; | 1633 Token get position => null; |
| 1636 } | 1634 } |
| 1637 | 1635 |
| 1638 class ConstructorBodyElementX extends FunctionElementX | 1636 class ConstructorBodyElementX extends FunctionElementX |
| 1639 implements ConstructorBodyElement { | 1637 implements ConstructorBodyElement { |
| 1640 FunctionElement constructor; | 1638 FunctionElement constructor; |
| 1641 | 1639 |
| 1642 ConstructorBodyElementX(FunctionElement constructor) | 1640 ConstructorBodyElementX(FunctionElement constructor) |
| 1643 : this.constructor = constructor, | 1641 : this.constructor = constructor, |
| 1644 super(constructor.name, | 1642 super(constructor.name, |
| 1645 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, | 1643 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, |
| 1646 Modifiers.EMPTY, | 1644 Modifiers.EMPTY, |
| 1647 constructor.enclosingElement, false) { | 1645 constructor.enclosingElement, false) { |
| 1648 functionSignatureCache = constructor.functionSignature; | 1646 functionSignatureCache = constructor.functionSignature; |
| 1649 } | 1647 } |
| 1650 | 1648 |
| 1651 bool isInstanceMember() => true; | 1649 bool get isInstanceMember => true; |
| 1652 | 1650 |
| 1653 FunctionType computeType(Compiler compiler) { | 1651 FunctionType computeType(Compiler compiler) { |
| 1654 compiler.internalError(this, '$this.computeType.'); | 1652 compiler.internalError(this, '$this.computeType.'); |
| 1655 return null; | 1653 return null; |
| 1656 } | 1654 } |
| 1657 | 1655 |
| 1658 Node parseNode(DiagnosticListener listener) { | 1656 Node parseNode(DiagnosticListener listener) { |
| 1659 if (cachedNode != null) return cachedNode; | 1657 if (cachedNode != null) return cachedNode; |
| 1660 cachedNode = constructor.parseNode(listener); | 1658 cachedNode = constructor.parseNode(listener); |
| 1661 assert(cachedNode != null); | 1659 assert(cachedNode != null); |
| 1662 return cachedNode; | 1660 return cachedNode; |
| 1663 } | 1661 } |
| 1664 | 1662 |
| 1665 Token position() => constructor.position(); | 1663 Token get position => constructor.position; |
| 1666 | 1664 |
| 1667 Element getOutermostEnclosingMemberOrTopLevel() => constructor; | 1665 Element get outermostEnclosingMemberOrTopLevel => constructor; |
| 1668 | 1666 |
| 1669 accept(ElementVisitor visitor) => visitor.visitConstructorBodyElement(this); | 1667 accept(ElementVisitor visitor) => visitor.visitConstructorBodyElement(this); |
| 1670 } | 1668 } |
| 1671 | 1669 |
| 1672 /** | 1670 /** |
| 1673 * A constructor that is not defined in the source code but rather implied by | 1671 * A constructor that is not defined in the source code but rather implied by |
| 1674 * the language semantics. | 1672 * the language semantics. |
| 1675 * | 1673 * |
| 1676 * This class is used to represent default constructors and forwarding | 1674 * This class is used to represent default constructors and forwarding |
| 1677 * constructors for mixin applications. | 1675 * constructors for mixin applications. |
| 1678 */ | 1676 */ |
| 1679 class SynthesizedConstructorElementX extends FunctionElementX { | 1677 class SynthesizedConstructorElementX extends FunctionElementX { |
| 1680 final FunctionElement superMember; | 1678 final FunctionElement superMember; |
| 1681 final bool isDefaultConstructor; | 1679 final bool isDefaultConstructor; |
| 1682 | 1680 |
| 1683 SynthesizedConstructorElementX(String name, | 1681 SynthesizedConstructorElementX(String name, |
| 1684 this.superMember, | 1682 this.superMember, |
| 1685 Element enclosing, | 1683 Element enclosing, |
| 1686 this.isDefaultConstructor) | 1684 this.isDefaultConstructor) |
| 1687 : super(name, | 1685 : super(name, |
| 1688 ElementKind.GENERATIVE_CONSTRUCTOR, | 1686 ElementKind.GENERATIVE_CONSTRUCTOR, |
| 1689 Modifiers.EMPTY, | 1687 Modifiers.EMPTY, |
| 1690 enclosing, false); | 1688 enclosing, false); |
| 1691 | 1689 |
| 1692 SynthesizedConstructorElementX.forDefault(superMember, Element enclosing) | 1690 SynthesizedConstructorElementX.forDefault(superMember, Element enclosing) |
| 1693 : this('', superMember, enclosing, true); | 1691 : this('', superMember, enclosing, true); |
| 1694 | 1692 |
| 1695 Token position() => enclosingElement.position(); | 1693 Token get position => enclosingElement.position; |
| 1696 | 1694 |
| 1697 bool get isSynthesized => true; | 1695 bool get isSynthesized => true; |
| 1698 | 1696 |
| 1699 FunctionElement get targetConstructor => superMember; | 1697 FunctionElement get targetConstructor => superMember; |
| 1700 | 1698 |
| 1701 FunctionSignature computeSignature(compiler) { | 1699 FunctionSignature computeSignature(compiler) { |
| 1702 if (functionSignatureCache != null) return functionSignatureCache; | 1700 if (functionSignatureCache != null) return functionSignatureCache; |
| 1703 if (isDefaultConstructor) { | 1701 if (isDefaultConstructor) { |
| 1704 return functionSignatureCache = new FunctionSignatureX( | 1702 return functionSignatureCache = new FunctionSignatureX( |
| 1705 const Link<Element>(), const Link<Element>(), 0, 0, false, | 1703 const Link<Element>(), const Link<Element>(), 0, 0, false, |
| 1706 const <Element>[], | 1704 const <Element>[], |
| 1707 new FunctionType(this, getEnclosingClass().thisType)); | 1705 new FunctionType(this, enclosingClass.thisType)); |
| 1708 } | 1706 } |
| 1709 if (superMember.isErroneous()) { | 1707 if (superMember.isErroneous) { |
| 1710 return functionSignatureCache = | 1708 return functionSignatureCache = |
| 1711 compiler.objectClass.localLookup('').computeSignature(compiler); | 1709 compiler.objectClass.localLookup('').computeSignature(compiler); |
| 1712 } | 1710 } |
| 1713 // TODO(johnniwinther): Ensure that the function signature (and with it the | 1711 // TODO(johnniwinther): Ensure that the function signature (and with it the |
| 1714 // function type) substitutes type variables correctly. | 1712 // function type) substitutes type variables correctly. |
| 1715 return functionSignatureCache = superMember.computeSignature(compiler); | 1713 return functionSignatureCache = superMember.computeSignature(compiler); |
| 1716 } | 1714 } |
| 1717 | 1715 |
| 1718 get declaration => this; | 1716 get declaration => this; |
| 1719 get implementation => this; | 1717 get implementation => this; |
| 1720 get defaultImplementation => this; | 1718 get defaultImplementation => this; |
| 1721 | 1719 |
| 1722 accept(ElementVisitor visitor) { | 1720 accept(ElementVisitor visitor) { |
| 1723 return visitor.visitFunctionElement(this); | 1721 return visitor.visitFunctionElement(this); |
| 1724 } | 1722 } |
| 1725 } | 1723 } |
| 1726 | 1724 |
| 1727 class VoidElementX extends ElementX implements VoidElement { | 1725 class VoidElementX extends ElementX implements VoidElement { |
| 1728 VoidElementX(Element enclosing) : super('void', ElementKind.VOID, enclosing); | 1726 VoidElementX(Element enclosing) : super('void', ElementKind.VOID, enclosing); |
| 1729 DartType computeType(compiler) => compiler.types.voidType; | 1727 DartType computeType(compiler) => compiler.types.voidType; |
| 1730 Node parseNode(_) { | 1728 Node parseNode(_) { |
| 1731 throw 'internal error: parseNode on void'; | 1729 throw 'internal error: parseNode on void'; |
| 1732 } | 1730 } |
| 1733 bool impliesType() => true; | 1731 bool get impliesType => true; |
| 1734 | 1732 |
| 1735 accept(ElementVisitor visitor) => visitor.visitVoidElement(this); | 1733 accept(ElementVisitor visitor) => visitor.visitVoidElement(this); |
| 1736 } | 1734 } |
| 1737 | 1735 |
| 1738 abstract class TypeDeclarationElementX<T extends GenericType> | 1736 abstract class TypeDeclarationElementX<T extends GenericType> |
| 1739 implements TypeDeclarationElement { | 1737 implements TypeDeclarationElement { |
| 1740 /** | 1738 /** |
| 1741 * The `this type` for this type declaration. | 1739 * The `this type` for this type declaration. |
| 1742 * | 1740 * |
| 1743 * The type of [:this:] is the generic type based on this element in which | 1741 * The type of [:this:] is the generic type based on this element in which |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 void ensureResolved(Compiler compiler) { | 1899 void ensureResolved(Compiler compiler) { |
| 1902 if (resolutionState == STATE_NOT_STARTED) { | 1900 if (resolutionState == STATE_NOT_STARTED) { |
| 1903 compiler.resolver.resolveClass(this); | 1901 compiler.resolver.resolveClass(this); |
| 1904 } | 1902 } |
| 1905 } | 1903 } |
| 1906 | 1904 |
| 1907 void setDefaultConstructor(FunctionElement constructor, Compiler compiler); | 1905 void setDefaultConstructor(FunctionElement constructor, Compiler compiler); |
| 1908 | 1906 |
| 1909 void addBackendMember(Element member) { | 1907 void addBackendMember(Element member) { |
| 1910 // TODO(ngeoffray): Deprecate this method. | 1908 // TODO(ngeoffray): Deprecate this method. |
| 1911 assert(member.isGenerativeConstructorBody()); | 1909 assert(member.isGenerativeConstructorBody); |
| 1912 backendMembers = backendMembers.prepend(member); | 1910 backendMembers = backendMembers.prepend(member); |
| 1913 } | 1911 } |
| 1914 | 1912 |
| 1915 void reverseBackendMembers() { | 1913 void reverseBackendMembers() { |
| 1916 backendMembers = backendMembers.reverse(); | 1914 backendMembers = backendMembers.reverse(); |
| 1917 } | 1915 } |
| 1918 | 1916 |
| 1919 /** | 1917 /** |
| 1920 * Lookup local members in the class. This will ignore constructors. | 1918 * Lookup local members in the class. This will ignore constructors. |
| 1921 */ | 1919 */ |
| 1922 Element lookupLocalMember(String memberName) { | 1920 Element lookupLocalMember(String memberName) { |
| 1923 var result = localLookup(memberName); | 1921 var result = localLookup(memberName); |
| 1924 if (result != null && result.isConstructor()) return null; | 1922 if (result != null && result.isConstructor) return null; |
| 1925 return result; | 1923 return result; |
| 1926 } | 1924 } |
| 1927 | 1925 |
| 1928 /// Lookup a synthetic element created by the backend. | 1926 /// Lookup a synthetic element created by the backend. |
| 1929 Element lookupBackendMember(String memberName) { | 1927 Element lookupBackendMember(String memberName) { |
| 1930 for (Element element in backendMembers) { | 1928 for (Element element in backendMembers) { |
| 1931 if (element.name == memberName) { | 1929 if (element.name == memberName) { |
| 1932 return element; | 1930 return element; |
| 1933 } | 1931 } |
| 1934 } | 1932 } |
| 1935 return null; | 1933 return null; |
| 1936 } | 1934 } |
| 1937 /** | 1935 /** |
| 1938 * Lookup super members for the class. This will ignore constructors. | 1936 * Lookup super members for the class. This will ignore constructors. |
| 1939 */ | 1937 */ |
| 1940 Element lookupSuperMember(String memberName) { | 1938 Element lookupSuperMember(String memberName) { |
| 1941 return lookupSuperMemberInLibrary(memberName, getLibrary()); | 1939 return lookupSuperMemberInLibrary(memberName, library); |
| 1942 } | 1940 } |
| 1943 | 1941 |
| 1944 /** | 1942 /** |
| 1945 * Lookup super members for the class that is accessible in [library]. | 1943 * Lookup super members for the class that is accessible in [library]. |
| 1946 * This will ignore constructors. | 1944 * This will ignore constructors. |
| 1947 */ | 1945 */ |
| 1948 Element lookupSuperMemberInLibrary(String memberName, | 1946 Element lookupSuperMemberInLibrary(String memberName, |
| 1949 LibraryElement library) { | 1947 LibraryElement library) { |
| 1950 bool isPrivate = isPrivateName(memberName); | 1948 bool isPrivate = isPrivateName(memberName); |
| 1951 for (ClassElement s = superclass; s != null; s = s.superclass) { | 1949 for (ClassElement s = superclass; s != null; s = s.superclass) { |
| 1952 // Private members from a different library are not visible. | 1950 // Private members from a different library are not visible. |
| 1953 if (isPrivate && !identical(library, s.getLibrary())) continue; | 1951 if (isPrivate && !identical(library, s.library)) continue; |
| 1954 Element e = s.lookupLocalMember(memberName); | 1952 Element e = s.lookupLocalMember(memberName); |
| 1955 if (e == null) continue; | 1953 if (e == null) continue; |
| 1956 // Static members are not inherited. | 1954 // Static members are not inherited. |
| 1957 if (e.modifiers.isStatic()) continue; | 1955 if (e.modifiers.isStatic) continue; |
| 1958 return e; | 1956 return e; |
| 1959 } | 1957 } |
| 1960 return null; | 1958 return null; |
| 1961 } | 1959 } |
| 1962 | 1960 |
| 1963 /** | 1961 /** |
| 1964 * Find the first member in the class chain with the given [selector]. | 1962 * Find the first member in the class chain with the given [selector]. |
| 1965 * | 1963 * |
| 1966 * This method is NOT to be used for resolving | 1964 * This method is NOT to be used for resolving |
| 1967 * unqualified sends because it does not implement the scoping | 1965 * unqualified sends because it does not implement the scoping |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1988 current != null; | 1986 current != null; |
| 1989 current = current.superclass) { | 1987 current = current.superclass) { |
| 1990 Element member = current.lookupLocalMember(name); | 1988 Element member = current.lookupLocalMember(name); |
| 1991 if (member == null && current.isPatched) { | 1989 if (member == null && current.isPatched) { |
| 1992 // Doing lookups on selectors is done after resolution, so it | 1990 // Doing lookups on selectors is done after resolution, so it |
| 1993 // is safe to look in the patch class. | 1991 // is safe to look in the patch class. |
| 1994 member = current.patch.lookupLocalMember(name); | 1992 member = current.patch.lookupLocalMember(name); |
| 1995 } | 1993 } |
| 1996 if (member == null) continue; | 1994 if (member == null) continue; |
| 1997 // Private members from a different library are not visible. | 1995 // Private members from a different library are not visible. |
| 1998 if (isPrivate && !identical(library, member.getLibrary())) continue; | 1996 if (isPrivate && !identical(library, member.library)) continue; |
| 1999 // Static members are not inherited. | 1997 // Static members are not inherited. |
| 2000 if (member.modifiers.isStatic() && !identical(this, current)) continue; | 1998 if (member.modifiers.isStatic && !identical(this, current)) continue; |
| 2001 // If we find an abstract field we have to make sure that it has | 1999 // If we find an abstract field we have to make sure that it has |
| 2002 // the getter or setter part we're actually looking | 2000 // the getter or setter part we're actually looking |
| 2003 // for. Otherwise, we continue up the superclass chain. | 2001 // for. Otherwise, we continue up the superclass chain. |
| 2004 if (member.isAbstractField()) { | 2002 if (member.isAbstractField) { |
| 2005 AbstractFieldElement field = member; | 2003 AbstractFieldElement field = member; |
| 2006 FunctionElement getter = field.getter; | 2004 FunctionElement getter = field.getter; |
| 2007 FunctionElement setter = field.setter; | 2005 FunctionElement setter = field.setter; |
| 2008 if (selector.isSetter()) { | 2006 if (selector.isSetter) { |
| 2009 // Abstract members can be defined in a super class. | 2007 // Abstract members can be defined in a super class. |
| 2010 if (setter != null && !setter.isAbstract) return setter; | 2008 if (setter != null && !setter.isAbstract) return setter; |
| 2011 } else { | 2009 } else { |
| 2012 assert(selector.isGetter() || selector.isCall()); | 2010 assert(selector.isGetter || selector.isCall); |
| 2013 if (getter != null && !getter.isAbstract) return getter; | 2011 if (getter != null && !getter.isAbstract) return getter; |
| 2014 } | 2012 } |
| 2015 // Abstract members can be defined in a super class. | 2013 // Abstract members can be defined in a super class. |
| 2016 } else if (!member.isAbstract) { | 2014 } else if (!member.isAbstract) { |
| 2017 return member; | 2015 return member; |
| 2018 } | 2016 } |
| 2019 } | 2017 } |
| 2020 return null; | 2018 return null; |
| 2021 } | 2019 } |
| 2022 | 2020 |
| 2023 /** | 2021 /** |
| 2024 * Find the first member in the class chain with the given | 2022 * Find the first member in the class chain with the given |
| 2025 * [memberName]. This method is NOT to be used for resolving | 2023 * [memberName]. This method is NOT to be used for resolving |
| 2026 * unqualified sends because it does not implement the scoping | 2024 * unqualified sends because it does not implement the scoping |
| 2027 * rules, where library scope comes before superclass scope. | 2025 * rules, where library scope comes before superclass scope. |
| 2028 */ | 2026 */ |
| 2029 Element lookupMember(String memberName) { | 2027 Element lookupMember(String memberName) { |
| 2030 Element localMember = lookupLocalMember(memberName); | 2028 Element localMember = lookupLocalMember(memberName); |
| 2031 return localMember == null ? lookupSuperMember(memberName) : localMember; | 2029 return localMember == null ? lookupSuperMember(memberName) : localMember; |
| 2032 } | 2030 } |
| 2033 | 2031 |
| 2034 /** | 2032 /** |
| 2035 * Returns true if the [fieldMember] shadows another field. The given | 2033 * Returns true if the [fieldMember] shadows another field. The given |
| 2036 * [fieldMember] must be a member of this class, i.e. if there is a field of | 2034 * [fieldMember] must be a member of this class, i.e. if there is a field of |
| 2037 * the same name in the superclass chain. | 2035 * the same name in the superclass chain. |
| 2038 * | 2036 * |
| 2039 * This method also works if the [fieldMember] is private. | 2037 * This method also works if the [fieldMember] is private. |
| 2040 */ | 2038 */ |
| 2041 bool hasFieldShadowedBy(Element fieldMember) { | 2039 bool hasFieldShadowedBy(Element fieldMember) { |
| 2042 assert(fieldMember.isField()); | 2040 assert(fieldMember.isField); |
| 2043 String fieldName = fieldMember.name; | 2041 String fieldName = fieldMember.name; |
| 2044 bool isPrivate = isPrivateName(fieldName); | 2042 bool isPrivate = isPrivateName(fieldName); |
| 2045 LibraryElement memberLibrary = fieldMember.getLibrary(); | 2043 LibraryElement memberLibrary = fieldMember.library; |
| 2046 ClassElement lookupClass = this.superclass; | 2044 ClassElement lookupClass = this.superclass; |
| 2047 while (lookupClass != null) { | 2045 while (lookupClass != null) { |
| 2048 Element foundMember = lookupClass.lookupLocalMember(fieldName); | 2046 Element foundMember = lookupClass.lookupLocalMember(fieldName); |
| 2049 if (foundMember != null) { | 2047 if (foundMember != null) { |
| 2050 if (foundMember.isField()) { | 2048 if (foundMember.isField) { |
| 2051 if (!isPrivate || memberLibrary == foundMember.getLibrary()) { | 2049 if (!isPrivate || memberLibrary == foundMember.library) { |
| 2052 // Private fields can only be shadowed by a field declared in the | 2050 // Private fields can only be shadowed by a field declared in the |
| 2053 // same library. | 2051 // same library. |
| 2054 return true; | 2052 return true; |
| 2055 } | 2053 } |
| 2056 } | 2054 } |
| 2057 } | 2055 } |
| 2058 lookupClass = lookupClass.superclass; | 2056 lookupClass = lookupClass.superclass; |
| 2059 } | 2057 } |
| 2060 return false; | 2058 return false; |
| 2061 } | 2059 } |
| 2062 | 2060 |
| 2063 Element validateConstructorLookupResults(Selector selector, | 2061 Element validateConstructorLookupResults(Selector selector, |
| 2064 Element result, | 2062 Element result, |
| 2065 Element noMatch(Element)) { | 2063 Element noMatch(Element)) { |
| 2066 if (result == null | 2064 if (result == null |
| 2067 || !result.isConstructor() | 2065 || !result.isConstructor |
| 2068 || (isPrivateName(selector.name) | 2066 || (isPrivateName(selector.name) |
| 2069 && result.getLibrary() != selector.library)) { | 2067 && result.library != selector.library)) { |
| 2070 result = noMatch != null ? noMatch(result) : null; | 2068 result = noMatch != null ? noMatch(result) : null; |
| 2071 } | 2069 } |
| 2072 return result; | 2070 return result; |
| 2073 } | 2071 } |
| 2074 | 2072 |
| 2075 // TODO(aprelev@gmail.com): Peter believes that it would be great to | 2073 // TODO(aprelev@gmail.com): Peter believes that it would be great to |
| 2076 // make noMatch a required argument. Peter's suspicion is that most | 2074 // make noMatch a required argument. Peter's suspicion is that most |
| 2077 // callers of this method would benefit from using the noMatch method. | 2075 // callers of this method would benefit from using the noMatch method. |
| 2078 Element lookupConstructor(Selector selector, [Element noMatch(Element)]) { | 2076 Element lookupConstructor(Selector selector, [Element noMatch(Element)]) { |
| 2079 Element result = localLookup(selector.name); | 2077 Element result = localLookup(selector.name); |
| 2080 return validateConstructorLookupResults(selector, result, noMatch); | 2078 return validateConstructorLookupResults(selector, result, noMatch); |
| 2081 } | 2079 } |
| 2082 | 2080 |
| 2083 Link<Element> get constructors { | 2081 Link<Element> get constructors { |
| 2084 // TODO(ajohnsen): See if we can avoid this method at some point. | 2082 // TODO(ajohnsen): See if we can avoid this method at some point. |
| 2085 Link<Element> result = const Link<Element>(); | 2083 Link<Element> result = const Link<Element>(); |
| 2086 // TODO(johnniwinther): Should we include injected constructors? | 2084 // TODO(johnniwinther): Should we include injected constructors? |
| 2087 forEachMember((_, Element member) { | 2085 forEachMember((_, Element member) { |
| 2088 if (member.isConstructor()) result = result.prepend(member); | 2086 if (member.isConstructor) result = result.prepend(member); |
| 2089 }); | 2087 }); |
| 2090 return result; | 2088 return result; |
| 2091 } | 2089 } |
| 2092 | 2090 |
| 2093 /** | 2091 /** |
| 2094 * Returns the super class, if any. | 2092 * Returns the super class, if any. |
| 2095 * | 2093 * |
| 2096 * The returned element may not be resolved yet. | 2094 * The returned element may not be resolved yet. |
| 2097 */ | 2095 */ |
| 2098 ClassElement get superclass { | 2096 ClassElement get superclass { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2144 * [includeSuperAndInjectedMembers] is [:true:]. | 2142 * [includeSuperAndInjectedMembers] is [:true:]. |
| 2145 * | 2143 * |
| 2146 * When called on the implementation element both the fields declared in the | 2144 * When called on the implementation element both the fields declared in the |
| 2147 * origin and in the patch are included. | 2145 * origin and in the patch are included. |
| 2148 */ | 2146 */ |
| 2149 void forEachInstanceField(void f(ClassElement enclosingClass, | 2147 void forEachInstanceField(void f(ClassElement enclosingClass, |
| 2150 FieldElement field), | 2148 FieldElement field), |
| 2151 {bool includeSuperAndInjectedMembers: false}) { | 2149 {bool includeSuperAndInjectedMembers: false}) { |
| 2152 // Filters so that [f] is only invoked with instance fields. | 2150 // Filters so that [f] is only invoked with instance fields. |
| 2153 void fieldFilter(ClassElement enclosingClass, Element member) { | 2151 void fieldFilter(ClassElement enclosingClass, Element member) { |
| 2154 if (member.isInstanceMember() && member.kind == ElementKind.FIELD) { | 2152 if (member.isInstanceMember && member.kind == ElementKind.FIELD) { |
| 2155 f(enclosingClass, member); | 2153 f(enclosingClass, member); |
| 2156 } | 2154 } |
| 2157 } | 2155 } |
| 2158 | 2156 |
| 2159 forEachMember(fieldFilter, | 2157 forEachMember(fieldFilter, |
| 2160 includeSuperAndInjectedMembers: includeSuperAndInjectedMembers); | 2158 includeSuperAndInjectedMembers: includeSuperAndInjectedMembers); |
| 2161 } | 2159 } |
| 2162 | 2160 |
| 2163 /// Similar to [forEachInstanceField] but visits static fields. | 2161 /// Similar to [forEachInstanceField] but visits static fields. |
| 2164 void forEachStaticField(void f(ClassElement enclosingClass, Element field)) { | 2162 void forEachStaticField(void f(ClassElement enclosingClass, Element field)) { |
| 2165 // Filters so that [f] is only invoked with static fields. | 2163 // Filters so that [f] is only invoked with static fields. |
| 2166 void fieldFilter(ClassElement enclosingClass, Element member) { | 2164 void fieldFilter(ClassElement enclosingClass, Element member) { |
| 2167 if (!member.isInstanceMember() && member.kind == ElementKind.FIELD) { | 2165 if (!member.isInstanceMember && member.kind == ElementKind.FIELD) { |
| 2168 f(enclosingClass, member); | 2166 f(enclosingClass, member); |
| 2169 } | 2167 } |
| 2170 } | 2168 } |
| 2171 | 2169 |
| 2172 forEachMember(fieldFilter); | 2170 forEachMember(fieldFilter); |
| 2173 } | 2171 } |
| 2174 | 2172 |
| 2175 void forEachBackendMember(void f(Element member)) { | 2173 void forEachBackendMember(void f(Element member)) { |
| 2176 backendMembers.forEach(f); | 2174 backendMembers.forEach(f); |
| 2177 } | 2175 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2196 bool isSubclassOf(ClassElement cls) { | 2194 bool isSubclassOf(ClassElement cls) { |
| 2197 // Use [declaration] for both [this] and [cls], because | 2195 // Use [declaration] for both [this] and [cls], because |
| 2198 // declaration classes hold the superclass hierarchy. | 2196 // declaration classes hold the superclass hierarchy. |
| 2199 cls = cls.declaration; | 2197 cls = cls.declaration; |
| 2200 for (ClassElement s = declaration; s != null; s = s.superclass) { | 2198 for (ClassElement s = declaration; s != null; s = s.superclass) { |
| 2201 if (identical(s, cls)) return true; | 2199 if (identical(s, cls)) return true; |
| 2202 } | 2200 } |
| 2203 return false; | 2201 return false; |
| 2204 } | 2202 } |
| 2205 | 2203 |
| 2206 bool isNative() => nativeTagInfo != null; | 2204 bool get isNative => nativeTagInfo != null; |
| 2207 void setNative(String name) { | 2205 void setNative(String name) { |
| 2208 nativeTagInfo = name; | 2206 nativeTagInfo = name; |
| 2209 } | 2207 } |
| 2210 | 2208 |
| 2211 FunctionType get callType { | 2209 FunctionType get callType { |
| 2212 MemberSignature member = | 2210 MemberSignature member = |
| 2213 lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME)); | 2211 lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME)); |
| 2214 return member != null && member.isMethod ? member.type : null; | 2212 return member != null && member.isMethod ? member.type : null; |
| 2215 } | 2213 } |
| 2216 | 2214 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2230 | 2228 |
| 2231 bool get isMixinApplication => false; | 2229 bool get isMixinApplication => false; |
| 2232 bool get hasLocalScopeMembers => !localScope.isEmpty; | 2230 bool get hasLocalScopeMembers => !localScope.isEmpty; |
| 2233 | 2231 |
| 2234 void addMember(Element element, DiagnosticListener listener) { | 2232 void addMember(Element element, DiagnosticListener listener) { |
| 2235 localMembers = localMembers.prepend(element); | 2233 localMembers = localMembers.prepend(element); |
| 2236 addToScope(element, listener); | 2234 addToScope(element, listener); |
| 2237 } | 2235 } |
| 2238 | 2236 |
| 2239 void addToScope(Element element, DiagnosticListener listener) { | 2237 void addToScope(Element element, DiagnosticListener listener) { |
| 2240 if (element.isField() && element.name == name) { | 2238 if (element.isField && element.name == name) { |
| 2241 listener.reportError(element, MessageKind.MEMBER_USES_CLASS_NAME); | 2239 listener.reportError(element, MessageKind.MEMBER_USES_CLASS_NAME); |
| 2242 } | 2240 } |
| 2243 localScope.add(element, listener); | 2241 localScope.add(element, listener); |
| 2244 } | 2242 } |
| 2245 | 2243 |
| 2246 Element localLookup(String elementName) { | 2244 Element localLookup(String elementName) { |
| 2247 Element result = localScope.lookup(elementName); | 2245 Element result = localScope.lookup(elementName); |
| 2248 if (result == null && isPatch) { | 2246 if (result == null && isPatch) { |
| 2249 result = origin.localLookup(elementName); | 2247 result = origin.localLookup(elementName); |
| 2250 } | 2248 } |
| 2251 return result; | 2249 return result; |
| 2252 } | 2250 } |
| 2253 | 2251 |
| 2254 void forEachLocalMember(void f(Element member)) { | 2252 void forEachLocalMember(void f(Element member)) { |
| 2255 localMembers.reverse().forEach(f); | 2253 localMembers.reverse().forEach(f); |
| 2256 } | 2254 } |
| 2257 | 2255 |
| 2258 bool get hasConstructor { | 2256 bool get hasConstructor { |
| 2259 // Search in scope to be sure we search patched constructors. | 2257 // Search in scope to be sure we search patched constructors. |
| 2260 for (var element in localScope.values) { | 2258 for (var element in localScope.values) { |
| 2261 if (element.isConstructor()) return true; | 2259 if (element.isConstructor) return true; |
| 2262 } | 2260 } |
| 2263 return false; | 2261 return false; |
| 2264 } | 2262 } |
| 2265 | 2263 |
| 2266 void setDefaultConstructor(FunctionElement constructor, Compiler compiler) { | 2264 void setDefaultConstructor(FunctionElement constructor, Compiler compiler) { |
| 2267 addToScope(constructor, compiler); | 2265 addToScope(constructor, compiler); |
| 2268 // The default constructor, although synthetic, is part of a class' API. | 2266 // The default constructor, although synthetic, is part of a class' API. |
| 2269 localMembers = localMembers.prepend(constructor); | 2267 localMembers = localMembers.prepend(constructor); |
| 2270 } | 2268 } |
| 2271 | 2269 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2303 ClassElement get mixin => mixinType != null ? mixinType.element : null; | 2301 ClassElement get mixin => mixinType != null ? mixinType.element : null; |
| 2304 | 2302 |
| 2305 bool get isMixinApplication => true; | 2303 bool get isMixinApplication => true; |
| 2306 bool get isUnnamedMixinApplication => node is! NamedMixinApplication; | 2304 bool get isUnnamedMixinApplication => node is! NamedMixinApplication; |
| 2307 bool get hasConstructor => !constructors.isEmpty; | 2305 bool get hasConstructor => !constructors.isEmpty; |
| 2308 bool get hasLocalScopeMembers => !constructors.isEmpty; | 2306 bool get hasLocalScopeMembers => !constructors.isEmpty; |
| 2309 | 2307 |
| 2310 get patch => null; | 2308 get patch => null; |
| 2311 get origin => null; | 2309 get origin => null; |
| 2312 | 2310 |
| 2313 Token position() => node.getBeginToken(); | 2311 Token get position => node.getBeginToken(); |
| 2314 | 2312 |
| 2315 Node parseNode(DiagnosticListener listener) => node; | 2313 Node parseNode(DiagnosticListener listener) => node; |
| 2316 | 2314 |
| 2317 FunctionElement lookupLocalConstructor(String name) { | 2315 FunctionElement lookupLocalConstructor(String name) { |
| 2318 for (Link<Element> link = constructors; | 2316 for (Link<Element> link = constructors; |
| 2319 !link.isEmpty; | 2317 !link.isEmpty; |
| 2320 link = link.tail) { | 2318 link = link.tail) { |
| 2321 if (link.head.name == name) return link.head; | 2319 if (link.head.name == name) return link.head; |
| 2322 } | 2320 } |
| 2323 return null; | 2321 return null; |
| 2324 } | 2322 } |
| 2325 | 2323 |
| 2326 Element localLookup(String name) { | 2324 Element localLookup(String name) { |
| 2327 Element constructor = lookupLocalConstructor(name); | 2325 Element constructor = lookupLocalConstructor(name); |
| 2328 if (constructor != null) return constructor; | 2326 if (constructor != null) return constructor; |
| 2329 if (mixin == null) return null; | 2327 if (mixin == null) return null; |
| 2330 Element mixedInElement = mixin.localLookup(name); | 2328 Element mixedInElement = mixin.localLookup(name); |
| 2331 if (mixedInElement == null) return null; | 2329 if (mixedInElement == null) return null; |
| 2332 return mixedInElement.isInstanceMember() ? mixedInElement : null; | 2330 return mixedInElement.isInstanceMember ? mixedInElement : null; |
| 2333 } | 2331 } |
| 2334 | 2332 |
| 2335 void forEachLocalMember(void f(Element member)) { | 2333 void forEachLocalMember(void f(Element member)) { |
| 2336 constructors.forEach(f); | 2334 constructors.forEach(f); |
| 2337 if (mixin != null) mixin.forEachLocalMember((Element mixedInElement) { | 2335 if (mixin != null) mixin.forEachLocalMember((Element mixedInElement) { |
| 2338 if (mixedInElement.isInstanceMember()) f(mixedInElement); | 2336 if (mixedInElement.isInstanceMember) f(mixedInElement); |
| 2339 }); | 2337 }); |
| 2340 } | 2338 } |
| 2341 | 2339 |
| 2342 void addMember(Element element, DiagnosticListener listener) { | 2340 void addMember(Element element, DiagnosticListener listener) { |
| 2343 throw new UnsupportedError("Cannot add member to $this."); | 2341 throw new UnsupportedError("Cannot add member to $this."); |
| 2344 } | 2342 } |
| 2345 | 2343 |
| 2346 void addToScope(Element element, DiagnosticListener listener) { | 2344 void addToScope(Element element, DiagnosticListener listener) { |
| 2347 listener.internalError(this, 'Cannot add to scope of $this.'); | 2345 listener.internalError(this, 'Cannot add to scope of $this.'); |
| 2348 } | 2346 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2394 target.isBreakTarget = true; | 2392 target.isBreakTarget = true; |
| 2395 } | 2393 } |
| 2396 void setContinueTarget() { | 2394 void setContinueTarget() { |
| 2397 isContinueTarget = true; | 2395 isContinueTarget = true; |
| 2398 target.isContinueTarget = true; | 2396 target.isContinueTarget = true; |
| 2399 } | 2397 } |
| 2400 | 2398 |
| 2401 bool get isTarget => isBreakTarget || isContinueTarget; | 2399 bool get isTarget => isBreakTarget || isContinueTarget; |
| 2402 Node parseNode(DiagnosticListener l) => label; | 2400 Node parseNode(DiagnosticListener l) => label; |
| 2403 | 2401 |
| 2404 Token position() => label.getBeginToken(); | 2402 Token get position => label.getBeginToken(); |
| 2405 String toString() => "${labelName}:"; | 2403 String toString() => "${labelName}:"; |
| 2406 | 2404 |
| 2407 accept(ElementVisitor visitor) => visitor.visitLabelElement(this); | 2405 accept(ElementVisitor visitor) => visitor.visitLabelElement(this); |
| 2408 } | 2406 } |
| 2409 | 2407 |
| 2410 // Represents a reference to a statement or switch-case, either by label or the | 2408 // Represents a reference to a statement or switch-case, either by label or the |
| 2411 // default target of a break or continue. | 2409 // default target of a break or continue. |
| 2412 class TargetElementX extends ElementX implements TargetElement { | 2410 class TargetElementX extends ElementX implements TargetElement { |
| 2413 final Node statement; | 2411 final Node statement; |
| 2414 final int nestingLevel; | 2412 final int nestingLevel; |
| 2415 Link<LabelElement> labels = const Link<LabelElement>(); | 2413 Link<LabelElement> labels = const Link<LabelElement>(); |
| 2416 bool isBreakTarget = false; | 2414 bool isBreakTarget = false; |
| 2417 bool isContinueTarget = false; | 2415 bool isContinueTarget = false; |
| 2418 | 2416 |
| 2419 TargetElementX(this.statement, this.nestingLevel, Element enclosingElement) | 2417 TargetElementX(this.statement, this.nestingLevel, Element enclosingElement) |
| 2420 : super("target", ElementKind.STATEMENT, enclosingElement); | 2418 : super("target", ElementKind.STATEMENT, enclosingElement); |
| 2421 bool get isTarget => isBreakTarget || isContinueTarget; | 2419 bool get isTarget => isBreakTarget || isContinueTarget; |
| 2422 | 2420 |
| 2423 LabelElement addLabel(Label label, String labelName) { | 2421 LabelElement addLabel(Label label, String labelName) { |
| 2424 LabelElement result = new LabelElementX(label, labelName, this, | 2422 LabelElement result = new LabelElementX(label, labelName, this, |
| 2425 enclosingElement); | 2423 enclosingElement); |
| 2426 labels = labels.prepend(result); | 2424 labels = labels.prepend(result); |
| 2427 return result; | 2425 return result; |
| 2428 } | 2426 } |
| 2429 | 2427 |
| 2430 Node parseNode(DiagnosticListener l) => statement; | 2428 Node parseNode(DiagnosticListener l) => statement; |
| 2431 | 2429 |
| 2432 bool get isSwitch => statement is SwitchStatement; | 2430 bool get isSwitch => statement is SwitchStatement; |
| 2433 | 2431 |
| 2434 Token position() => statement.getBeginToken(); | 2432 Token get position => statement.getBeginToken(); |
| 2435 String toString() => statement.toString(); | 2433 String toString() => statement.toString(); |
| 2436 | 2434 |
| 2437 accept(ElementVisitor visitor) => visitor.visitTargetElement(this); | 2435 accept(ElementVisitor visitor) => visitor.visitTargetElement(this); |
| 2438 } | 2436 } |
| 2439 | 2437 |
| 2440 class TypeVariableElementX extends ElementX implements TypeVariableElement { | 2438 class TypeVariableElementX extends ElementX implements TypeVariableElement { |
| 2441 final Node cachedNode; | 2439 final Node cachedNode; |
| 2442 TypeVariableType typeCache; | 2440 TypeVariableType typeCache; |
| 2443 DartType boundCache; | 2441 DartType boundCache; |
| 2444 | 2442 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2456 DartType get bound { | 2454 DartType get bound { |
| 2457 assert(invariant(this, boundCache != null, | 2455 assert(invariant(this, boundCache != null, |
| 2458 message: "Bound has not been set on $this.")); | 2456 message: "Bound has not been set on $this.")); |
| 2459 return boundCache; | 2457 return boundCache; |
| 2460 } | 2458 } |
| 2461 | 2459 |
| 2462 Node parseNode(compiler) => cachedNode; | 2460 Node parseNode(compiler) => cachedNode; |
| 2463 | 2461 |
| 2464 String toString() => "${enclosingElement.toString()}.${name}"; | 2462 String toString() => "${enclosingElement.toString()}.${name}"; |
| 2465 | 2463 |
| 2466 Token position() => cachedNode.getBeginToken(); | 2464 Token get position => cachedNode.getBeginToken(); |
| 2467 | 2465 |
| 2468 accept(ElementVisitor visitor) => visitor.visitTypeVariableElement(this); | 2466 accept(ElementVisitor visitor) => visitor.visitTypeVariableElement(this); |
| 2469 } | 2467 } |
| 2470 | 2468 |
| 2471 /** | 2469 /** |
| 2472 * A single metadata annotation. | 2470 * A single metadata annotation. |
| 2473 * | 2471 * |
| 2474 * For example, consider: | 2472 * For example, consider: |
| 2475 * | 2473 * |
| 2476 * class Data { | 2474 * class Data { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2557 assert(invariant(this, this.origin == null, | 2555 assert(invariant(this, this.origin == null, |
| 2558 message: "Origin element is a patch.")); | 2556 message: "Origin element is a patch.")); |
| 2559 assert(invariant(patch, patch.origin == null, | 2557 assert(invariant(patch, patch.origin == null, |
| 2560 message: "Element is patched twice.")); | 2558 message: "Element is patched twice.")); |
| 2561 assert(invariant(patch, patch.patch == null, | 2559 assert(invariant(patch, patch.patch == null, |
| 2562 message: "Patch element is patched.")); | 2560 message: "Patch element is patched.")); |
| 2563 this.patch = patch; | 2561 this.patch = patch; |
| 2564 patch.origin = this; | 2562 patch.origin = this; |
| 2565 } | 2563 } |
| 2566 } | 2564 } |
| OLD | NEW |