| 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 bool get isDeferredLoaderGetter => false; | 83 bool get isDeferredLoaderGetter => false; |
| 84 | 84 |
| 85 bool get isFactoryConstructor => modifiers.isFactory; | 85 bool get isFactoryConstructor => modifiers.isFactory; |
| 86 bool get isConst => modifiers.isConst; | 86 bool get isConst => modifiers.isConst; |
| 87 bool get isFinal => modifiers.isFinal; | 87 bool get isFinal => modifiers.isFinal; |
| 88 bool get isStatic => modifiers.isStatic; | 88 bool get isStatic => modifiers.isStatic; |
| 89 bool get isOperator => Elements.isOperatorName(name); | 89 bool get isOperator => Elements.isOperatorName(name); |
| 90 bool get isStatement => identical(kind, ElementKind.STATEMENT); | 90 bool get isStatement => identical(kind, ElementKind.STATEMENT); |
| 91 bool get impliesType => (kind.category & ElementCategory.IMPLIES_TYPE) != 0; | 91 bool get impliesType => (kind.category & ElementCategory.IMPLIES_TYPE) != 0; |
| 92 | 92 |
| 93 /** See [ErroneousElement] for documentation. */ | |
| 94 bool get isErroneous => false; | |
| 95 | |
| 96 /** See [AmbiguousElement] for documentation. */ | |
| 97 bool get isAmbiguous => false; | |
| 98 | |
| 99 /** See [WarnOnUseElement] for documentation. */ | |
| 100 bool get isWarnOnUse => false; | |
| 101 | |
| 102 bool get isPatched => false; | 93 bool get isPatched => false; |
| 103 | 94 |
| 104 bool get isPatch => false; | 95 bool get isPatch => false; |
| 105 | 96 |
| 106 bool get isImplementation => true; | 97 bool get isImplementation => true; |
| 107 | 98 |
| 108 bool get isDeclaration => true; | 99 bool get isDeclaration => true; |
| 109 | 100 |
| 110 bool get isInjected => !isPatch && implementationLibrary.isPatch; | 101 bool get isInjected => !isPatch && implementationLibrary.isPatch; |
| 111 | 102 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 return null; | 178 return null; |
| 188 } | 179 } |
| 189 | 180 |
| 190 Element get enclosingClassOrCompilationUnit { | 181 Element get enclosingClassOrCompilationUnit { |
| 191 for (Element e = this; e != null; e = e.enclosingElement) { | 182 for (Element e = this; e != null; e = e.enclosingElement) { |
| 192 if (e.isClass || e.isCompilationUnit) return e; | 183 if (e.isClass || e.isCompilationUnit) return e; |
| 193 } | 184 } |
| 194 return null; | 185 return null; |
| 195 } | 186 } |
| 196 | 187 |
| 197 /** | |
| 198 * Returns the member enclosing this element or the element itself if it is a | |
| 199 * member. If no enclosing element is found, [:null:] is returned. | |
| 200 */ | |
| 201 Element get enclosingMember { | |
| 202 for (Element e = this; e != null; e = e.enclosingElement) { | |
| 203 if (e.isClassMember) return e; | |
| 204 } | |
| 205 return null; | |
| 206 } | |
| 207 | |
| 208 Element get outermostEnclosingMemberOrTopLevel { | 188 Element get outermostEnclosingMemberOrTopLevel { |
| 209 // TODO(lrn): Why is this called "Outermost"? | 189 // TODO(lrn): Why is this called "Outermost"? |
| 210 // TODO(johnniwinther): Clean up this method: This method does not return | 190 // TODO(johnniwinther): Clean up this method: This method does not return |
| 211 // the outermost for elements in closure classses, but some call-sites rely | 191 // the outermost for elements in closure classses, but some call-sites rely |
| 212 // on that behavior. | 192 // on that behavior. |
| 213 for (Element e = this; e != null; e = e.enclosingElement) { | 193 for (Element e = this; e != null; e = e.enclosingElement) { |
| 214 if (e.isClassMember || e.isTopLevel) { | 194 if (e.isClassMember || e.isTopLevel) { |
| 215 return e; | 195 return e; |
| 216 } | 196 } |
| 217 } | 197 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 | 254 |
| 275 TreeElements get treeElements => analyzableElement.treeElements; | 255 TreeElements get treeElements => analyzableElement.treeElements; |
| 276 | 256 |
| 277 AnalyzableElement get analyzableElement { | 257 AnalyzableElement get analyzableElement { |
| 278 Element element = outermostEnclosingMemberOrTopLevel; | 258 Element element = outermostEnclosingMemberOrTopLevel; |
| 279 if (element.isAbstractField || element.isPrefix) return element.library; | 259 if (element.isAbstractField || element.isPrefix) return element.library; |
| 280 return element; | 260 return element; |
| 281 } | 261 } |
| 282 } | 262 } |
| 283 | 263 |
| 284 /** | |
| 285 * Represents an unresolvable or duplicated element. | |
| 286 * | |
| 287 * An [ErroneousElement] is used instead of [:null:] to provide additional | |
| 288 * information about the error that caused the element to be unresolvable | |
| 289 * or otherwise invalid. | |
| 290 * | |
| 291 * Accessing any field or calling any method defined on [ErroneousElement] | |
| 292 * except [isErroneous] will currently throw an exception. (This might | |
| 293 * change when we actually want more information on the erroneous element, | |
| 294 * e.g., the name of the element we were trying to resolve.) | |
| 295 * | |
| 296 * Code that cannot not handle an [ErroneousElement] should use | |
| 297 * [: Element.isInvalid(element) :] | |
| 298 * to check for unresolvable elements instead of | |
| 299 * [: element == null :]. | |
| 300 */ | |
| 301 class ErroneousElementX extends ElementX implements ErroneousElement { | 264 class ErroneousElementX extends ElementX implements ErroneousElement { |
| 302 final MessageKind messageKind; | 265 final MessageKind messageKind; |
| 303 final Map messageArguments; | 266 final Map messageArguments; |
| 304 | 267 |
| 305 ErroneousElementX(this.messageKind, this.messageArguments, | 268 ErroneousElementX(this.messageKind, this.messageArguments, |
| 306 String name, Element enclosing) | 269 String name, Element enclosing) |
| 307 : super(name, ElementKind.ERROR, enclosing); | 270 : super(name, ElementKind.ERROR, enclosing); |
| 308 | 271 |
| 309 bool get isErroneous => true; | |
| 310 | |
| 311 bool get isSynthesized => true; | 272 bool get isSynthesized => true; |
| 312 | 273 |
| 313 AbstractFieldElement abstractField; | 274 AbstractFieldElement abstractField; |
| 314 | 275 |
| 315 unsupported() { | 276 unsupported() { |
| 316 throw 'unsupported operation on erroneous element'; | 277 throw 'unsupported operation on erroneous element'; |
| 317 } | 278 } |
| 318 | 279 |
| 319 Link<MetadataAnnotation> get metadata => unsupported(); | 280 Link<MetadataAnnotation> get metadata => unsupported(); |
| 320 bool get hasNode => false; | 281 bool get hasNode => false; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 final MessageKind messageKind; | 323 final MessageKind messageKind; |
| 363 | 324 |
| 364 /** | 325 /** |
| 365 * The message arguments to report on resolving a wrapped element. | 326 * The message arguments to report on resolving a wrapped element. |
| 366 */ | 327 */ |
| 367 final Map messageArguments; | 328 final Map messageArguments; |
| 368 | 329 |
| 369 WrappedMessage(this.spannable, this.messageKind, this.messageArguments); | 330 WrappedMessage(this.spannable, this.messageKind, this.messageArguments); |
| 370 } | 331 } |
| 371 | 332 |
| 372 /** | |
| 373 * An [Element] whose reference should cause one or more warnings. | |
| 374 */ | |
| 375 class WarnOnUseElementX extends ElementX implements WarnOnUseElement { | 333 class WarnOnUseElementX extends ElementX implements WarnOnUseElement { |
| 376 /// Warning to report on resolving this element. | 334 /// Warning to report on resolving this element. |
| 377 final WrappedMessage warning; | 335 final WrappedMessage warning; |
| 378 | 336 |
| 379 /// Info to report on resolving this element. | 337 /// Info to report on resolving this element. |
| 380 final WrappedMessage info; | 338 final WrappedMessage info; |
| 381 | 339 |
| 382 /// The element whose usage cause a warning. | 340 /// The element whose usage cause a warning. |
| 383 final Element wrappedElement; | 341 final Element wrappedElement; |
| 384 | 342 |
| 385 WarnOnUseElementX(WrappedMessage this.warning, WrappedMessage this.info, | 343 WarnOnUseElementX(WrappedMessage this.warning, WrappedMessage this.info, |
| 386 Element enclosingElement, Element wrappedElement) | 344 Element enclosingElement, Element wrappedElement) |
| 387 : this.wrappedElement = wrappedElement, | 345 : this.wrappedElement = wrappedElement, |
| 388 super(wrappedElement.name, ElementKind.WARN_ON_USE, enclosingElement); | 346 super(wrappedElement.name, ElementKind.WARN_ON_USE, enclosingElement); |
| 389 | 347 |
| 390 bool get isWarnOnUse => true; | |
| 391 | |
| 392 Element unwrap(DiagnosticListener listener, Spannable usageSpannable) { | 348 Element unwrap(DiagnosticListener listener, Spannable usageSpannable) { |
| 393 var unwrapped = wrappedElement; | 349 var unwrapped = wrappedElement; |
| 394 if (warning != null) { | 350 if (warning != null) { |
| 395 Spannable spannable = warning.spannable; | 351 Spannable spannable = warning.spannable; |
| 396 if (spannable == null) spannable = usageSpannable; | 352 if (spannable == null) spannable = usageSpannable; |
| 397 listener.reportWarning( | 353 listener.reportWarning( |
| 398 spannable, warning.messageKind, warning.messageArguments); | 354 spannable, warning.messageKind, warning.messageArguments); |
| 399 } | 355 } |
| 400 if (info != null) { | 356 if (info != null) { |
| 401 Spannable spannable = info.spannable; | 357 Spannable spannable = info.spannable; |
| 402 if (spannable == null) spannable = usageSpannable; | 358 if (spannable == null) spannable = usageSpannable; |
| 403 listener.reportInfo( | 359 listener.reportInfo( |
| 404 spannable, info.messageKind, info.messageArguments); | 360 spannable, info.messageKind, info.messageArguments); |
| 405 } | 361 } |
| 406 if (unwrapped.isWarnOnUse) { | 362 if (unwrapped.isWarnOnUse) { |
| 407 unwrapped = unwrapped.unwrap(listener, usageSpannable); | 363 unwrapped = unwrapped.unwrap(listener, usageSpannable); |
| 408 } | 364 } |
| 409 return unwrapped; | 365 return unwrapped; |
| 410 } | 366 } |
| 411 | 367 |
| 412 accept(ElementVisitor visitor) => visitor.visitWarnOnUseElement(this); | 368 accept(ElementVisitor visitor) => visitor.visitWarnOnUseElement(this); |
| 413 } | 369 } |
| 414 | 370 |
| 415 /** | |
| 416 * An ambiguous element represents multiple elements accessible by the same name
. | |
| 417 * | |
| 418 * Ambiguous elements are created during handling of import/export scopes. If an | |
| 419 * ambiguous element is encountered during resolution a warning/error should be | |
| 420 * reported. | |
| 421 */ | |
| 422 class AmbiguousElementX extends ElementX implements AmbiguousElement { | 371 class AmbiguousElementX extends ElementX implements AmbiguousElement { |
| 423 /** | 372 /** |
| 424 * The message to report on resolving this element. | 373 * The message to report on resolving this element. |
| 425 */ | 374 */ |
| 426 final MessageKind messageKind; | 375 final MessageKind messageKind; |
| 427 | 376 |
| 428 /** | 377 /** |
| 429 * The message arguments to report on resolving this element. | 378 * The message arguments to report on resolving this element. |
| 430 */ | 379 */ |
| 431 final Map messageArguments; | 380 final Map messageArguments; |
| 432 | 381 |
| 433 /** | 382 /** |
| 434 * The first element that this ambiguous element might refer to. | 383 * The first element that this ambiguous element might refer to. |
| 435 */ | 384 */ |
| 436 final Element existingElement; | 385 final Element existingElement; |
| 437 | 386 |
| 438 /** | 387 /** |
| 439 * The second element that this ambiguous element might refer to. | 388 * The second element that this ambiguous element might refer to. |
| 440 */ | 389 */ |
| 441 final Element newElement; | 390 final Element newElement; |
| 442 | 391 |
| 443 AmbiguousElementX(this.messageKind, this.messageArguments, | 392 AmbiguousElementX(this.messageKind, this.messageArguments, |
| 444 Element enclosingElement, Element existingElement, Element newElement) | 393 Element enclosingElement, Element existingElement, Element newElement) |
| 445 : this.existingElement = existingElement, | 394 : this.existingElement = existingElement, |
| 446 this.newElement = newElement, | 395 this.newElement = newElement, |
| 447 super(existingElement.name, ElementKind.AMBIGUOUS, enclosingElement); | 396 super(existingElement.name, ElementKind.AMBIGUOUS, enclosingElement); |
| 448 | 397 |
| 449 bool get isAmbiguous => true; | |
| 450 | |
| 451 Setlet flatten() { | 398 Setlet flatten() { |
| 452 Element element = this; | 399 Element element = this; |
| 453 var set = new Setlet(); | 400 var set = new Setlet(); |
| 454 while (element.isAmbiguous) { | 401 while (element.isAmbiguous) { |
| 455 AmbiguousElement ambiguous = element; | 402 AmbiguousElement ambiguous = element; |
| 456 set.add(ambiguous.newElement); | 403 set.add(ambiguous.newElement); |
| 457 element = ambiguous.existingElement; | 404 element = ambiguous.existingElement; |
| 458 } | 405 } |
| 459 set.add(element); | 406 set.add(element); |
| 460 return set; | 407 return set; |
| (...skipping 2258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2719 AstElement get definingElement; | 2666 AstElement get definingElement; |
| 2720 | 2667 |
| 2721 bool get hasResolvedAst => definingElement.hasTreeElements; | 2668 bool get hasResolvedAst => definingElement.hasTreeElements; |
| 2722 | 2669 |
| 2723 ResolvedAst get resolvedAst { | 2670 ResolvedAst get resolvedAst { |
| 2724 return new ResolvedAst(declaration, | 2671 return new ResolvedAst(declaration, |
| 2725 definingElement.node, definingElement.treeElements); | 2672 definingElement.node, definingElement.treeElements); |
| 2726 } | 2673 } |
| 2727 | 2674 |
| 2728 } | 2675 } |
| OLD | NEW |