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 '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/resolution.dart' show | 8 import '../common/resolution.dart' show Resolution, Parsing; |
9 Resolution, | 9 import '../compiler.dart' show Compiler; |
10 Parsing; | |
11 import '../compiler.dart' show | |
12 Compiler; | |
13 import '../constants/constant_constructors.dart'; | 10 import '../constants/constant_constructors.dart'; |
14 import '../constants/constructors.dart'; | 11 import '../constants/constructors.dart'; |
15 import '../constants/expressions.dart'; | 12 import '../constants/expressions.dart'; |
16 import '../dart_types.dart'; | 13 import '../dart_types.dart'; |
17 import '../diagnostics/messages.dart' show | 14 import '../diagnostics/messages.dart' show MessageTemplate; |
18 MessageTemplate; | 15 import '../ordered_typeset.dart' show OrderedTypeSet; |
19 import '../ordered_typeset.dart' show | 16 import '../resolution/class_members.dart' show ClassMemberMixin; |
20 OrderedTypeSet; | 17 import '../resolution/scope.dart' |
21 import '../resolution/class_members.dart' show | 18 show ClassScope, LibraryScope, Scope, TypeDeclarationScope; |
22 ClassMemberMixin; | 19 import '../resolution/resolution.dart' show AnalyzableElementX; |
23 import '../resolution/scope.dart' show | 20 import '../resolution/tree_elements.dart' show TreeElements; |
24 ClassScope, | 21 import '../resolution/typedefs.dart' show TypedefCyclicVisitor; |
25 LibraryScope, | |
26 Scope, | |
27 TypeDeclarationScope; | |
28 import '../resolution/resolution.dart' show | |
29 AnalyzableElementX; | |
30 import '../resolution/tree_elements.dart' show | |
31 TreeElements; | |
32 import '../resolution/typedefs.dart' show | |
33 TypedefCyclicVisitor; | |
34 import '../script.dart'; | 22 import '../script.dart'; |
35 import '../tokens/token.dart' show | 23 import '../tokens/token.dart' show ErrorToken, Token; |
36 ErrorToken, | 24 import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN; |
37 Token; | |
38 import '../tokens/token_constants.dart' as Tokens show | |
39 EOF_TOKEN; | |
40 import '../tree/tree.dart'; | 25 import '../tree/tree.dart'; |
41 import '../util/util.dart'; | 26 import '../util/util.dart'; |
42 | 27 |
43 import 'common.dart'; | 28 import 'common.dart'; |
44 import 'elements.dart'; | 29 import 'elements.dart'; |
45 import 'visitor.dart' show | 30 import 'visitor.dart' show ElementVisitor; |
46 ElementVisitor; | |
47 | 31 |
48 /// Object that identifies a declaration site. | 32 /// Object that identifies a declaration site. |
49 /// | 33 /// |
50 /// For most elements, this is the element itself, but for variable declarations | 34 /// For most elements, this is the element itself, but for variable declarations |
51 /// where multi-declarations like `var a, b, c` are allowed, the declaration | 35 /// where multi-declarations like `var a, b, c` are allowed, the declaration |
52 /// site is a separate object. | 36 /// site is a separate object. |
53 // TODO(johnniwinther): Add [beginToken] and [endToken] getters. | 37 // TODO(johnniwinther): Add [beginToken] and [endToken] getters. |
54 abstract class DeclarationSite { | 38 abstract class DeclarationSite {} |
55 } | |
56 | 39 |
57 abstract class ElementX extends Element with ElementCommon { | 40 abstract class ElementX extends Element with ElementCommon { |
58 static int elementHashCode = 0; | 41 static int elementHashCode = 0; |
59 | 42 |
60 final String name; | 43 final String name; |
61 final ElementKind kind; | 44 final ElementKind kind; |
62 final Element enclosingElement; | 45 final Element enclosingElement; |
63 final int hashCode = ++elementHashCode; | 46 final int hashCode = ++elementHashCode; |
64 List<MetadataAnnotation> metadataInternal; | 47 List<MetadataAnnotation> metadataInternal; |
65 | 48 |
66 ElementX(this.name, this.kind, this.enclosingElement) { | 49 ElementX(this.name, this.kind, this.enclosingElement) { |
67 assert(isError || implementationLibrary != null); | 50 assert(isError || implementationLibrary != null); |
68 } | 51 } |
69 | 52 |
70 Modifiers get modifiers => Modifiers.EMPTY; | 53 Modifiers get modifiers => Modifiers.EMPTY; |
71 | 54 |
72 Node parseNode(Parsing parsing) { | 55 Node parseNode(Parsing parsing) { |
73 parsing.reporter.internalError(this, | 56 parsing.reporter.internalError(this, 'parseNode not implemented on $this.'); |
74 'parseNode not implemented on $this.'); | |
75 return null; | 57 return null; |
76 } | 58 } |
77 | 59 |
78 void set metadata(List<MetadataAnnotation> metadata) { | 60 void set metadata(List<MetadataAnnotation> metadata) { |
79 assert(metadataInternal == null); | 61 assert(metadataInternal == null); |
80 for (MetadataAnnotationX annotation in metadata) { | 62 for (MetadataAnnotationX annotation in metadata) { |
81 assert(annotation.annotatedElement == null); | 63 assert(annotation.annotatedElement == null); |
82 annotation.annotatedElement = this; | 64 annotation.annotatedElement = this; |
83 } | 65 } |
84 metadataInternal = metadata; | 66 metadataInternal = metadata; |
85 } | 67 } |
86 | 68 |
87 Iterable<MetadataAnnotation> get metadata { | 69 Iterable<MetadataAnnotation> get metadata { |
88 if (isPatch && metadataInternal != null) { | 70 if (isPatch && metadataInternal != null) { |
89 if (origin.metadata.isEmpty) { | 71 if (origin.metadata.isEmpty) { |
90 return metadataInternal; | 72 return metadataInternal; |
91 } else { | 73 } else { |
92 return <MetadataAnnotation>[] | 74 return <MetadataAnnotation>[] |
93 ..addAll(origin.metadata) | 75 ..addAll(origin.metadata) |
94 ..addAll(metadataInternal); | 76 ..addAll(metadataInternal); |
95 } | 77 } |
96 } | 78 } |
97 return metadataInternal != null | 79 return metadataInternal != null |
98 ? metadataInternal : const <MetadataAnnotation>[]; | 80 ? metadataInternal |
| 81 : const <MetadataAnnotation>[]; |
99 } | 82 } |
100 | 83 |
101 bool get isClosure => false; | 84 bool get isClosure => false; |
102 bool get isClassMember { | 85 bool get isClassMember { |
103 // Check that this element is defined in the scope of a Class. | 86 // Check that this element is defined in the scope of a Class. |
104 return enclosingElement != null && enclosingElement.isClass; | 87 return enclosingElement != null && enclosingElement.isClass; |
105 } | 88 } |
| 89 |
106 bool get isInstanceMember => false; | 90 bool get isInstanceMember => false; |
107 bool get isDeferredLoaderGetter => false; | 91 bool get isDeferredLoaderGetter => false; |
108 | 92 |
109 bool get isConst => modifiers.isConst; | 93 bool get isConst => modifiers.isConst; |
110 bool get isFinal => modifiers.isFinal; | 94 bool get isFinal => modifiers.isFinal; |
111 bool get isStatic => modifiers.isStatic; | 95 bool get isStatic => modifiers.isStatic; |
112 bool get isOperator => Elements.isOperatorName(name); | 96 bool get isOperator => Elements.isOperatorName(name); |
113 | 97 |
114 bool get isSynthesized => false; | 98 bool get isSynthesized => false; |
115 | 99 |
(...skipping 21 matching lines...) Expand all Loading... |
137 if (position == null) return null; | 121 if (position == null) return null; |
138 Uri uri = compilationUnit.script.resourceUri; | 122 Uri uri = compilationUnit.script.resourceUri; |
139 return new SourceSpan( | 123 return new SourceSpan( |
140 uri, position.charOffset, position.charOffset + position.charCount); | 124 uri, position.charOffset, position.charOffset + position.charCount); |
141 } | 125 } |
142 | 126 |
143 Token findMyName(Token token) { | 127 Token findMyName(Token token) { |
144 return findNameToken(token, isConstructor, name, enclosingElement.name); | 128 return findNameToken(token, isConstructor, name, enclosingElement.name); |
145 } | 129 } |
146 | 130 |
147 static Token findNameToken(Token token, bool isConstructor, String name, | 131 static Token findNameToken( |
148 String enclosingClassName) { | 132 Token token, bool isConstructor, String name, String enclosingClassName) { |
149 // We search for the token that has the name of this element. | 133 // We search for the token that has the name of this element. |
150 // For constructors, that doesn't work because they may have | 134 // For constructors, that doesn't work because they may have |
151 // named formed out of multiple tokens (named constructors) so | 135 // named formed out of multiple tokens (named constructors) so |
152 // for those we search for the class name instead. | 136 // for those we search for the class name instead. |
153 String needle = isConstructor ? enclosingClassName : name; | 137 String needle = isConstructor ? enclosingClassName : name; |
154 // The unary '-' operator has a special element name (specified). | 138 // The unary '-' operator has a special element name (specified). |
155 if (needle == 'unary-') needle = '-'; | 139 if (needle == 'unary-') needle = '-'; |
156 for (Token t = token; Tokens.EOF_TOKEN != t.kind; t = t.next) { | 140 for (Token t = token; Tokens.EOF_TOKEN != t.kind; t = t.next) { |
157 if (t is !ErrorToken && needle == t.value) return t; | 141 if (t is! ErrorToken && needle == t.value) return t; |
158 } | 142 } |
159 return token; | 143 return token; |
160 } | 144 } |
161 | 145 |
162 CompilationUnitElement get compilationUnit { | 146 CompilationUnitElement get compilationUnit { |
163 Element element = this; | 147 Element element = this; |
164 while (!element.isCompilationUnit) { | 148 while (!element.isCompilationUnit) { |
165 element = element.enclosingElement; | 149 element = element.enclosingElement; |
166 } | 150 } |
167 return element; | 151 return element; |
(...skipping 12 matching lines...) Expand all Loading... |
180 } | 164 } |
181 | 165 |
182 ClassElement get enclosingClass { | 166 ClassElement get enclosingClass { |
183 for (Element e = this; e != null; e = e.enclosingElement) { | 167 for (Element e = this; e != null; e = e.enclosingElement) { |
184 if (e.isClass) return e; | 168 if (e.isClass) return e; |
185 } | 169 } |
186 return null; | 170 return null; |
187 } | 171 } |
188 | 172 |
189 Element get enclosingClassOrCompilationUnit { | 173 Element get enclosingClassOrCompilationUnit { |
190 for (Element e = this; e != null; e = e.enclosingElement) { | 174 for (Element e = this; e != null; e = e.enclosingElement) { |
191 if (e.isClass || e.isCompilationUnit) return e; | 175 if (e.isClass || e.isCompilationUnit) return e; |
192 } | 176 } |
193 return null; | 177 return null; |
194 } | 178 } |
195 | 179 |
196 Element get outermostEnclosingMemberOrTopLevel { | 180 Element get outermostEnclosingMemberOrTopLevel { |
197 // TODO(lrn): Why is this called "Outermost"? | 181 // TODO(lrn): Why is this called "Outermost"? |
198 // TODO(johnniwinther): Clean up this method: This method does not return | 182 // TODO(johnniwinther): Clean up this method: This method does not return |
199 // the outermost for elements in closure classses, but some call-sites rely | 183 // the outermost for elements in closure classses, but some call-sites rely |
200 // on that behavior. | 184 // on that behavior. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 | 227 |
244 void reuseElement() { | 228 void reuseElement() { |
245 throw "reuseElement isn't implemented on ${runtimeType}."; | 229 throw "reuseElement isn't implemented on ${runtimeType}."; |
246 } | 230 } |
247 } | 231 } |
248 | 232 |
249 class ErroneousElementX extends ElementX implements ErroneousElement { | 233 class ErroneousElementX extends ElementX implements ErroneousElement { |
250 final MessageKind messageKind; | 234 final MessageKind messageKind; |
251 final Map messageArguments; | 235 final Map messageArguments; |
252 | 236 |
253 ErroneousElementX(this.messageKind, this.messageArguments, | 237 ErroneousElementX( |
254 String name, Element enclosing) | 238 this.messageKind, this.messageArguments, String name, Element enclosing) |
255 : super(name, ElementKind.ERROR, enclosing); | 239 : super(name, ElementKind.ERROR, enclosing); |
256 | 240 |
257 bool get isTopLevel => false; | 241 bool get isTopLevel => false; |
258 | 242 |
259 bool get isSynthesized => true; | 243 bool get isSynthesized => true; |
260 | 244 |
261 bool get isCyclicRedirection => false; | 245 bool get isCyclicRedirection => false; |
262 | 246 |
263 bool get isMalformed => true; | 247 bool get isMalformed => true; |
264 | 248 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 get effectiveTarget => this; | 283 get effectiveTarget => this; |
300 | 284 |
301 computeEffectiveTargetType(InterfaceType newType) => unsupported(); | 285 computeEffectiveTargetType(InterfaceType newType) => unsupported(); |
302 | 286 |
303 get definingConstructor => null; | 287 get definingConstructor => null; |
304 | 288 |
305 FunctionElement asFunctionElement() => this; | 289 FunctionElement asFunctionElement() => this; |
306 | 290 |
307 String get message { | 291 String get message { |
308 return MessageTemplate.TEMPLATES[messageKind] | 292 return MessageTemplate.TEMPLATES[messageKind] |
309 .message(messageArguments).toString(); | 293 .message(messageArguments) |
| 294 .toString(); |
310 } | 295 } |
311 | 296 |
312 String toString() => '<$name: $message>'; | 297 String toString() => '<$name: $message>'; |
313 | 298 |
314 accept(ElementVisitor visitor, arg) { | 299 accept(ElementVisitor visitor, arg) { |
315 return visitor.visitErroneousElement(this, arg); | 300 return visitor.visitErroneousElement(this, arg); |
316 } | 301 } |
317 | 302 |
318 @override | 303 @override |
319 get isEffectiveTargetMalformed { | 304 get isEffectiveTargetMalformed { |
320 throw new UnsupportedError("isEffectiveTargetMalformed"); | 305 throw new UnsupportedError("isEffectiveTargetMalformed"); |
321 } | 306 } |
322 | 307 |
323 @override | 308 @override |
324 bool get isFromEnvironmentConstructor => false; | 309 bool get isFromEnvironmentConstructor => false; |
325 } | 310 } |
326 | 311 |
327 /// A constructor that was synthesized to recover from a compile-time error. | 312 /// A constructor that was synthesized to recover from a compile-time error. |
328 class ErroneousConstructorElementX extends ErroneousElementX | 313 class ErroneousConstructorElementX extends ErroneousElementX |
329 with PatchMixin<FunctionElement>, | 314 with |
330 AnalyzableElementX, | 315 PatchMixin<FunctionElement>, |
331 ConstantConstructorMixin | 316 AnalyzableElementX, |
| 317 ConstantConstructorMixin |
332 implements ConstructorElementX { | 318 implements ConstructorElementX { |
333 // TODO(ahe): Instead of subclassing [ErroneousElementX], this class should | 319 // TODO(ahe): Instead of subclassing [ErroneousElementX], this class should |
334 // be more like [ErroneousFieldElementX]. In particular, its kind should be | 320 // be more like [ErroneousFieldElementX]. In particular, its kind should be |
335 // [ElementKind.GENERATIVE_CONSTRUCTOR], and it shouldn't throw as much. | 321 // [ElementKind.GENERATIVE_CONSTRUCTOR], and it shouldn't throw as much. |
336 | 322 |
337 ErroneousConstructorElementX( | 323 ErroneousConstructorElementX(MessageKind messageKind, Map messageArguments, |
338 MessageKind messageKind, | 324 String name, Element enclosing) |
339 Map messageArguments, | |
340 String name, | |
341 Element enclosing) | |
342 : super(messageKind, messageArguments, name, enclosing); | 325 : super(messageKind, messageArguments, name, enclosing); |
343 | 326 |
344 @override | 327 @override |
345 bool get isRedirectingGenerative => false; | 328 bool get isRedirectingGenerative => false; |
346 | 329 |
347 @override | 330 @override |
348 void set isRedirectingGenerative(_) { | 331 void set isRedirectingGenerative(_) { |
349 throw new UnsupportedError("isRedirectingGenerative"); | 332 throw new UnsupportedError("isRedirectingGenerative"); |
350 } | 333 } |
351 | 334 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 set _isEffectiveTargetMalformed(_) { | 384 set _isEffectiveTargetMalformed(_) { |
402 throw new UnsupportedError("_isEffectiveTargetMalformed="); | 385 throw new UnsupportedError("_isEffectiveTargetMalformed="); |
403 } | 386 } |
404 | 387 |
405 @override | 388 @override |
406 get isEffectiveTargetMalformed { | 389 get isEffectiveTargetMalformed { |
407 throw new UnsupportedError("isEffectiveTargetMalformed"); | 390 throw new UnsupportedError("isEffectiveTargetMalformed"); |
408 } | 391 } |
409 | 392 |
410 @override | 393 @override |
411 void setEffectiveTarget(ConstructorElement target, | 394 void setEffectiveTarget(ConstructorElement target, InterfaceType type, |
412 InterfaceType type, | 395 {bool isMalformed: false}) { |
413 {bool isMalformed: false}) { | |
414 throw new UnsupportedError("setEffectiveTarget"); | 396 throw new UnsupportedError("setEffectiveTarget"); |
415 } | 397 } |
416 | 398 |
417 @override | 399 @override |
418 void _computeSignature(Resolution resolution) { | 400 void _computeSignature(Resolution resolution) { |
419 throw new UnsupportedError("_computeSignature"); | 401 throw new UnsupportedError("_computeSignature"); |
420 } | 402 } |
421 | 403 |
422 @override | 404 @override |
423 get typeCache { | 405 get typeCache { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 /// Warning to report on resolving this element. | 475 /// Warning to report on resolving this element. |
494 final WrappedMessage warning; | 476 final WrappedMessage warning; |
495 | 477 |
496 /// Info to report on resolving this element. | 478 /// Info to report on resolving this element. |
497 final WrappedMessage info; | 479 final WrappedMessage info; |
498 | 480 |
499 /// The element whose usage cause a warning. | 481 /// The element whose usage cause a warning. |
500 final Element wrappedElement; | 482 final Element wrappedElement; |
501 | 483 |
502 WarnOnUseElementX(WrappedMessage this.warning, WrappedMessage this.info, | 484 WarnOnUseElementX(WrappedMessage this.warning, WrappedMessage this.info, |
503 Element enclosingElement, Element wrappedElement) | 485 Element enclosingElement, Element wrappedElement) |
504 : this.wrappedElement = wrappedElement, | 486 : this.wrappedElement = wrappedElement, |
505 super(wrappedElement.name, ElementKind.WARN_ON_USE, enclosingElement); | 487 super(wrappedElement.name, ElementKind.WARN_ON_USE, enclosingElement); |
506 | 488 |
507 Element unwrap(DiagnosticReporter reporter, Spannable usageSpannable) { | 489 Element unwrap(DiagnosticReporter reporter, Spannable usageSpannable) { |
508 var unwrapped = wrappedElement; | 490 var unwrapped = wrappedElement; |
509 if (warning != null) { | 491 if (warning != null) { |
510 Spannable spannable = warning.spannable; | 492 Spannable spannable = warning.spannable; |
511 if (spannable == null) spannable = usageSpannable; | 493 if (spannable == null) spannable = usageSpannable; |
512 DiagnosticMessage warningMessage = reporter.createMessage( | 494 DiagnosticMessage warningMessage = reporter.createMessage( |
513 spannable, warning.messageKind, warning.messageArguments); | 495 spannable, warning.messageKind, warning.messageArguments); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 var set = new Setlet(); | 545 var set = new Setlet(); |
564 while (element.isAmbiguous) { | 546 while (element.isAmbiguous) { |
565 AmbiguousElement ambiguous = element; | 547 AmbiguousElement ambiguous = element; |
566 set.add(ambiguous.newElement); | 548 set.add(ambiguous.newElement); |
567 element = ambiguous.existingElement; | 549 element = ambiguous.existingElement; |
568 } | 550 } |
569 set.add(element); | 551 set.add(element); |
570 return set; | 552 return set; |
571 } | 553 } |
572 | 554 |
573 List<DiagnosticMessage> computeInfos(Element context, | 555 List<DiagnosticMessage> computeInfos( |
574 DiagnosticReporter reporter) { | 556 Element context, DiagnosticReporter reporter) { |
575 return const <DiagnosticMessage>[]; | 557 return const <DiagnosticMessage>[]; |
576 } | 558 } |
577 | 559 |
578 accept(ElementVisitor visitor, arg) { | 560 accept(ElementVisitor visitor, arg) { |
579 return visitor.visitAmbiguousElement(this, arg); | 561 return visitor.visitAmbiguousElement(this, arg); |
580 } | 562 } |
581 | 563 |
582 bool get isTopLevel => false; | 564 bool get isTopLevel => false; |
583 | 565 |
584 DynamicType get type => const DynamicType(); | 566 DynamicType get type => const DynamicType(); |
585 } | 567 } |
586 | 568 |
587 /// Element synthesized to diagnose an ambiguous import. | 569 /// Element synthesized to diagnose an ambiguous import. |
588 class AmbiguousImportX extends AmbiguousElementX { | 570 class AmbiguousImportX extends AmbiguousElementX { |
589 AmbiguousImportX( | 571 AmbiguousImportX(MessageKind messageKind, Map messageArguments, |
590 MessageKind messageKind, | |
591 Map messageArguments, | |
592 Element enclosingElement, Element existingElement, Element newElement) | 572 Element enclosingElement, Element existingElement, Element newElement) |
593 : super(messageKind, messageArguments, enclosingElement, existingElement, | 573 : super(messageKind, messageArguments, enclosingElement, existingElement, |
594 newElement); | 574 newElement); |
595 | 575 |
596 List<DiagnosticMessage> computeInfos( | 576 List<DiagnosticMessage> computeInfos( |
597 Element context, | 577 Element context, DiagnosticReporter reporter) { |
598 DiagnosticReporter reporter) { | |
599 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; | 578 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
600 Setlet ambiguousElements = flatten(); | 579 Setlet ambiguousElements = flatten(); |
601 MessageKind code = (ambiguousElements.length == 1) | 580 MessageKind code = (ambiguousElements.length == 1) |
602 ? MessageKind.AMBIGUOUS_REEXPORT : MessageKind.AMBIGUOUS_LOCATION; | 581 ? MessageKind.AMBIGUOUS_REEXPORT |
| 582 : MessageKind.AMBIGUOUS_LOCATION; |
603 LibraryElementX importer = context.library; | 583 LibraryElementX importer = context.library; |
604 for (Element element in ambiguousElements) { | 584 for (Element element in ambiguousElements) { |
605 Map arguments = {'name': element.name}; | 585 Map arguments = {'name': element.name}; |
606 infos.add(reporter.createMessage(element, code, arguments)); | 586 infos.add(reporter.createMessage(element, code, arguments)); |
607 reporter.withCurrentElement(importer, () { | 587 reporter.withCurrentElement(importer, () { |
608 for (ImportElement import in importer.importers.getImports(element)) { | 588 for (ImportElement import in importer.importers.getImports(element)) { |
609 infos.add(reporter.createMessage( | 589 infos.add(reporter.createMessage( |
610 import, MessageKind.IMPORTED_HERE, arguments)); | 590 import, MessageKind.IMPORTED_HERE, arguments)); |
611 } | 591 } |
612 }); | 592 }); |
613 } | 593 } |
614 return infos; | 594 return infos; |
615 } | 595 } |
616 } | 596 } |
617 | 597 |
618 /// Element synthesized to recover from a duplicated member of an element. | 598 /// Element synthesized to recover from a duplicated member of an element. |
619 class DuplicatedElementX extends AmbiguousElementX { | 599 class DuplicatedElementX extends AmbiguousElementX { |
620 DuplicatedElementX( | 600 DuplicatedElementX(MessageKind messageKind, Map messageArguments, |
621 MessageKind messageKind, | |
622 Map messageArguments, | |
623 Element enclosingElement, Element existingElement, Element newElement) | 601 Element enclosingElement, Element existingElement, Element newElement) |
624 : super(messageKind, messageArguments, enclosingElement, existingElement, | 602 : super(messageKind, messageArguments, enclosingElement, existingElement, |
625 newElement); | 603 newElement); |
626 | 604 |
627 bool get isMalformed => true; | 605 bool get isMalformed => true; |
628 } | 606 } |
629 | 607 |
630 class ScopeX { | 608 class ScopeX { |
631 final Map<String, Element> contents = new Map<String, Element>(); | 609 final Map<String, Element> contents = new Map<String, Element>(); |
632 | 610 |
633 bool get isEmpty => contents.isEmpty; | 611 bool get isEmpty => contents.isEmpty; |
634 Iterable<Element> get values => contents.values; | 612 Iterable<Element> get values => contents.values; |
635 | 613 |
636 Element lookup(String name) { | 614 Element lookup(String name) { |
637 return contents[name]; | 615 return contents[name]; |
638 } | 616 } |
639 | 617 |
640 void add(Element element, DiagnosticReporter reporter) { | 618 void add(Element element, DiagnosticReporter reporter) { |
641 String name = element.name; | 619 String name = element.name; |
642 if (element.isAccessor) { | 620 if (element.isAccessor) { |
643 addAccessor(element, contents[name], reporter); | 621 addAccessor(element, contents[name], reporter); |
644 } else { | 622 } else { |
645 Element existing = contents.putIfAbsent(name, () => element); | 623 Element existing = contents.putIfAbsent(name, () => element); |
646 if (!identical(existing, element)) { | 624 if (!identical(existing, element)) { |
647 reporter.reportError( | 625 reporter.reportError( |
648 reporter.createMessage( | 626 reporter.createMessage( |
649 element, | 627 element, MessageKind.DUPLICATE_DEFINITION, {'name': name}), |
650 MessageKind.DUPLICATE_DEFINITION, | |
651 {'name': name}), | |
652 <DiagnosticMessage>[ | 628 <DiagnosticMessage>[ |
653 reporter.createMessage( | 629 reporter.createMessage( |
654 existing, | 630 existing, MessageKind.EXISTING_DEFINITION, {'name': name}), |
655 MessageKind.EXISTING_DEFINITION, | |
656 {'name': name}), | |
657 ]); | 631 ]); |
658 } | 632 } |
659 } | 633 } |
660 } | 634 } |
661 | 635 |
662 /** | 636 /** |
663 * Adds a definition for an [accessor] (getter or setter) to a scope. | 637 * Adds a definition for an [accessor] (getter or setter) to a scope. |
664 * The definition binds to an abstract field that can hold both a getter | 638 * The definition binds to an abstract field that can hold both a getter |
665 * and a setter. | 639 * and a setter. |
666 * | 640 * |
667 * The abstract field is added once, for the first getter or setter, and | 641 * The abstract field is added once, for the first getter or setter, and |
668 * reused if the other one is also added. | 642 * reused if the other one is also added. |
669 * The abstract field should not be treated as a proper member of the | 643 * The abstract field should not be treated as a proper member of the |
670 * container, it's simply a way to return two results for one lookup. | 644 * container, it's simply a way to return two results for one lookup. |
671 * That is, the getter or setter does not have the abstract field as enclosing | 645 * That is, the getter or setter does not have the abstract field as enclosing |
672 * element, they are enclosed by the class or compilation unit, as is the | 646 * element, they are enclosed by the class or compilation unit, as is the |
673 * abstract field. | 647 * abstract field. |
674 */ | 648 */ |
675 void addAccessor(AccessorElementX accessor, | 649 void addAccessor(AccessorElementX accessor, Element existing, |
676 Element existing, | 650 DiagnosticReporter reporter) { |
677 DiagnosticReporter reporter) { | |
678 void reportError(Element other) { | 651 void reportError(Element other) { |
679 reporter.reportError( | 652 reporter.reportError( |
680 reporter.createMessage( | 653 reporter.createMessage(accessor, MessageKind.DUPLICATE_DEFINITION, |
681 accessor, | |
682 MessageKind.DUPLICATE_DEFINITION, | |
683 {'name': accessor.name}), | 654 {'name': accessor.name}), |
684 <DiagnosticMessage>[ | 655 <DiagnosticMessage>[ |
685 reporter.createMessage( | 656 reporter.createMessage(other, MessageKind.EXISTING_DEFINITION, |
686 other, | 657 {'name': accessor.name}), |
687 MessageKind.EXISTING_DEFINITION, | |
688 {'name': accessor.name}), | |
689 ]); | 658 ]); |
690 | 659 |
691 contents[accessor.name] = new DuplicatedElementX( | 660 contents[accessor.name] = new DuplicatedElementX( |
692 MessageKind.DUPLICATE_DEFINITION, {'name': accessor.name}, | 661 MessageKind.DUPLICATE_DEFINITION, |
693 accessor.memberContext.enclosingElement, other, accessor); | 662 {'name': accessor.name}, |
| 663 accessor.memberContext.enclosingElement, |
| 664 other, |
| 665 accessor); |
694 } | 666 } |
695 | 667 |
696 if (existing != null) { | 668 if (existing != null) { |
697 if (!identical(existing.kind, ElementKind.ABSTRACT_FIELD)) { | 669 if (!identical(existing.kind, ElementKind.ABSTRACT_FIELD)) { |
698 reportError(existing); | 670 reportError(existing); |
699 return; | 671 return; |
700 } else { | 672 } else { |
701 AbstractFieldElementX field = existing; | 673 AbstractFieldElementX field = existing; |
702 accessor.abstractField = field; | 674 accessor.abstractField = field; |
703 if (accessor.isGetter) { | 675 if (accessor.isGetter) { |
(...skipping 27 matching lines...) Expand all Loading... |
731 } | 703 } |
732 | 704 |
733 class CompilationUnitElementX extends ElementX | 705 class CompilationUnitElementX extends ElementX |
734 with CompilationUnitElementCommon | 706 with CompilationUnitElementCommon |
735 implements CompilationUnitElement { | 707 implements CompilationUnitElement { |
736 final Script script; | 708 final Script script; |
737 PartOf partTag; | 709 PartOf partTag; |
738 Link<Element> localMembers = const Link<Element>(); | 710 Link<Element> localMembers = const Link<Element>(); |
739 | 711 |
740 CompilationUnitElementX(Script script, LibraryElementX library) | 712 CompilationUnitElementX(Script script, LibraryElementX library) |
741 : this.script = script, | 713 : this.script = script, |
742 super(script.name, | 714 super(script.name, ElementKind.COMPILATION_UNIT, library) { |
743 ElementKind.COMPILATION_UNIT, | |
744 library) { | |
745 library.addCompilationUnit(this); | 715 library.addCompilationUnit(this); |
746 } | 716 } |
747 | 717 |
748 @override | 718 @override |
749 LibraryElementX get library => enclosingElement.declaration; | 719 LibraryElementX get library => enclosingElement.declaration; |
750 | 720 |
751 void set metadata(List<MetadataAnnotation> metadata) { | 721 void set metadata(List<MetadataAnnotation> metadata) { |
752 for (MetadataAnnotationX annotation in metadata) { | 722 for (MetadataAnnotationX annotation in metadata) { |
753 assert(annotation.annotatedElement == null); | 723 assert(annotation.annotatedElement == null); |
754 annotation.annotatedElement = this; | 724 annotation.annotatedElement = this; |
(...skipping 23 matching lines...) Expand all Loading... |
778 | 748 |
779 void setPartOf(PartOf tag, DiagnosticReporter reporter) { | 749 void setPartOf(PartOf tag, DiagnosticReporter reporter) { |
780 LibraryElementX library = enclosingElement; | 750 LibraryElementX library = enclosingElement; |
781 if (library.entryCompilationUnit == this) { | 751 if (library.entryCompilationUnit == this) { |
782 // This compilation unit is loaded as a library. The error is reported by | 752 // This compilation unit is loaded as a library. The error is reported by |
783 // the library loader. | 753 // the library loader. |
784 partTag = tag; | 754 partTag = tag; |
785 return; | 755 return; |
786 } | 756 } |
787 if (!localMembers.isEmpty) { | 757 if (!localMembers.isEmpty) { |
788 reporter.reportErrorMessage( | 758 reporter.reportErrorMessage(tag, MessageKind.BEFORE_TOP_LEVEL); |
789 tag, MessageKind.BEFORE_TOP_LEVEL); | |
790 return; | 759 return; |
791 } | 760 } |
792 if (partTag != null) { | 761 if (partTag != null) { |
793 reporter.reportWarningMessage(tag, MessageKind.DUPLICATED_PART_OF); | 762 reporter.reportWarningMessage(tag, MessageKind.DUPLICATED_PART_OF); |
794 return; | 763 return; |
795 } | 764 } |
796 partTag = tag; | 765 partTag = tag; |
797 LibraryName libraryTag = library.libraryTag; | 766 LibraryName libraryTag = library.libraryTag; |
798 String actualName = tag.name.toString(); | 767 String actualName = tag.name.toString(); |
799 if (libraryTag != null) { | 768 if (libraryTag != null) { |
800 String expectedName = libraryTag.name.toString(); | 769 String expectedName = libraryTag.name.toString(); |
801 if (expectedName != actualName) { | 770 if (expectedName != actualName) { |
802 reporter.reportWarningMessage( | 771 reporter.reportWarningMessage(tag.name, |
803 tag.name, | 772 MessageKind.LIBRARY_NAME_MISMATCH, {'libraryName': expectedName}); |
804 MessageKind.LIBRARY_NAME_MISMATCH, | |
805 {'libraryName': expectedName}); | |
806 } | 773 } |
807 } else { | 774 } else { |
808 reporter.reportWarning( | 775 reporter.reportWarning( |
809 reporter.createMessage( | 776 reporter.createMessage(library, MessageKind.MISSING_LIBRARY_NAME, |
810 library, | |
811 MessageKind.MISSING_LIBRARY_NAME, | |
812 {'libraryName': actualName}), | 777 {'libraryName': actualName}), |
813 <DiagnosticMessage>[ | 778 <DiagnosticMessage>[ |
814 reporter.createMessage( | 779 reporter.createMessage( |
815 tag.name, | 780 tag.name, MessageKind.THIS_IS_THE_PART_OF_TAG), |
816 MessageKind.THIS_IS_THE_PART_OF_TAG), | |
817 ]); | 781 ]); |
818 } | 782 } |
819 } | 783 } |
820 | 784 |
821 bool get hasMembers => !localMembers.isEmpty; | 785 bool get hasMembers => !localMembers.isEmpty; |
822 | 786 |
823 Element get analyzableElement => library; | 787 Element get analyzableElement => library; |
824 | 788 |
825 accept(ElementVisitor visitor, arg) { | 789 accept(ElementVisitor visitor, arg) { |
826 return visitor.visitCompilationUnitElement(this, arg); | 790 return visitor.visitCompilationUnitElement(this, arg); |
(...skipping 23 matching lines...) Expand all Loading... |
850 } | 814 } |
851 } | 815 } |
852 | 816 |
853 class ImportScope { | 817 class ImportScope { |
854 /** | 818 /** |
855 * Map for elements imported through import declarations. | 819 * Map for elements imported through import declarations. |
856 * | 820 * |
857 * Addition to the map is performed by [addImport]. Lookup is done trough | 821 * Addition to the map is performed by [addImport]. Lookup is done trough |
858 * [find]. | 822 * [find]. |
859 */ | 823 */ |
860 final Map<String, Element> importScope = | 824 final Map<String, Element> importScope = new Map<String, Element>(); |
861 new Map<String, Element>(); | |
862 | 825 |
863 /** | 826 /** |
864 * Adds [element] to the import scope of this library. | 827 * Adds [element] to the import scope of this library. |
865 * | 828 * |
866 * If an element by the same name is already in the imported scope, an | 829 * If an element by the same name is already in the imported scope, an |
867 * [ErroneousElement] will be put in the imported scope, allowing for | 830 * [ErroneousElement] will be put in the imported scope, allowing for |
868 * detection of ambiguous uses of imported names. | 831 * detection of ambiguous uses of imported names. |
869 */ | 832 */ |
870 void addImport(Element enclosingElement, | 833 void addImport(Element enclosingElement, Element element, |
871 Element element, | 834 ImportElement import, DiagnosticReporter reporter) { |
872 ImportElement import, | |
873 DiagnosticReporter reporter) { | |
874 LibraryElementX library = enclosingElement.library; | 835 LibraryElementX library = enclosingElement.library; |
875 Importers importers = library.importers; | 836 Importers importers = library.importers; |
876 | 837 |
877 String name = element.name; | 838 String name = element.name; |
878 | 839 |
879 // The loadLibrary function always shadows existing bindings to that name. | 840 // The loadLibrary function always shadows existing bindings to that name. |
880 if (element.isDeferredLoaderGetter) { | 841 if (element.isDeferredLoaderGetter) { |
881 importScope.remove(name); | 842 importScope.remove(name); |
882 // TODO(sigurdm): Print a hint. | 843 // TODO(sigurdm): Print a hint. |
883 } | 844 } |
884 Element existing = importScope.putIfAbsent(name, () => element); | 845 Element existing = importScope.putIfAbsent(name, () => element); |
885 importers.registerImport(element, import); | 846 importers.registerImport(element, import); |
886 | 847 |
887 void registerWarnOnUseElement(ImportElement import, | 848 void registerWarnOnUseElement(ImportElement import, MessageKind messageKind, |
888 MessageKind messageKind, | 849 Element hidingElement, Element hiddenElement) { |
889 Element hidingElement, | |
890 Element hiddenElement) { | |
891 Uri hiddenUri = hiddenElement.library.canonicalUri; | 850 Uri hiddenUri = hiddenElement.library.canonicalUri; |
892 Uri hidingUri = hidingElement.library.canonicalUri; | 851 Uri hidingUri = hidingElement.library.canonicalUri; |
893 Element element = new WarnOnUseElementX( | 852 Element element = new WarnOnUseElementX( |
894 new WrappedMessage( | 853 new WrappedMessage( |
895 null, // Report on reference to [hidingElement]. | 854 null, // Report on reference to [hidingElement]. |
896 messageKind, | 855 messageKind, |
897 {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}), | 856 {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}), |
898 new WrappedMessage( | 857 new WrappedMessage(reporter.spanFromSpannable(import), |
899 reporter.spanFromSpannable(import), | 858 MessageKind.IMPORTED_HERE, {'name': name}), |
900 MessageKind.IMPORTED_HERE, | 859 enclosingElement, |
901 {'name': name}), | 860 hidingElement); |
902 enclosingElement, hidingElement); | |
903 importScope[name] = element; | 861 importScope[name] = element; |
904 importers.registerImport(element, import); | 862 importers.registerImport(element, import); |
905 } | 863 } |
906 | 864 |
907 if (existing != element) { | 865 if (existing != element) { |
908 ImportElement existingImport = importers.getImport(existing); | 866 ImportElement existingImport = importers.getImport(existing); |
909 if (existing.library.isPlatformLibrary && | 867 if (existing.library.isPlatformLibrary && |
910 !element.library.isPlatformLibrary) { | 868 !element.library.isPlatformLibrary) { |
911 // [existing] is implicitly hidden. | 869 // [existing] is implicitly hidden. |
912 registerWarnOnUseElement( | 870 registerWarnOnUseElement( |
913 import, MessageKind.HIDDEN_IMPORT, element, existing); | 871 import, MessageKind.HIDDEN_IMPORT, element, existing); |
914 } else if (!existing.library.isPlatformLibrary && | 872 } else if (!existing.library.isPlatformLibrary && |
915 element.library.isPlatformLibrary) { | 873 element.library.isPlatformLibrary) { |
916 // [element] is implicitly hidden. | 874 // [element] is implicitly hidden. |
917 if (import.isSynthesized) { | 875 if (import.isSynthesized) { |
918 // [element] is imported implicitly (probably through dart:core). | 876 // [element] is imported implicitly (probably through dart:core). |
919 registerWarnOnUseElement( | 877 registerWarnOnUseElement(existingImport, |
920 existingImport, MessageKind.HIDDEN_IMPLICIT_IMPORT, | 878 MessageKind.HIDDEN_IMPLICIT_IMPORT, existing, element); |
921 existing, element); | |
922 } else { | 879 } else { |
923 registerWarnOnUseElement( | 880 registerWarnOnUseElement( |
924 import, MessageKind.HIDDEN_IMPORT, existing, element); | 881 import, MessageKind.HIDDEN_IMPORT, existing, element); |
925 } | 882 } |
926 } else { | 883 } else { |
927 Element ambiguousElement = new AmbiguousImportX( | 884 Element ambiguousElement = new AmbiguousImportX( |
928 MessageKind.DUPLICATE_IMPORT, {'name': name}, | 885 MessageKind.DUPLICATE_IMPORT, |
929 enclosingElement, existing, element); | 886 {'name': name}, |
| 887 enclosingElement, |
| 888 existing, |
| 889 element); |
930 importScope[name] = ambiguousElement; | 890 importScope[name] = ambiguousElement; |
931 importers.registerImport(ambiguousElement, import); | 891 importers.registerImport(ambiguousElement, import); |
932 importers.registerImport(ambiguousElement, existingImport); | 892 importers.registerImport(ambiguousElement, existingImport); |
933 } | 893 } |
934 } | 894 } |
935 } | 895 } |
936 | 896 |
937 Element operator [](String name) => importScope[name]; | 897 Element operator [](String name) => importScope[name]; |
938 | 898 |
939 void forEach(f(Element element)) => importScope.values.forEach(f); | 899 void forEach(f(Element element)) => importScope.values.forEach(f); |
940 } | 900 } |
941 | 901 |
942 abstract class LibraryDependencyElementX extends ElementX { | 902 abstract class LibraryDependencyElementX extends ElementX { |
943 final LibraryDependency node; | 903 final LibraryDependency node; |
944 final Uri uri; | 904 final Uri uri; |
945 LibraryElement libraryDependency; | 905 LibraryElement libraryDependency; |
946 | 906 |
947 LibraryDependencyElementX(CompilationUnitElement enclosingElement, | 907 LibraryDependencyElementX(CompilationUnitElement enclosingElement, |
948 ElementKind kind, | 908 ElementKind kind, this.node, this.uri) |
949 this.node, | |
950 this.uri) | |
951 : super('', kind, enclosingElement); | 909 : super('', kind, enclosingElement); |
952 | 910 |
953 @override | 911 @override |
954 List<MetadataAnnotation> get metadata => node.metadata; | 912 List<MetadataAnnotation> get metadata => node.metadata; |
955 | 913 |
956 void set metadata(value) { | 914 void set metadata(value) { |
957 // The metadata is stored on [libraryDependency]. | 915 // The metadata is stored on [libraryDependency]. |
958 throw new SpannableAssertionFailure( | 916 throw new SpannableAssertionFailure( |
959 this, 'Cannot set metadata on a import/export.'); | 917 this, 'Cannot set metadata on a import/export.'); |
960 } | 918 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 @override | 960 @override |
1003 bool get isDeferred => false; | 961 bool get isDeferred => false; |
1004 | 962 |
1005 @override | 963 @override |
1006 List<MetadataAnnotation> get metadata => const <MetadataAnnotation>[]; | 964 List<MetadataAnnotation> get metadata => const <MetadataAnnotation>[]; |
1007 | 965 |
1008 @override | 966 @override |
1009 SourceSpan get sourcePosition => library.sourcePosition; | 967 SourceSpan get sourcePosition => library.sourcePosition; |
1010 } | 968 } |
1011 | 969 |
1012 | |
1013 class ExportElementX extends LibraryDependencyElementX | 970 class ExportElementX extends LibraryDependencyElementX |
1014 implements ExportElement { | 971 implements ExportElement { |
1015 | |
1016 ExportElementX(CompilationUnitElement enclosingElement, Export node, Uri uri) | 972 ExportElementX(CompilationUnitElement enclosingElement, Export node, Uri uri) |
1017 : super(enclosingElement, ElementKind.EXPORT, node, uri); | 973 : super(enclosingElement, ElementKind.EXPORT, node, uri); |
1018 | 974 |
1019 Export get node => super.node; | 975 Export get node => super.node; |
1020 | 976 |
1021 @override | 977 @override |
1022 LibraryElement get exportedLibrary => libraryDependency; | 978 LibraryElement get exportedLibrary => libraryDependency; |
1023 | 979 |
1024 @override | 980 @override |
1025 accept(ElementVisitor visitor, arg) => visitor.visitExportElement(this, arg); | 981 accept(ElementVisitor visitor, arg) => visitor.visitExportElement(this, arg); |
1026 } | 982 } |
1027 | 983 |
1028 class LibraryElementX | 984 class LibraryElementX extends ElementX |
1029 extends ElementX | 985 with LibraryElementCommon, AnalyzableElementX, PatchMixin<LibraryElementX> |
1030 with LibraryElementCommon, | |
1031 AnalyzableElementX, | |
1032 PatchMixin<LibraryElementX> | |
1033 implements LibraryElement { | 986 implements LibraryElement { |
1034 final Uri canonicalUri; | 987 final Uri canonicalUri; |
1035 | 988 |
1036 /// True if the constructing script was synthesized. | 989 /// True if the constructing script was synthesized. |
1037 final bool isSynthesized; | 990 final bool isSynthesized; |
1038 | 991 |
1039 CompilationUnitElement entryCompilationUnit; | 992 CompilationUnitElement entryCompilationUnit; |
1040 Link<CompilationUnitElement> compilationUnits = | 993 Link<CompilationUnitElement> compilationUnits = |
1041 const Link<CompilationUnitElement>(); | 994 const Link<CompilationUnitElement>(); |
1042 LinkBuilder<LibraryTag> tagsBuilder = new LinkBuilder<LibraryTag>(); | 995 LinkBuilder<LibraryTag> tagsBuilder = new LinkBuilder<LibraryTag>(); |
(...skipping 15 matching lines...) Expand all Loading... |
1058 * library is loaded. | 1011 * library is loaded. |
1059 */ | 1012 */ |
1060 Link<Element> slotForExports; | 1013 Link<Element> slotForExports; |
1061 | 1014 |
1062 List<ImportElement> _imports = <ImportElement>[]; | 1015 List<ImportElement> _imports = <ImportElement>[]; |
1063 List<ExportElement> _exports = <ExportElement>[]; | 1016 List<ExportElement> _exports = <ExportElement>[]; |
1064 | 1017 |
1065 final Map<LibraryDependency, LibraryElement> tagMapping = | 1018 final Map<LibraryDependency, LibraryElement> tagMapping = |
1066 new Map<LibraryDependency, LibraryElement>(); | 1019 new Map<LibraryDependency, LibraryElement>(); |
1067 | 1020 |
1068 LibraryElementX(Script script, | 1021 LibraryElementX(Script script, [Uri canonicalUri, LibraryElementX origin]) |
1069 [Uri canonicalUri, LibraryElementX origin]) | 1022 : this.canonicalUri = |
1070 : this.canonicalUri = | 1023 ((canonicalUri == null) ? script.readableUri : canonicalUri), |
1071 ((canonicalUri == null) ? script.readableUri : canonicalUri), | 1024 this.isSynthesized = script.isSynthesized, |
1072 this.isSynthesized = script.isSynthesized, | 1025 super(script.name, ElementKind.LIBRARY, null) { |
1073 super(script.name, ElementKind.LIBRARY, null) { | |
1074 entryCompilationUnit = new CompilationUnitElementX(script, this); | 1026 entryCompilationUnit = new CompilationUnitElementX(script, this); |
1075 if (origin != null) { | 1027 if (origin != null) { |
1076 origin.applyPatch(this); | 1028 origin.applyPatch(this); |
1077 } | 1029 } |
1078 } | 1030 } |
1079 | 1031 |
1080 Iterable<MetadataAnnotation> get metadata { | 1032 Iterable<MetadataAnnotation> get metadata { |
1081 if (libraryTag != null) { | 1033 if (libraryTag != null) { |
1082 return libraryTag.metadata; | 1034 return libraryTag.metadata; |
1083 } | 1035 } |
1084 return const <MetadataAnnotation>[]; | 1036 return const <MetadataAnnotation>[]; |
1085 } | 1037 } |
1086 | 1038 |
1087 void set metadata(value) { | 1039 void set metadata(value) { |
1088 // The metadata is stored on [libraryTag]. | 1040 // The metadata is stored on [libraryTag]. |
1089 throw new SpannableAssertionFailure(this, 'Cannot set metadata on Library'); | 1041 throw new SpannableAssertionFailure(this, 'Cannot set metadata on Library'); |
1090 } | 1042 } |
1091 | 1043 |
1092 CompilationUnitElement get compilationUnit => entryCompilationUnit; | 1044 CompilationUnitElement get compilationUnit => entryCompilationUnit; |
1093 | 1045 |
1094 Element get analyzableElement => this; | 1046 Element get analyzableElement => this; |
1095 | 1047 |
1096 void addCompilationUnit(CompilationUnitElement element) { | 1048 void addCompilationUnit(CompilationUnitElement element) { |
1097 compilationUnits = compilationUnits.prepend(element); | 1049 compilationUnits = compilationUnits.prepend(element); |
1098 } | 1050 } |
1099 | 1051 |
1100 void addTag(LibraryTag tag, DiagnosticReporter reporter) { | 1052 void addTag(LibraryTag tag, DiagnosticReporter reporter) { |
1101 if (tagsCache != null) { | 1053 if (tagsCache != null) { |
1102 reporter.internalError(tag, | 1054 reporter.internalError( |
1103 "Library tags for $this have already been computed."); | 1055 tag, "Library tags for $this have already been computed."); |
1104 } | 1056 } |
1105 tagsBuilder.addLast(tag); | 1057 tagsBuilder.addLast(tag); |
1106 } | 1058 } |
1107 | 1059 |
1108 Iterable<LibraryTag> get tags { | 1060 Iterable<LibraryTag> get tags { |
1109 if (tagsCache == null) { | 1061 if (tagsCache == null) { |
1110 tagsCache = tagsBuilder.toList(); | 1062 tagsCache = tagsBuilder.toList(); |
1111 tagsBuilder = null; | 1063 tagsBuilder = null; |
1112 } | 1064 } |
1113 return tagsCache; | 1065 return tagsCache; |
(...skipping 11 matching lines...) Expand all Loading... |
1125 | 1077 |
1126 Iterable<ExportElement> get exports => _exports; | 1078 Iterable<ExportElement> get exports => _exports; |
1127 | 1079 |
1128 /** | 1080 /** |
1129 * Adds [element] to the import scope of this library. | 1081 * Adds [element] to the import scope of this library. |
1130 * | 1082 * |
1131 * If an element by the same name is already in the imported scope, an | 1083 * If an element by the same name is already in the imported scope, an |
1132 * [ErroneousElement] will be put in the imported scope, allowing for | 1084 * [ErroneousElement] will be put in the imported scope, allowing for |
1133 * detection of ambiguous uses of imported names. | 1085 * detection of ambiguous uses of imported names. |
1134 */ | 1086 */ |
1135 void addImport(Element element, | 1087 void addImport( |
1136 ImportElement import, | 1088 Element element, ImportElement import, DiagnosticReporter reporter) { |
1137 DiagnosticReporter reporter) { | |
1138 importScope.addImport(this, element, import, reporter); | 1089 importScope.addImport(this, element, import, reporter); |
1139 } | 1090 } |
1140 | 1091 |
1141 void addMember(Element element, DiagnosticReporter reporter) { | 1092 void addMember(Element element, DiagnosticReporter reporter) { |
1142 localMembers = localMembers.prepend(element); | 1093 localMembers = localMembers.prepend(element); |
1143 addToScope(element, reporter); | 1094 addToScope(element, reporter); |
1144 } | 1095 } |
1145 | 1096 |
1146 void addToScope(Element element, DiagnosticReporter reporter) { | 1097 void addToScope(Element element, DiagnosticReporter reporter) { |
1147 localScope.add(element, reporter); | 1098 localScope.add(element, reporter); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 // library? | 1157 // library? |
1207 Element result = localScope.lookup(elementName); | 1158 Element result = localScope.lookup(elementName); |
1208 if (result == null && isPatch) { | 1159 if (result == null && isPatch) { |
1209 return origin.findLocal(elementName); | 1160 return origin.findLocal(elementName); |
1210 } | 1161 } |
1211 return result; | 1162 return result; |
1212 } | 1163 } |
1213 | 1164 |
1214 Element findExported(String elementName) { | 1165 Element findExported(String elementName) { |
1215 assert(invariant(this, exportsHandled, | 1166 assert(invariant(this, exportsHandled, |
1216 message: 'Exports not handled on $this')); | 1167 message: 'Exports not handled on $this')); |
1217 for (Link link = slotForExports; !link.isEmpty; link = link.tail) { | 1168 for (Link link = slotForExports; !link.isEmpty; link = link.tail) { |
1218 Element element = link.head; | 1169 Element element = link.head; |
1219 if (element.name == elementName) return element; | 1170 if (element.name == elementName) return element; |
1220 } | 1171 } |
1221 return null; | 1172 return null; |
1222 } | 1173 } |
1223 | 1174 |
1224 void forEachExport(f(Element element)) { | 1175 void forEachExport(f(Element element)) { |
1225 assert(invariant(this, exportsHandled, | 1176 assert(invariant(this, exportsHandled, |
1226 message: 'Exports not handled on $this')); | 1177 message: 'Exports not handled on $this')); |
1227 slotForExports.forEach((Element e) => f(e)); | 1178 slotForExports.forEach((Element e) => f(e)); |
1228 } | 1179 } |
1229 | 1180 |
1230 Iterable<ImportElement> getImportsFor(Element element) { | 1181 Iterable<ImportElement> getImportsFor(Element element) { |
1231 return importers.getImports(element); | 1182 return importers.getImports(element); |
1232 } | 1183 } |
1233 | 1184 |
1234 void forEachImport(f(Element element)) => importScope.forEach(f); | 1185 void forEachImport(f(Element element)) => importScope.forEach(f); |
1235 | 1186 |
1236 void forEachLocalMember(f(Element element)) { | 1187 void forEachLocalMember(f(Element element)) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1299 class PrefixElementX extends ElementX implements PrefixElement { | 1250 class PrefixElementX extends ElementX implements PrefixElement { |
1300 Token firstPosition; | 1251 Token firstPosition; |
1301 | 1252 |
1302 final ImportScope importScope = new ImportScope(); | 1253 final ImportScope importScope = new ImportScope(); |
1303 | 1254 |
1304 bool get isDeferred => deferredImport != null; | 1255 bool get isDeferred => deferredImport != null; |
1305 | 1256 |
1306 // Only needed for deferred imports. | 1257 // Only needed for deferred imports. |
1307 final ImportElement deferredImport; | 1258 final ImportElement deferredImport; |
1308 | 1259 |
1309 PrefixElementX(String prefix, | 1260 PrefixElementX( |
1310 Element enclosing, | 1261 String prefix, Element enclosing, this.firstPosition, this.deferredImport) |
1311 this.firstPosition, | |
1312 this.deferredImport) | |
1313 : super(prefix, ElementKind.PREFIX, enclosing); | 1262 : super(prefix, ElementKind.PREFIX, enclosing); |
1314 | 1263 |
1315 bool get isTopLevel => false; | 1264 bool get isTopLevel => false; |
1316 | 1265 |
1317 Element lookupLocalMember(String memberName) => importScope[memberName]; | 1266 Element lookupLocalMember(String memberName) => importScope[memberName]; |
1318 | 1267 |
1319 DartType computeType(Resolution resolution) => const DynamicType(); | 1268 DartType computeType(Resolution resolution) => const DynamicType(); |
1320 | 1269 |
1321 Token get position => firstPosition; | 1270 Token get position => firstPosition; |
1322 | 1271 |
1323 void addImport(Element element, | 1272 void addImport( |
1324 ImportElement import, | 1273 Element element, ImportElement import, DiagnosticReporter reporter) { |
1325 DiagnosticReporter reporter) { | |
1326 importScope.addImport(this, element, import, reporter); | 1274 importScope.addImport(this, element, import, reporter); |
1327 } | 1275 } |
1328 | 1276 |
1329 accept(ElementVisitor visitor, arg) { | 1277 accept(ElementVisitor visitor, arg) { |
1330 return visitor.visitPrefixElement(this, arg); | 1278 return visitor.visitPrefixElement(this, arg); |
1331 } | 1279 } |
1332 | 1280 |
1333 String toString() => '$kind($name)'; | 1281 String toString() => '$kind($name)'; |
1334 } | 1282 } |
1335 | 1283 |
1336 class TypedefElementX extends ElementX | 1284 class TypedefElementX extends ElementX |
1337 with AstElementMixin, | 1285 with |
1338 AnalyzableElementX, | 1286 AstElementMixin, |
1339 TypeDeclarationElementX<TypedefType> | 1287 AnalyzableElementX, |
| 1288 TypeDeclarationElementX<TypedefType> |
1340 implements TypedefElement { | 1289 implements TypedefElement { |
1341 Typedef cachedNode; | 1290 Typedef cachedNode; |
1342 | 1291 |
1343 /** | 1292 /** |
1344 * The type annotation which defines this typedef. | 1293 * The type annotation which defines this typedef. |
1345 */ | 1294 */ |
1346 DartType aliasCache; | 1295 DartType aliasCache; |
1347 | 1296 |
1348 DartType get alias { | 1297 DartType get alias { |
1349 assert(invariant(this, hasBeenCheckedForCycles, | 1298 assert(invariant(this, hasBeenCheckedForCycles, |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1427 VariableList(Modifiers this.modifiers); | 1376 VariableList(Modifiers this.modifiers); |
1428 | 1377 |
1429 VariableList.node(VariableDefinitions node, this.type) | 1378 VariableList.node(VariableDefinitions node, this.type) |
1430 : this.definitions = node, | 1379 : this.definitions = node, |
1431 this.modifiers = node.modifiers { | 1380 this.modifiers = node.modifiers { |
1432 assert(modifiers != null); | 1381 assert(modifiers != null); |
1433 } | 1382 } |
1434 | 1383 |
1435 Iterable<MetadataAnnotation> get metadata { | 1384 Iterable<MetadataAnnotation> get metadata { |
1436 return metadataInternal != null | 1385 return metadataInternal != null |
1437 ? metadataInternal : const <MetadataAnnotation>[]; | 1386 ? metadataInternal |
| 1387 : const <MetadataAnnotation>[]; |
1438 } | 1388 } |
1439 | 1389 |
1440 void set metadata(List<MetadataAnnotation> metadata) { | 1390 void set metadata(List<MetadataAnnotation> metadata) { |
1441 if (metadata.isEmpty) { | 1391 if (metadata.isEmpty) { |
1442 // For a multi declaration like: | 1392 // For a multi declaration like: |
1443 // | 1393 // |
1444 // @foo @bar var a, b, c | 1394 // @foo @bar var a, b, c |
1445 // | 1395 // |
1446 // the metadata list is reported through the declaration of `a`, and `b` | 1396 // the metadata list is reported through the declaration of `a`, and `b` |
1447 // and `c` report an empty list of metadata. | 1397 // and `c` report an empty list of metadata. |
(...skipping 22 matching lines...) Expand all Loading... |
1470 message: "Constant has not been computed for $this.")); | 1420 message: "Constant has not been computed for $this.")); |
1471 return constantCache; | 1421 return constantCache; |
1472 } | 1422 } |
1473 | 1423 |
1474 void set constant(ConstantExpression value) { | 1424 void set constant(ConstantExpression value) { |
1475 if (isPatch) { | 1425 if (isPatch) { |
1476 ConstantVariableMixin originVariable = origin; | 1426 ConstantVariableMixin originVariable = origin; |
1477 originVariable.constant = value; | 1427 originVariable.constant = value; |
1478 return; | 1428 return; |
1479 } | 1429 } |
1480 assert(invariant( | 1430 assert(invariant(this, constantCache == null || constantCache == value, |
1481 this, constantCache == null || constantCache == value, | |
1482 message: "Constant has already been computed for $this. " | 1431 message: "Constant has already been computed for $this. " |
1483 "Existing constant: " | 1432 "Existing constant: " |
1484 "${constantCache != null ? constantCache.getText() : ''}, " | 1433 "${constantCache != null ? constantCache.getText() : ''}, " |
1485 "New constant: ${value != null ? value.getText() : ''}.")); | 1434 "New constant: ${value != null ? value.getText() : ''}.")); |
1486 constantCache = value; | 1435 constantCache = value; |
1487 } | 1436 } |
1488 } | 1437 } |
1489 | 1438 |
1490 abstract class VariableElementX extends ElementX | 1439 abstract class VariableElementX extends ElementX |
1491 with AstElementMixin, ConstantVariableMixin | 1440 with AstElementMixin, ConstantVariableMixin |
1492 implements VariableElement { | 1441 implements VariableElement { |
1493 final Token token; | 1442 final Token token; |
1494 final VariableList variables; | 1443 final VariableList variables; |
1495 VariableDefinitions definitionsCache; | 1444 VariableDefinitions definitionsCache; |
1496 Expression initializerCache; | 1445 Expression initializerCache; |
1497 | 1446 |
1498 Modifiers get modifiers => variables.modifiers; | 1447 Modifiers get modifiers => variables.modifiers; |
1499 | 1448 |
1500 VariableElementX(String name, | 1449 VariableElementX(String name, ElementKind kind, Element enclosingElement, |
1501 ElementKind kind, | 1450 VariableList variables, this.token) |
1502 Element enclosingElement, | 1451 : this.variables = variables, |
1503 VariableList variables, | 1452 super(name, kind, enclosingElement); |
1504 this.token) | |
1505 : this.variables = variables, | |
1506 super(name, kind, enclosingElement); | |
1507 | 1453 |
1508 // TODO(johnniwinther): Ensure that the [TreeElements] for this variable hold | 1454 // TODO(johnniwinther): Ensure that the [TreeElements] for this variable hold |
1509 // the mappings for all its metadata. | 1455 // the mappings for all its metadata. |
1510 Iterable<MetadataAnnotation> get metadata => variables.metadata; | 1456 Iterable<MetadataAnnotation> get metadata => variables.metadata; |
1511 | 1457 |
1512 void set metadata(List<MetadataAnnotation> metadata) { | 1458 void set metadata(List<MetadataAnnotation> metadata) { |
1513 for (MetadataAnnotationX annotation in metadata) { | 1459 for (MetadataAnnotationX annotation in metadata) { |
1514 assert(annotation.annotatedElement == null); | 1460 assert(annotation.annotatedElement == null); |
1515 annotation.annotatedElement = this; | 1461 annotation.annotatedElement = this; |
1516 } | 1462 } |
(...skipping 24 matching lines...) Expand all Loading... |
1541 createDefinitions(definitions); | 1487 createDefinitions(definitions); |
1542 return definitionsCache; | 1488 return definitionsCache; |
1543 } | 1489 } |
1544 | 1490 |
1545 void createDefinitions(VariableDefinitions definitions) { | 1491 void createDefinitions(VariableDefinitions definitions) { |
1546 assert(invariant(this, definitionsCache == null, | 1492 assert(invariant(this, definitionsCache == null, |
1547 message: "VariableDefinitions has already been computed for $this.")); | 1493 message: "VariableDefinitions has already been computed for $this.")); |
1548 Expression node; | 1494 Expression node; |
1549 int count = 0; | 1495 int count = 0; |
1550 for (Link<Node> link = definitions.definitions.nodes; | 1496 for (Link<Node> link = definitions.definitions.nodes; |
1551 !link.isEmpty; link = link.tail) { | 1497 !link.isEmpty; |
| 1498 link = link.tail) { |
1552 Expression initializedIdentifier = link.head; | 1499 Expression initializedIdentifier = link.head; |
1553 Identifier identifier = initializedIdentifier.asIdentifier(); | 1500 Identifier identifier = initializedIdentifier.asIdentifier(); |
1554 if (identifier == null) { | 1501 if (identifier == null) { |
1555 SendSet sendSet = initializedIdentifier.asSendSet(); | 1502 SendSet sendSet = initializedIdentifier.asSendSet(); |
1556 identifier = sendSet.selector.asIdentifier(); | 1503 identifier = sendSet.selector.asIdentifier(); |
1557 if (identical(name, identifier.source)) { | 1504 if (identical(name, identifier.source)) { |
1558 node = initializedIdentifier; | 1505 node = initializedIdentifier; |
1559 initializerCache = sendSet.arguments.first; | 1506 initializerCache = sendSet.arguments.first; |
1560 } | 1507 } |
1561 } else if (identical(name, identifier.source)) { | 1508 } else if (identical(name, identifier.source)) { |
1562 node = initializedIdentifier; | 1509 node = initializedIdentifier; |
1563 } | 1510 } |
1564 count++; | 1511 count++; |
1565 } | 1512 } |
1566 invariant(definitions, node != null, message: "Could not find '$name'."); | 1513 invariant(definitions, node != null, message: "Could not find '$name'."); |
1567 if (count == 1) { | 1514 if (count == 1) { |
1568 definitionsCache = definitions; | 1515 definitionsCache = definitions; |
1569 } else { | 1516 } else { |
1570 // Create a [VariableDefinitions] node for the single definition of | 1517 // Create a [VariableDefinitions] node for the single definition of |
1571 // [node]. | 1518 // [node]. |
1572 definitionsCache = new VariableDefinitions(definitions.type, | 1519 definitionsCache = new VariableDefinitions( |
1573 definitions.modifiers, new NodeList( | 1520 definitions.type, |
| 1521 definitions.modifiers, |
| 1522 new NodeList( |
1574 definitions.definitions.beginToken, | 1523 definitions.definitions.beginToken, |
1575 const Link<Node>().prepend(node), | 1524 const Link<Node>().prepend(node), |
1576 definitions.definitions.endToken)); | 1525 definitions.definitions.endToken)); |
1577 } | 1526 } |
1578 } | 1527 } |
1579 | 1528 |
1580 DartType computeType(Resolution resolution) { | 1529 DartType computeType(Resolution resolution) { |
1581 if (variables.type != null) return variables.type; | 1530 if (variables.type != null) return variables.type; |
1582 // Call [parseNode] to ensure that [definitionsCache] and [initializerCache] | 1531 // Call [parseNode] to ensure that [definitionsCache] and [initializerCache] |
1583 // are set as a consequence of calling [computeType]. | 1532 // are set as a consequence of calling [computeType]. |
(...skipping 15 matching lines...) Expand all Loading... |
1599 | 1548 |
1600 accept(ElementVisitor visitor, arg) { | 1549 accept(ElementVisitor visitor, arg) { |
1601 return visitor.visitVariableElement(this, arg); | 1550 return visitor.visitVariableElement(this, arg); |
1602 } | 1551 } |
1603 | 1552 |
1604 DeclarationSite get declarationSite => variables; | 1553 DeclarationSite get declarationSite => variables; |
1605 } | 1554 } |
1606 | 1555 |
1607 class LocalVariableElementX extends VariableElementX | 1556 class LocalVariableElementX extends VariableElementX |
1608 implements LocalVariableElement { | 1557 implements LocalVariableElement { |
1609 LocalVariableElementX(String name, | 1558 LocalVariableElementX(String name, ExecutableElement enclosingElement, |
1610 ExecutableElement enclosingElement, | 1559 VariableList variables, Token token) |
1611 VariableList variables, | |
1612 Token token) | |
1613 : super(name, ElementKind.VARIABLE, enclosingElement, variables, token) { | 1560 : super(name, ElementKind.VARIABLE, enclosingElement, variables, token) { |
1614 createDefinitions(variables.definitions); | 1561 createDefinitions(variables.definitions); |
1615 } | 1562 } |
1616 | 1563 |
1617 ExecutableElement get executableContext => enclosingElement; | 1564 ExecutableElement get executableContext => enclosingElement; |
1618 | 1565 |
1619 MemberElement get memberContext => executableContext.memberContext; | 1566 MemberElement get memberContext => executableContext.memberContext; |
1620 | 1567 |
1621 bool get isLocal => true; | 1568 bool get isLocal => true; |
1622 } | 1569 } |
1623 | 1570 |
1624 class FieldElementX extends VariableElementX | 1571 class FieldElementX extends VariableElementX |
1625 with AnalyzableElementX implements FieldElement { | 1572 with AnalyzableElementX |
| 1573 implements FieldElement { |
1626 List<FunctionElement> nestedClosures = new List<FunctionElement>(); | 1574 List<FunctionElement> nestedClosures = new List<FunctionElement>(); |
1627 | 1575 |
1628 FieldElementX(Identifier name, | 1576 FieldElementX( |
1629 Element enclosingElement, | 1577 Identifier name, Element enclosingElement, VariableList variables) |
1630 VariableList variables) | 1578 : super(name.source, ElementKind.FIELD, enclosingElement, variables, |
1631 : super(name.source, ElementKind.FIELD, enclosingElement, | 1579 name.token); |
1632 variables, name.token); | |
1633 | 1580 |
1634 accept(ElementVisitor visitor, arg) { | 1581 accept(ElementVisitor visitor, arg) { |
1635 return visitor.visitFieldElement(this, arg); | 1582 return visitor.visitFieldElement(this, arg); |
1636 } | 1583 } |
1637 | 1584 |
1638 MemberElement get memberContext => this; | 1585 MemberElement get memberContext => this; |
1639 | 1586 |
1640 void reuseElement() { | 1587 void reuseElement() { |
1641 super.reuseElement(); | 1588 super.reuseElement(); |
1642 nestedClosures.clear(); | 1589 nestedClosures.clear(); |
1643 } | 1590 } |
1644 | 1591 |
1645 FieldElementX copyWithEnclosing(Element enclosingElement) { | 1592 FieldElementX copyWithEnclosing(Element enclosingElement) { |
1646 return new FieldElementX( | 1593 return new FieldElementX( |
1647 new Identifier(token), enclosingElement, variables); | 1594 new Identifier(token), enclosingElement, variables); |
1648 } | 1595 } |
1649 } | 1596 } |
1650 | 1597 |
1651 /// A field that was synthesized to recover from a compile-time error. | 1598 /// A field that was synthesized to recover from a compile-time error. |
1652 class ErroneousFieldElementX extends ElementX | 1599 class ErroneousFieldElementX extends ElementX |
1653 with ConstantVariableMixin implements FieldElementX { | 1600 with ConstantVariableMixin |
| 1601 implements FieldElementX { |
1654 final VariableList variables; | 1602 final VariableList variables; |
1655 | 1603 |
1656 ErroneousFieldElementX(Identifier name, Element enclosingElement) | 1604 ErroneousFieldElementX(Identifier name, Element enclosingElement) |
1657 : variables = new VariableList(Modifiers.EMPTY) | 1605 : variables = new VariableList(Modifiers.EMPTY) |
1658 ..definitions = new VariableDefinitions( | 1606 ..definitions = new VariableDefinitions( |
1659 null, Modifiers.EMPTY, new NodeList.singleton(name)) | 1607 null, Modifiers.EMPTY, new NodeList.singleton(name)) |
1660 ..type = const DynamicType(), | 1608 ..type = const DynamicType(), |
1661 super(name.source, ElementKind.FIELD, enclosingElement); | 1609 super(name.source, ElementKind.FIELD, enclosingElement); |
1662 | 1610 |
1663 VariableDefinitions get definitionsCache => variables.definitions; | 1611 VariableDefinitions get definitionsCache => variables.definitions; |
1664 | 1612 |
1665 set definitionsCache(VariableDefinitions _) { | 1613 set definitionsCache(VariableDefinitions _) { |
1666 throw new UnsupportedError("definitionsCache="); | 1614 throw new UnsupportedError("definitionsCache="); |
1667 } | 1615 } |
1668 | 1616 |
1669 bool get hasNode => true; | 1617 bool get hasNode => true; |
1670 | 1618 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1734 final Identifier identifier; | 1682 final Identifier identifier; |
1735 DartType typeCache; | 1683 DartType typeCache; |
1736 | 1684 |
1737 /** | 1685 /** |
1738 * Function signature for a variable with a function type. The signature is | 1686 * Function signature for a variable with a function type. The signature is |
1739 * kept to provide full information about parameter names through the mirror | 1687 * kept to provide full information about parameter names through the mirror |
1740 * system. | 1688 * system. |
1741 */ | 1689 */ |
1742 FunctionSignature _functionSignatureCache; | 1690 FunctionSignature _functionSignatureCache; |
1743 | 1691 |
1744 FormalElementX(ElementKind elementKind, | 1692 FormalElementX(ElementKind elementKind, FunctionTypedElement enclosingElement, |
1745 FunctionTypedElement enclosingElement, | 1693 this.definitions, Identifier identifier) |
1746 this.definitions, | |
1747 Identifier identifier) | |
1748 : this.identifier = identifier, | 1694 : this.identifier = identifier, |
1749 super(identifier.source, elementKind, enclosingElement); | 1695 super(identifier.source, elementKind, enclosingElement); |
1750 | 1696 |
1751 FunctionTypedElement get functionDeclaration => enclosingElement; | 1697 FunctionTypedElement get functionDeclaration => enclosingElement; |
1752 | 1698 |
1753 Modifiers get modifiers => definitions.modifiers; | 1699 Modifiers get modifiers => definitions.modifiers; |
1754 | 1700 |
1755 Token get position => identifier.getBeginToken(); | 1701 Token get position => identifier.getBeginToken(); |
1756 | 1702 |
1757 Node parseNode(Parsing parsing) => definitions; | 1703 Node parseNode(Parsing parsing) => definitions; |
1758 | 1704 |
1759 DartType computeType(Resolution resolution) { | 1705 DartType computeType(Resolution resolution) { |
1760 assert(invariant(this, type != null, | 1706 assert(invariant(this, type != null, |
1761 message: "Parameter type has not been set for $this.")); | 1707 message: "Parameter type has not been set for $this.")); |
1762 return type; | 1708 return type; |
1763 } | 1709 } |
1764 | 1710 |
1765 DartType get type { | 1711 DartType get type { |
1766 assert(invariant(this, typeCache != null, | 1712 assert(invariant(this, typeCache != null, |
1767 message: "Parameter type has not been set for $this.")); | 1713 message: "Parameter type has not been set for $this.")); |
1768 return typeCache; | 1714 return typeCache; |
1769 } | 1715 } |
1770 | 1716 |
1771 FunctionSignature get functionSignature { | 1717 FunctionSignature get functionSignature { |
1772 assert(invariant(this, _functionSignatureCache != null, | 1718 assert(invariant(this, _functionSignatureCache != null, |
1773 message: "Parameter signature has not been computed for $this.")); | 1719 message: "Parameter signature has not been computed for $this.")); |
1774 return _functionSignatureCache; | 1720 return _functionSignatureCache; |
1775 } | 1721 } |
1776 | 1722 |
1777 void set functionSignature(FunctionSignature value) { | 1723 void set functionSignature(FunctionSignature value) { |
1778 assert(invariant(this, _functionSignatureCache == null, | 1724 assert(invariant(this, _functionSignatureCache == null, |
(...skipping 16 matching lines...) Expand all Loading... |
1795 AstElement get definingElement => declaration; | 1741 AstElement get definingElement => declaration; |
1796 } | 1742 } |
1797 | 1743 |
1798 /// [Element] for a formal parameter. | 1744 /// [Element] for a formal parameter. |
1799 /// | 1745 /// |
1800 /// A [ParameterElementX] can be patched. A parameter of an external method is | 1746 /// A [ParameterElementX] can be patched. A parameter of an external method is |
1801 /// patched with the corresponding parameter of the patch method. This is done | 1747 /// patched with the corresponding parameter of the patch method. This is done |
1802 /// to ensure that default values on parameters are computed once (on the | 1748 /// to ensure that default values on parameters are computed once (on the |
1803 /// origin parameter) but can be found through both the origin and the patch. | 1749 /// origin parameter) but can be found through both the origin and the patch. |
1804 abstract class ParameterElementX extends FormalElementX | 1750 abstract class ParameterElementX extends FormalElementX |
1805 with PatchMixin<ParameterElement>, | 1751 with PatchMixin<ParameterElement>, ConstantVariableMixin |
1806 ConstantVariableMixin | |
1807 implements ParameterElement { | 1752 implements ParameterElement { |
1808 final Expression initializer; | 1753 final Expression initializer; |
1809 final bool isOptional; | 1754 final bool isOptional; |
1810 final bool isNamed; | 1755 final bool isNamed; |
1811 | 1756 |
1812 ParameterElementX(ElementKind elementKind, | 1757 ParameterElementX( |
1813 FunctionElement functionDeclaration, | 1758 ElementKind elementKind, |
1814 VariableDefinitions definitions, | 1759 FunctionElement functionDeclaration, |
1815 Identifier identifier, | 1760 VariableDefinitions definitions, |
1816 this.initializer, | 1761 Identifier identifier, |
1817 {this.isOptional: false, | 1762 this.initializer, |
1818 this.isNamed: false}) | 1763 {this.isOptional: false, |
| 1764 this.isNamed: false}) |
1819 : super(elementKind, functionDeclaration, definitions, identifier); | 1765 : super(elementKind, functionDeclaration, definitions, identifier); |
1820 | 1766 |
1821 FunctionElement get functionDeclaration => enclosingElement; | 1767 FunctionElement get functionDeclaration => enclosingElement; |
1822 | 1768 |
1823 ExecutableElement get executableContext => enclosingElement; | 1769 ExecutableElement get executableContext => enclosingElement; |
1824 | 1770 |
1825 MemberElement get memberContext => executableContext.memberContext; | 1771 MemberElement get memberContext => executableContext.memberContext; |
1826 | 1772 |
1827 accept(ElementVisitor visitor, arg) { | 1773 accept(ElementVisitor visitor, arg) { |
1828 return visitor.visitParameterElement(this, arg); | 1774 return visitor.visitParameterElement(this, arg); |
1829 } | 1775 } |
1830 | 1776 |
1831 bool get isLocal => true; | 1777 bool get isLocal => true; |
1832 | 1778 |
1833 String toString() { | 1779 String toString() { |
1834 if (isPatched) { | 1780 if (isPatched) { |
1835 return 'origin ${super.toString()}'; | 1781 return 'origin ${super.toString()}'; |
1836 } else if (isPatch) { | 1782 } else if (isPatch) { |
1837 return 'patch ${super.toString()}'; | 1783 return 'patch ${super.toString()}'; |
1838 } | 1784 } |
1839 return super.toString(); | 1785 return super.toString(); |
1840 } | 1786 } |
1841 } | 1787 } |
1842 | 1788 |
1843 class LocalParameterElementX extends ParameterElementX | 1789 class LocalParameterElementX extends ParameterElementX |
1844 implements LocalParameterElement { | 1790 implements LocalParameterElement { |
1845 | 1791 LocalParameterElementX( |
1846 | 1792 FunctionElement functionDeclaration, |
1847 LocalParameterElementX(FunctionElement functionDeclaration, | 1793 VariableDefinitions definitions, |
1848 VariableDefinitions definitions, | 1794 Identifier identifier, |
1849 Identifier identifier, | 1795 Expression initializer, |
1850 Expression initializer, | 1796 {bool isOptional: false, |
1851 {bool isOptional: false, | 1797 bool isNamed: false}) |
1852 bool isNamed: false}) | 1798 : super(ElementKind.PARAMETER, functionDeclaration, definitions, |
1853 : super(ElementKind.PARAMETER, functionDeclaration, | 1799 identifier, initializer, |
1854 definitions, identifier, initializer, | 1800 isOptional: isOptional, isNamed: isNamed); |
1855 isOptional: isOptional, isNamed: isNamed); | |
1856 } | 1801 } |
1857 | 1802 |
1858 /// Parameters in constructors that directly initialize fields. For example: | 1803 /// Parameters in constructors that directly initialize fields. For example: |
1859 /// `A(this.field)`. | 1804 /// `A(this.field)`. |
1860 class InitializingFormalElementX extends ParameterElementX | 1805 class InitializingFormalElementX extends ParameterElementX |
1861 implements InitializingFormalElement { | 1806 implements InitializingFormalElement { |
1862 final FieldElement fieldElement; | 1807 final FieldElement fieldElement; |
1863 | 1808 |
1864 InitializingFormalElementX(ConstructorElement constructorDeclaration, | 1809 InitializingFormalElementX( |
1865 VariableDefinitions variables, | 1810 ConstructorElement constructorDeclaration, |
1866 Identifier identifier, | 1811 VariableDefinitions variables, |
1867 Expression initializer, | 1812 Identifier identifier, |
1868 this.fieldElement, | 1813 Expression initializer, |
1869 {bool isOptional: false, | 1814 this.fieldElement, |
1870 bool isNamed: false}) | 1815 {bool isOptional: false, |
| 1816 bool isNamed: false}) |
1871 : super(ElementKind.INITIALIZING_FORMAL, constructorDeclaration, | 1817 : super(ElementKind.INITIALIZING_FORMAL, constructorDeclaration, |
1872 variables, identifier, initializer, | 1818 variables, identifier, initializer, |
1873 isOptional: isOptional, isNamed: isNamed); | 1819 isOptional: isOptional, isNamed: isNamed); |
1874 | 1820 |
1875 accept(ElementVisitor visitor, arg) { | 1821 accept(ElementVisitor visitor, arg) { |
1876 return visitor.visitFieldParameterElement(this, arg); | 1822 return visitor.visitFieldParameterElement(this, arg); |
1877 } | 1823 } |
1878 | 1824 |
1879 MemberElement get memberContext => enclosingElement; | 1825 MemberElement get memberContext => enclosingElement; |
1880 | 1826 |
1881 bool get isLocal => false; | 1827 bool get isLocal => false; |
1882 } | 1828 } |
1883 | 1829 |
1884 class ErroneousInitializingFormalElementX extends ParameterElementX | 1830 class ErroneousInitializingFormalElementX extends ParameterElementX |
1885 implements InitializingFormalElementX { | 1831 implements InitializingFormalElementX { |
1886 final ErroneousFieldElementX fieldElement; | 1832 final ErroneousFieldElementX fieldElement; |
1887 | 1833 |
1888 ErroneousInitializingFormalElementX( | 1834 ErroneousInitializingFormalElementX( |
1889 Identifier identifier, | 1835 Identifier identifier, Element enclosingElement) |
1890 Element enclosingElement) | |
1891 : this.fieldElement = | 1836 : this.fieldElement = |
1892 new ErroneousFieldElementX(identifier, enclosingElement), | 1837 new ErroneousFieldElementX(identifier, enclosingElement), |
1893 super( | 1838 super(ElementKind.INITIALIZING_FORMAL, enclosingElement, null, |
1894 ElementKind.INITIALIZING_FORMAL, | 1839 identifier, null); |
1895 enclosingElement, null, identifier, null); | |
1896 | 1840 |
1897 VariableDefinitions get definitions => fieldElement.node; | 1841 VariableDefinitions get definitions => fieldElement.node; |
1898 | 1842 |
1899 MemberElement get memberContext => enclosingElement; | 1843 MemberElement get memberContext => enclosingElement; |
1900 | 1844 |
1901 bool get isLocal => false; | 1845 bool get isLocal => false; |
1902 | 1846 |
1903 bool get isMalformed => true; | 1847 bool get isMalformed => true; |
1904 | 1848 |
1905 DynamicType get type => const DynamicType(); | 1849 DynamicType get type => const DynamicType(); |
(...skipping 17 matching lines...) Expand all Loading... |
1923 Token get position { | 1867 Token get position { |
1924 // The getter and setter may be defined in two different | 1868 // The getter and setter may be defined in two different |
1925 // compilation units. However, we know that one of them is | 1869 // compilation units. However, we know that one of them is |
1926 // non-null and defined in the same compilation unit as the | 1870 // non-null and defined in the same compilation unit as the |
1927 // abstract element. | 1871 // abstract element. |
1928 // TODO(lrn): No we don't know that if the element from the same | 1872 // TODO(lrn): No we don't know that if the element from the same |
1929 // compilation unit is patched. | 1873 // compilation unit is patched. |
1930 // | 1874 // |
1931 // We need to make sure that the position returned is relative to | 1875 // We need to make sure that the position returned is relative to |
1932 // the compilation unit of the abstract element. | 1876 // the compilation unit of the abstract element. |
1933 if (getter != null | 1877 if (getter != null && identical(getter.compilationUnit, compilationUnit)) { |
1934 && identical(getter.compilationUnit, compilationUnit)) { | |
1935 return getter.position; | 1878 return getter.position; |
1936 } else { | 1879 } else { |
1937 return setter.position; | 1880 return setter.position; |
1938 } | 1881 } |
1939 } | 1882 } |
1940 | 1883 |
1941 Modifiers get modifiers { | 1884 Modifiers get modifiers { |
1942 // The resolver ensures that the flags match (ignoring abstract). | 1885 // The resolver ensures that the flags match (ignoring abstract). |
1943 if (getter != null) { | 1886 if (getter != null) { |
1944 return new Modifiers.withFlags( | 1887 return new Modifiers.withFlags(getter.modifiers.nodes, |
1945 getter.modifiers.nodes, | |
1946 getter.modifiers.flags | Modifiers.FLAG_ABSTRACT); | 1888 getter.modifiers.flags | Modifiers.FLAG_ABSTRACT); |
1947 } else { | 1889 } else { |
1948 return new Modifiers.withFlags( | 1890 return new Modifiers.withFlags(setter.modifiers.nodes, |
1949 setter.modifiers.nodes, | |
1950 setter.modifiers.flags | Modifiers.FLAG_ABSTRACT); | 1891 setter.modifiers.flags | Modifiers.FLAG_ABSTRACT); |
1951 } | 1892 } |
1952 } | 1893 } |
1953 | 1894 |
1954 bool get isInstanceMember { | 1895 bool get isInstanceMember { |
1955 return isClassMember && !isStatic; | 1896 return isClassMember && !isStatic; |
1956 } | 1897 } |
1957 | 1898 |
1958 accept(ElementVisitor visitor, arg) { | 1899 accept(ElementVisitor visitor, arg) { |
1959 return visitor.visitAbstractFieldElement(this, arg); | 1900 return visitor.visitAbstractFieldElement(this, arg); |
1960 } | 1901 } |
1961 | 1902 |
1962 bool get isAbstract { | 1903 bool get isAbstract { |
1963 return getter != null && getter.isAbstract | 1904 return getter != null && getter.isAbstract || |
1964 || setter != null && setter.isAbstract; | 1905 setter != null && setter.isAbstract; |
1965 } | 1906 } |
1966 } | 1907 } |
1967 | 1908 |
1968 // TODO(johnniwinther): [FunctionSignature] should be merged with | 1909 // TODO(johnniwinther): [FunctionSignature] should be merged with |
1969 // [FunctionType]. | 1910 // [FunctionType]. |
1970 // TODO(karlklose): all these lists should have element type [FormalElement]. | 1911 // TODO(karlklose): all these lists should have element type [FormalElement]. |
1971 class FunctionSignatureX extends FunctionSignatureCommon | 1912 class FunctionSignatureX extends FunctionSignatureCommon |
1972 implements FunctionSignature { | 1913 implements FunctionSignature { |
1973 final List<Element> requiredParameters; | 1914 final List<Element> requiredParameters; |
1974 final List<Element> optionalParameters; | 1915 final List<Element> optionalParameters; |
1975 final int requiredParameterCount; | 1916 final int requiredParameterCount; |
1976 final int optionalParameterCount; | 1917 final int optionalParameterCount; |
1977 final bool optionalParametersAreNamed; | 1918 final bool optionalParametersAreNamed; |
1978 final List<Element> orderedOptionalParameters; | 1919 final List<Element> orderedOptionalParameters; |
1979 final FunctionType type; | 1920 final FunctionType type; |
1980 final bool hasOptionalParameters; | 1921 final bool hasOptionalParameters; |
1981 | 1922 |
1982 FunctionSignatureX({this.requiredParameters: const <Element>[], | 1923 FunctionSignatureX( |
1983 this.requiredParameterCount: 0, | 1924 {this.requiredParameters: const <Element>[], |
1984 List<Element> optionalParameters: const <Element>[], | 1925 this.requiredParameterCount: 0, |
1985 this.optionalParameterCount: 0, | 1926 List<Element> optionalParameters: const <Element>[], |
1986 this.optionalParametersAreNamed: false, | 1927 this.optionalParameterCount: 0, |
1987 this.orderedOptionalParameters: const <Element>[], | 1928 this.optionalParametersAreNamed: false, |
1988 this.type}) | 1929 this.orderedOptionalParameters: const <Element>[], |
| 1930 this.type}) |
1989 : optionalParameters = optionalParameters, | 1931 : optionalParameters = optionalParameters, |
1990 hasOptionalParameters = !optionalParameters.isEmpty; | 1932 hasOptionalParameters = !optionalParameters.isEmpty; |
1991 } | 1933 } |
1992 | 1934 |
1993 abstract class BaseFunctionElementX | 1935 abstract class BaseFunctionElementX extends ElementX |
1994 extends ElementX with PatchMixin<FunctionElement>, AstElementMixin | 1936 with PatchMixin<FunctionElement>, AstElementMixin |
1995 implements FunctionElement { | 1937 implements FunctionElement { |
1996 DartType typeCache; | 1938 DartType typeCache; |
1997 final Modifiers modifiers; | 1939 final Modifiers modifiers; |
1998 | 1940 |
1999 List<FunctionElement> nestedClosures = new List<FunctionElement>(); | 1941 List<FunctionElement> nestedClosures = new List<FunctionElement>(); |
2000 | 1942 |
2001 FunctionSignature _functionSignatureCache; | 1943 FunctionSignature _functionSignatureCache; |
2002 | 1944 |
2003 AsyncMarker asyncMarker = AsyncMarker.SYNC; | 1945 AsyncMarker asyncMarker = AsyncMarker.SYNC; |
2004 | 1946 |
2005 BaseFunctionElementX(String name, | 1947 BaseFunctionElementX(String name, ElementKind kind, Modifiers this.modifiers, |
2006 ElementKind kind, | 1948 Element enclosing) |
2007 Modifiers this.modifiers, | |
2008 Element enclosing) | |
2009 : super(name, kind, enclosing) { | 1949 : super(name, kind, enclosing) { |
2010 assert(modifiers != null); | 1950 assert(modifiers != null); |
2011 } | 1951 } |
2012 | 1952 |
2013 bool get isExternal => modifiers.isExternal; | 1953 bool get isExternal => modifiers.isExternal; |
2014 | 1954 |
2015 bool get isInstanceMember { | 1955 bool get isInstanceMember { |
2016 return isClassMember | 1956 return isClassMember && !isConstructor && !isStatic; |
2017 && !isConstructor | |
2018 && !isStatic; | |
2019 } | 1957 } |
2020 | 1958 |
2021 bool get hasFunctionSignature => _functionSignatureCache != null; | 1959 bool get hasFunctionSignature => _functionSignatureCache != null; |
2022 | 1960 |
2023 void _computeSignature(Resolution resolution) { | 1961 void _computeSignature(Resolution resolution) { |
2024 if (hasFunctionSignature) return; | 1962 if (hasFunctionSignature) return; |
2025 functionSignature = resolution.resolveSignature(this); | 1963 functionSignature = resolution.resolveSignature(this); |
2026 } | 1964 } |
2027 | 1965 |
2028 FunctionSignature get functionSignature { | 1966 FunctionSignature get functionSignature { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2074 } | 2012 } |
2075 } | 2013 } |
2076 | 2014 |
2077 bool get isAbstract => false; | 2015 bool get isAbstract => false; |
2078 | 2016 |
2079 // A function is defined by the implementation element. | 2017 // A function is defined by the implementation element. |
2080 AstElement get definingElement => implementation; | 2018 AstElement get definingElement => implementation; |
2081 } | 2019 } |
2082 | 2020 |
2083 abstract class FunctionElementX extends BaseFunctionElementX | 2021 abstract class FunctionElementX extends BaseFunctionElementX |
2084 with AnalyzableElementX implements MethodElement { | 2022 with AnalyzableElementX |
2085 | 2023 implements MethodElement { |
2086 FunctionElementX(String name, | 2024 FunctionElementX( |
2087 ElementKind kind, | 2025 String name, ElementKind kind, Modifiers modifiers, Element enclosing) |
2088 Modifiers modifiers, | |
2089 Element enclosing) | |
2090 : super(name, kind, modifiers, enclosing); | 2026 : super(name, kind, modifiers, enclosing); |
2091 | 2027 |
2092 MemberElement get memberContext => this; | 2028 MemberElement get memberContext => this; |
2093 | 2029 |
2094 @override | 2030 @override |
2095 SourceSpan get sourcePosition { | 2031 SourceSpan get sourcePosition { |
2096 SourceSpan span = super.sourcePosition; | 2032 SourceSpan span = super.sourcePosition; |
2097 if (span != null && hasNode) { | 2033 if (span != null && hasNode) { |
2098 FunctionExpression functionExpression = node.asFunctionExpression(); | 2034 FunctionExpression functionExpression = node.asFunctionExpression(); |
2099 if (functionExpression != null) { | 2035 if (functionExpression != null) { |
2100 span = new SourceSpan.fromNode(span.uri, functionExpression); | 2036 span = new SourceSpan.fromNode(span.uri, functionExpression); |
2101 } | 2037 } |
2102 } | 2038 } |
2103 return span; | 2039 return span; |
2104 } | 2040 } |
2105 | 2041 |
2106 void reuseElement() { | 2042 void reuseElement() { |
2107 super.reuseElement(); | 2043 super.reuseElement(); |
2108 nestedClosures.clear(); | 2044 nestedClosures.clear(); |
2109 _functionSignatureCache = null; | 2045 _functionSignatureCache = null; |
2110 typeCache = null; | 2046 typeCache = null; |
2111 } | 2047 } |
2112 } | 2048 } |
2113 | 2049 |
2114 abstract class MethodElementX extends FunctionElementX { | 2050 abstract class MethodElementX extends FunctionElementX { |
2115 final bool hasBody; | 2051 final bool hasBody; |
2116 | 2052 |
2117 MethodElementX(String name, | 2053 MethodElementX( |
2118 ElementKind kind, | 2054 String name, |
2119 Modifiers modifiers, | 2055 ElementKind kind, |
2120 Element enclosing, | 2056 Modifiers modifiers, |
2121 // TODO(15101): Make this a named parameter. | 2057 Element enclosing, |
2122 this.hasBody) | 2058 // TODO(15101): Make this a named parameter. |
| 2059 this.hasBody) |
2123 : super(name, kind, modifiers, enclosing); | 2060 : super(name, kind, modifiers, enclosing); |
2124 | 2061 |
2125 @override | 2062 @override |
2126 bool get isAbstract { | 2063 bool get isAbstract { |
2127 return !modifiers.isExternal && !hasBody; | 2064 return !modifiers.isExternal && !hasBody; |
2128 } | 2065 } |
2129 | 2066 |
2130 accept(ElementVisitor visitor, arg) { | 2067 accept(ElementVisitor visitor, arg) { |
2131 return visitor.visitMethodElement(this, arg); | 2068 return visitor.visitMethodElement(this, arg); |
2132 } | 2069 } |
2133 } | 2070 } |
2134 | 2071 |
2135 abstract class AccessorElementX extends MethodElementX | 2072 abstract class AccessorElementX extends MethodElementX |
2136 implements AccessorElement { | 2073 implements AccessorElement { |
2137 AbstractFieldElement abstractField; | 2074 AbstractFieldElement abstractField; |
2138 | 2075 |
2139 AccessorElementX(String name, | 2076 AccessorElementX(String name, ElementKind kind, Modifiers modifiers, |
2140 ElementKind kind, | 2077 Element enclosing, bool hasBody) |
2141 Modifiers modifiers, | |
2142 Element enclosing, | |
2143 bool hasBody) | |
2144 : super(name, kind, modifiers, enclosing, hasBody); | 2078 : super(name, kind, modifiers, enclosing, hasBody); |
2145 } | 2079 } |
2146 | 2080 |
2147 abstract class GetterElementX extends AccessorElementX | 2081 abstract class GetterElementX extends AccessorElementX |
2148 implements GetterElement { | 2082 implements GetterElement { |
2149 | 2083 GetterElementX( |
2150 GetterElementX(String name, | 2084 String name, Modifiers modifiers, Element enclosing, bool hasBody) |
2151 Modifiers modifiers, | |
2152 Element enclosing, | |
2153 bool hasBody) | |
2154 : super(name, ElementKind.GETTER, modifiers, enclosing, hasBody); | 2085 : super(name, ElementKind.GETTER, modifiers, enclosing, hasBody); |
2155 | 2086 |
2156 accept(ElementVisitor visitor, arg) { | 2087 accept(ElementVisitor visitor, arg) { |
2157 return visitor.visitGetterElement(this, arg); | 2088 return visitor.visitGetterElement(this, arg); |
2158 } | 2089 } |
2159 } | 2090 } |
2160 | 2091 |
2161 abstract class SetterElementX extends AccessorElementX | 2092 abstract class SetterElementX extends AccessorElementX |
2162 implements SetterElement { | 2093 implements SetterElement { |
2163 | 2094 SetterElementX( |
2164 SetterElementX(String name, | 2095 String name, Modifiers modifiers, Element enclosing, bool hasBody) |
2165 Modifiers modifiers, | |
2166 Element enclosing, | |
2167 bool hasBody) | |
2168 : super(name, ElementKind.SETTER, modifiers, enclosing, hasBody); | 2096 : super(name, ElementKind.SETTER, modifiers, enclosing, hasBody); |
2169 | 2097 |
2170 accept(ElementVisitor visitor, arg) { | 2098 accept(ElementVisitor visitor, arg) { |
2171 return visitor.visitSetterElement(this, arg); | 2099 return visitor.visitSetterElement(this, arg); |
2172 } | 2100 } |
2173 } | 2101 } |
2174 | 2102 |
2175 class LocalFunctionElementX extends BaseFunctionElementX | 2103 class LocalFunctionElementX extends BaseFunctionElementX |
2176 implements LocalFunctionElement { | 2104 implements LocalFunctionElement { |
2177 final FunctionExpression node; | 2105 final FunctionExpression node; |
2178 | 2106 |
2179 LocalFunctionElementX(String name, | 2107 LocalFunctionElementX(String name, FunctionExpression this.node, |
2180 FunctionExpression this.node, | 2108 ElementKind kind, Modifiers modifiers, ExecutableElement enclosing) |
2181 ElementKind kind, | |
2182 Modifiers modifiers, | |
2183 ExecutableElement enclosing) | |
2184 : super(name, kind, modifiers, enclosing); | 2109 : super(name, kind, modifiers, enclosing); |
2185 | 2110 |
2186 ExecutableElement get executableContext => enclosingElement; | 2111 ExecutableElement get executableContext => enclosingElement; |
2187 | 2112 |
2188 MemberElement get memberContext => executableContext.memberContext; | 2113 MemberElement get memberContext => executableContext.memberContext; |
2189 | 2114 |
2190 bool get hasNode => true; | 2115 bool get hasNode => true; |
2191 | 2116 |
2192 FunctionExpression parseNode(Parsing parsing) => node; | 2117 FunctionExpression parseNode(Parsing parsing) => node; |
2193 | 2118 |
(...skipping 28 matching lines...) Expand all Loading... |
2222 return _constantConstructor; | 2147 return _constantConstructor; |
2223 } | 2148 } |
2224 | 2149 |
2225 void set constantConstructor(ConstantConstructor value) { | 2150 void set constantConstructor(ConstantConstructor value) { |
2226 if (isPatch) { | 2151 if (isPatch) { |
2227 ConstantConstructorMixin originConstructor = origin; | 2152 ConstantConstructorMixin originConstructor = origin; |
2228 originConstructor.constantConstructor = value; | 2153 originConstructor.constantConstructor = value; |
2229 } else { | 2154 } else { |
2230 assert(invariant(this, isConst, | 2155 assert(invariant(this, isConst, |
2231 message: "Constant constructor set on non-constant " | 2156 message: "Constant constructor set on non-constant " |
2232 "constructor $this.")); | 2157 "constructor $this.")); |
2233 assert(invariant(this, !isFromEnvironmentConstructor, | 2158 assert(invariant(this, !isFromEnvironmentConstructor, |
2234 message: "Constant constructor set on fromEnvironment " | 2159 message: "Constant constructor set on fromEnvironment " |
2235 "constructor: $this.")); | 2160 "constructor: $this.")); |
2236 assert(invariant(this, | 2161 assert(invariant( |
2237 _constantConstructor == null || _constantConstructor == value, | 2162 this, _constantConstructor == null || _constantConstructor == value, |
2238 message: "Constant constructor already computed for $this:" | 2163 message: "Constant constructor already computed for $this:" |
2239 "Existing: $_constantConstructor, new: $value")); | 2164 "Existing: $_constantConstructor, new: $value")); |
2240 _constantConstructor = value; | 2165 _constantConstructor = value; |
2241 } | 2166 } |
2242 } | 2167 } |
2243 | 2168 |
2244 bool get isFromEnvironmentConstructor { | 2169 bool get isFromEnvironmentConstructor { |
2245 return name == 'fromEnvironment' && | 2170 return name == 'fromEnvironment' && |
2246 library.isDartCore && | 2171 library.isDartCore && |
2247 (enclosingClass.name == 'bool' || | 2172 (enclosingClass.name == 'bool' || |
2248 enclosingClass.name == 'int' || | 2173 enclosingClass.name == 'int' || |
2249 enclosingClass.name == 'String'); | 2174 enclosingClass.name == 'String'); |
2250 } | 2175 } |
2251 } | 2176 } |
2252 | 2177 |
2253 abstract class ConstructorElementX extends FunctionElementX | 2178 abstract class ConstructorElementX extends FunctionElementX |
2254 with ConstantConstructorMixin implements ConstructorElement { | 2179 with ConstantConstructorMixin |
| 2180 implements ConstructorElement { |
2255 bool isRedirectingGenerative = false; | 2181 bool isRedirectingGenerative = false; |
2256 | 2182 |
2257 ConstructorElementX(String name, | 2183 ConstructorElementX( |
2258 ElementKind kind, | 2184 String name, ElementKind kind, Modifiers modifiers, Element enclosing) |
2259 Modifiers modifiers, | 2185 : super(name, kind, modifiers, enclosing); |
2260 Element enclosing) | |
2261 : super(name, kind, modifiers, enclosing); | |
2262 | 2186 |
2263 FunctionElement immediateRedirectionTarget; | 2187 FunctionElement immediateRedirectionTarget; |
2264 PrefixElement redirectionDeferredPrefix; | 2188 PrefixElement redirectionDeferredPrefix; |
2265 | 2189 |
2266 bool get isRedirectingFactory => immediateRedirectionTarget != null; | 2190 bool get isRedirectingFactory => immediateRedirectionTarget != null; |
2267 | 2191 |
2268 // TODO(johnniwinther): This should also return true for cyclic redirecting | 2192 // TODO(johnniwinther): This should also return true for cyclic redirecting |
2269 // generative constructors. | 2193 // generative constructors. |
2270 bool get isCyclicRedirection => effectiveTarget.isRedirectingFactory; | 2194 bool get isCyclicRedirection => effectiveTarget.isRedirectingFactory; |
2271 | 2195 |
2272 /// These fields are set by the post process queue when checking for cycles. | 2196 /// These fields are set by the post process queue when checking for cycles. |
2273 ConstructorElement effectiveTargetInternal; | 2197 ConstructorElement effectiveTargetInternal; |
2274 DartType _effectiveTargetType; | 2198 DartType _effectiveTargetType; |
2275 bool _isEffectiveTargetMalformed; | 2199 bool _isEffectiveTargetMalformed; |
2276 | 2200 |
2277 void setEffectiveTarget(ConstructorElement target, | 2201 void setEffectiveTarget(ConstructorElement target, DartType type, |
2278 DartType type, | 2202 {bool isMalformed: false}) { |
2279 {bool isMalformed: false}) { | |
2280 assert(invariant(this, target != null, | 2203 assert(invariant(this, target != null, |
2281 message: 'No effective target provided for $this.')); | 2204 message: 'No effective target provided for $this.')); |
2282 assert(invariant(this, effectiveTargetInternal == null, | 2205 assert(invariant(this, effectiveTargetInternal == null, |
2283 message: 'Effective target has already been computed for $this.')); | 2206 message: 'Effective target has already been computed for $this.')); |
2284 effectiveTargetInternal = target; | 2207 effectiveTargetInternal = target; |
2285 _effectiveTargetType = type; | 2208 _effectiveTargetType = type; |
2286 _isEffectiveTargetMalformed = isMalformed; | 2209 _isEffectiveTargetMalformed = isMalformed; |
2287 } | 2210 } |
2288 | 2211 |
2289 ConstructorElement get effectiveTarget { | 2212 ConstructorElement get effectiveTarget { |
(...skipping 17 matching lines...) Expand all Loading... |
2307 } | 2230 } |
2308 | 2231 |
2309 InterfaceType computeEffectiveTargetType(InterfaceType newType) { | 2232 InterfaceType computeEffectiveTargetType(InterfaceType newType) { |
2310 if (!isRedirectingFactory) return newType; | 2233 if (!isRedirectingFactory) return newType; |
2311 return effectiveTargetType.substByContext(newType); | 2234 return effectiveTargetType.substByContext(newType); |
2312 } | 2235 } |
2313 | 2236 |
2314 bool get isEffectiveTargetMalformed { | 2237 bool get isEffectiveTargetMalformed { |
2315 if (!isRedirectingFactory) return false; | 2238 if (!isRedirectingFactory) return false; |
2316 assert(invariant(this, _isEffectiveTargetMalformed != null, | 2239 assert(invariant(this, _isEffectiveTargetMalformed != null, |
2317 message: 'Malformedness has not yet been computed for $this.')); | 2240 message: 'Malformedness has not yet been computed for $this.')); |
2318 return _isEffectiveTargetMalformed == true; | 2241 return _isEffectiveTargetMalformed == true; |
2319 } | 2242 } |
2320 | 2243 |
2321 accept(ElementVisitor visitor, arg) { | 2244 accept(ElementVisitor visitor, arg) { |
2322 return visitor.visitConstructorElement(this, arg); | 2245 return visitor.visitConstructorElement(this, arg); |
2323 } | 2246 } |
2324 | 2247 |
2325 ConstructorElement get definingConstructor => null; | 2248 ConstructorElement get definingConstructor => null; |
2326 | 2249 |
2327 ClassElement get enclosingClass => enclosingElement; | 2250 ClassElement get enclosingClass => enclosingElement; |
2328 } | 2251 } |
2329 | 2252 |
2330 class DeferredLoaderGetterElementX extends GetterElementX | 2253 class DeferredLoaderGetterElementX extends GetterElementX |
2331 implements GetterElement { | 2254 implements GetterElement { |
2332 final PrefixElement prefix; | 2255 final PrefixElement prefix; |
2333 | 2256 |
2334 DeferredLoaderGetterElementX(PrefixElement prefix) | 2257 DeferredLoaderGetterElementX(PrefixElement prefix) |
2335 : this.prefix = prefix, | 2258 : this.prefix = prefix, |
2336 super("loadLibrary", | 2259 super("loadLibrary", Modifiers.EMPTY, prefix, false) { |
2337 Modifiers.EMPTY, | |
2338 prefix, | |
2339 false) { | |
2340 functionSignature = new FunctionSignatureX(type: new FunctionType(this)); | 2260 functionSignature = new FunctionSignatureX(type: new FunctionType(this)); |
2341 } | 2261 } |
2342 | 2262 |
2343 bool get isClassMember => false; | 2263 bool get isClassMember => false; |
2344 | 2264 |
2345 bool get isSynthesized => true; | 2265 bool get isSynthesized => true; |
2346 | 2266 |
2347 bool get isDeferredLoaderGetter => true; | 2267 bool get isDeferredLoaderGetter => true; |
2348 | 2268 |
2349 bool get isTopLevel => true; | 2269 bool get isTopLevel => true; |
(...skipping 10 matching lines...) Expand all Loading... |
2360 @override | 2280 @override |
2361 SetterElement get setter => null; | 2281 SetterElement get setter => null; |
2362 } | 2282 } |
2363 | 2283 |
2364 class ConstructorBodyElementX extends BaseFunctionElementX | 2284 class ConstructorBodyElementX extends BaseFunctionElementX |
2365 implements ConstructorBodyElement { | 2285 implements ConstructorBodyElement { |
2366 ConstructorElementX constructor; | 2286 ConstructorElementX constructor; |
2367 | 2287 |
2368 ConstructorBodyElementX(ConstructorElementX constructor) | 2288 ConstructorBodyElementX(ConstructorElementX constructor) |
2369 : this.constructor = constructor, | 2289 : this.constructor = constructor, |
2370 super(constructor.name, | 2290 super(constructor.name, ElementKind.GENERATIVE_CONSTRUCTOR_BODY, |
2371 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, | 2291 Modifiers.EMPTY, constructor.enclosingElement) { |
2372 Modifiers.EMPTY, | |
2373 constructor.enclosingElement) { | |
2374 functionSignature = constructor.functionSignature; | 2292 functionSignature = constructor.functionSignature; |
2375 } | 2293 } |
2376 | 2294 |
2377 bool get hasNode => constructor.hasNode; | 2295 bool get hasNode => constructor.hasNode; |
2378 | 2296 |
2379 FunctionExpression get node => constructor.node; | 2297 FunctionExpression get node => constructor.node; |
2380 | 2298 |
2381 List<MetadataAnnotation> get metadata => constructor.metadata; | 2299 List<MetadataAnnotation> get metadata => constructor.metadata; |
2382 | 2300 |
2383 bool get isInstanceMember => true; | 2301 bool get isInstanceMember => true; |
(...skipping 21 matching lines...) Expand all Loading... |
2405 * A constructor that is not defined in the source code but rather implied by | 2323 * A constructor that is not defined in the source code but rather implied by |
2406 * the language semantics. | 2324 * the language semantics. |
2407 * | 2325 * |
2408 * This class is used to represent default constructors and forwarding | 2326 * This class is used to represent default constructors and forwarding |
2409 * constructors for mixin applications. | 2327 * constructors for mixin applications. |
2410 */ | 2328 */ |
2411 class SynthesizedConstructorElementX extends ConstructorElementX { | 2329 class SynthesizedConstructorElementX extends ConstructorElementX { |
2412 final ConstructorElement definingConstructor; | 2330 final ConstructorElement definingConstructor; |
2413 final bool isDefaultConstructor; | 2331 final bool isDefaultConstructor; |
2414 | 2332 |
2415 SynthesizedConstructorElementX.notForDefault(String name, | 2333 SynthesizedConstructorElementX.notForDefault( |
2416 this.definingConstructor, | 2334 String name, this.definingConstructor, Element enclosing) |
2417 Element enclosing) | |
2418 : isDefaultConstructor = false, | 2335 : isDefaultConstructor = false, |
2419 super(name, | 2336 super(name, ElementKind.GENERATIVE_CONSTRUCTOR, Modifiers.EMPTY, |
2420 ElementKind.GENERATIVE_CONSTRUCTOR, | 2337 enclosing); |
2421 Modifiers.EMPTY, | |
2422 enclosing) ; | |
2423 | 2338 |
2424 SynthesizedConstructorElementX.forDefault(this.definingConstructor, | 2339 SynthesizedConstructorElementX.forDefault( |
2425 Element enclosing) | 2340 this.definingConstructor, Element enclosing) |
2426 : isDefaultConstructor = true, | 2341 : isDefaultConstructor = true, |
2427 super('', | 2342 super('', ElementKind.GENERATIVE_CONSTRUCTOR, Modifiers.EMPTY, |
2428 ElementKind.GENERATIVE_CONSTRUCTOR, | 2343 enclosing) { |
2429 Modifiers.EMPTY, | |
2430 enclosing) { | |
2431 functionSignature = new FunctionSignatureX( | 2344 functionSignature = new FunctionSignatureX( |
2432 type: new FunctionType.synthesized(enclosingClass.thisType)); | 2345 type: new FunctionType.synthesized(enclosingClass.thisType)); |
2433 } | 2346 } |
2434 | 2347 |
2435 FunctionExpression parseNode(Parsing parsing) => null; | 2348 FunctionExpression parseNode(Parsing parsing) => null; |
2436 | 2349 |
2437 bool get hasNode => false; | 2350 bool get hasNode => false; |
2438 | 2351 |
2439 FunctionExpression get node => null; | 2352 FunctionExpression get node => null; |
2440 | 2353 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2499 * instantiation of [InterfaceType] with [:dynamic:] as type argument. Using | 2412 * instantiation of [InterfaceType] with [:dynamic:] as type argument. Using |
2500 * this distinction, we can print the raw type with type arguments only when | 2413 * this distinction, we can print the raw type with type arguments only when |
2501 * the input source has used explicit type arguments. | 2414 * the input source has used explicit type arguments. |
2502 * | 2415 * |
2503 * This type is computed together with [thisType] in [computeType]. | 2416 * This type is computed together with [thisType] in [computeType]. |
2504 */ | 2417 */ |
2505 T rawTypeCache; | 2418 T rawTypeCache; |
2506 | 2419 |
2507 T get thisType { | 2420 T get thisType { |
2508 assert(invariant(this, thisTypeCache != null, | 2421 assert(invariant(this, thisTypeCache != null, |
2509 message: 'This type has not been computed for $this')); | 2422 message: 'This type has not been computed for $this')); |
2510 return thisTypeCache; | 2423 return thisTypeCache; |
2511 } | 2424 } |
2512 | 2425 |
2513 T get rawType { | 2426 T get rawType { |
2514 assert(invariant(this, rawTypeCache != null, | 2427 assert(invariant(this, rawTypeCache != null, |
2515 message: 'Raw type has not been computed for $this')); | 2428 message: 'Raw type has not been computed for $this')); |
2516 return rawTypeCache; | 2429 return rawTypeCache; |
2517 } | 2430 } |
2518 | 2431 |
2519 T createType(List<DartType> typeArguments); | 2432 T createType(List<DartType> typeArguments); |
2520 | 2433 |
2521 void setThisAndRawTypes(List<DartType> typeParameters) { | 2434 void setThisAndRawTypes(List<DartType> typeParameters) { |
2522 assert(invariant(this, thisTypeCache == null, | 2435 assert(invariant(this, thisTypeCache == null, |
2523 message: "This type has already been set on $this.")); | 2436 message: "This type has already been set on $this.")); |
2524 assert(invariant(this, rawTypeCache == null, | 2437 assert(invariant(this, rawTypeCache == null, |
2525 message: "Raw type has already been set on $this.")); | 2438 message: "Raw type has already been set on $this.")); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2558 }, growable: false); | 2471 }, growable: false); |
2559 return arguments; | 2472 return arguments; |
2560 } | 2473 } |
2561 | 2474 |
2562 bool get isResolved => resolutionState == STATE_DONE; | 2475 bool get isResolved => resolutionState == STATE_DONE; |
2563 | 2476 |
2564 int get resolutionState; | 2477 int get resolutionState; |
2565 } | 2478 } |
2566 | 2479 |
2567 abstract class BaseClassElementX extends ElementX | 2480 abstract class BaseClassElementX extends ElementX |
2568 with AstElementMixin, | 2481 with |
2569 AnalyzableElementX, | 2482 AstElementMixin, |
2570 ClassElementCommon, | 2483 AnalyzableElementX, |
2571 TypeDeclarationElementX<InterfaceType>, | 2484 ClassElementCommon, |
2572 PatchMixin<ClassElement>, | 2485 TypeDeclarationElementX<InterfaceType>, |
2573 ClassMemberMixin | 2486 PatchMixin<ClassElement>, |
| 2487 ClassMemberMixin |
2574 implements ClassElement { | 2488 implements ClassElement { |
2575 final int id; | 2489 final int id; |
2576 | 2490 |
2577 DartType supertype; | 2491 DartType supertype; |
2578 Link<DartType> interfaces; | 2492 Link<DartType> interfaces; |
2579 int supertypeLoadState; | 2493 int supertypeLoadState; |
2580 int resolutionState; | 2494 int resolutionState; |
2581 bool isProxy = false; | 2495 bool isProxy = false; |
2582 bool hasIncompleteHierarchy = false; | 2496 bool hasIncompleteHierarchy = false; |
2583 | 2497 |
2584 // backendMembers are members that have been added by the backend to simplify | 2498 // backendMembers are members that have been added by the backend to simplify |
2585 // compilation. They don't have any user-side counter-part. | 2499 // compilation. They don't have any user-side counter-part. |
2586 Link<Element> backendMembers = const Link<Element>(); | 2500 Link<Element> backendMembers = const Link<Element>(); |
2587 | 2501 |
2588 OrderedTypeSet allSupertypesAndSelf; | 2502 OrderedTypeSet allSupertypesAndSelf; |
2589 | 2503 |
2590 BaseClassElementX(String name, | 2504 BaseClassElementX(String name, Element enclosing, this.id, int initialState) |
2591 Element enclosing, | |
2592 this.id, | |
2593 int initialState) | |
2594 : supertypeLoadState = initialState, | 2505 : supertypeLoadState = initialState, |
2595 resolutionState = initialState, | 2506 resolutionState = initialState, |
2596 super(name, ElementKind.CLASS, enclosing); | 2507 super(name, ElementKind.CLASS, enclosing); |
2597 | 2508 |
2598 int get hashCode => id; | 2509 int get hashCode => id; |
2599 | 2510 |
2600 bool get hasBackendMembers => !backendMembers.isEmpty; | 2511 bool get hasBackendMembers => !backendMembers.isEmpty; |
2601 | 2512 |
2602 bool get isUnnamedMixinApplication => false; | 2513 bool get isUnnamedMixinApplication => false; |
2603 | 2514 |
2604 @override | 2515 @override |
2605 bool get isEnumClass => false; | 2516 bool get isEnumClass => false; |
2606 | 2517 |
2607 InterfaceType computeType(Resolution resolution) { | 2518 InterfaceType computeType(Resolution resolution) { |
2608 if (isPatch) { | 2519 if (isPatch) { |
2609 origin.computeType(resolution); | 2520 origin.computeType(resolution); |
2610 thisTypeCache = origin.thisType; | 2521 thisTypeCache = origin.thisType; |
2611 rawTypeCache = origin.rawType; | 2522 rawTypeCache = origin.rawType; |
2612 } else if (thisTypeCache == null) { | 2523 } else if (thisTypeCache == null) { |
2613 computeThisAndRawType( | 2524 computeThisAndRawType( |
2614 resolution, computeTypeParameters(resolution.parsing)); | 2525 resolution, computeTypeParameters(resolution.parsing)); |
2615 } | 2526 } |
2616 return thisTypeCache; | 2527 return thisTypeCache; |
2617 } | 2528 } |
2618 | 2529 |
2619 void computeThisAndRawType(Resolution resolution, | 2530 void computeThisAndRawType( |
2620 List<DartType> typeVariables) { | 2531 Resolution resolution, List<DartType> typeVariables) { |
2621 if (thisTypeCache == null) { | 2532 if (thisTypeCache == null) { |
2622 if (origin == null) { | 2533 if (origin == null) { |
2623 setThisAndRawTypes(typeVariables); | 2534 setThisAndRawTypes(typeVariables); |
2624 } else { | 2535 } else { |
2625 thisTypeCache = origin.computeType(resolution); | 2536 thisTypeCache = origin.computeType(resolution); |
2626 rawTypeCache = origin.rawType; | 2537 rawTypeCache = origin.rawType; |
2627 } | 2538 } |
2628 } | 2539 } |
2629 } | 2540 } |
2630 | 2541 |
(...skipping 10 matching lines...) Expand all Loading... |
2641 return supertype == null; | 2552 return supertype == null; |
2642 } | 2553 } |
2643 | 2554 |
2644 void ensureResolved(Resolution resolution) { | 2555 void ensureResolved(Resolution resolution) { |
2645 if (resolutionState == STATE_NOT_STARTED) { | 2556 if (resolutionState == STATE_NOT_STARTED) { |
2646 resolution.resolveClass(this); | 2557 resolution.resolveClass(this); |
2647 resolution.registerClass(this); | 2558 resolution.registerClass(this); |
2648 } | 2559 } |
2649 } | 2560 } |
2650 | 2561 |
2651 void setDefaultConstructor(FunctionElement constructor, | 2562 void setDefaultConstructor( |
2652 DiagnosticReporter reporter); | 2563 FunctionElement constructor, DiagnosticReporter reporter); |
2653 | 2564 |
2654 void addBackendMember(Element member) { | 2565 void addBackendMember(Element member) { |
2655 // TODO(ngeoffray): Deprecate this method. | 2566 // TODO(ngeoffray): Deprecate this method. |
2656 assert(member.isGenerativeConstructorBody); | 2567 assert(member.isGenerativeConstructorBody); |
2657 backendMembers = backendMembers.prepend(member); | 2568 backendMembers = backendMembers.prepend(member); |
2658 } | 2569 } |
2659 | 2570 |
2660 void reverseBackendMembers() { | 2571 void reverseBackendMembers() { |
2661 backendMembers = backendMembers.reverse(); | 2572 backendMembers = backendMembers.reverse(); |
2662 } | 2573 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2727 bool get hasLocalScopeMembers => !localScope.isEmpty; | 2638 bool get hasLocalScopeMembers => !localScope.isEmpty; |
2728 | 2639 |
2729 void addMember(Element element, DiagnosticReporter reporter) { | 2640 void addMember(Element element, DiagnosticReporter reporter) { |
2730 localMembersCache = null; | 2641 localMembersCache = null; |
2731 localMembersReversed = localMembersReversed.prepend(element); | 2642 localMembersReversed = localMembersReversed.prepend(element); |
2732 addToScope(element, reporter); | 2643 addToScope(element, reporter); |
2733 } | 2644 } |
2734 | 2645 |
2735 void addToScope(Element element, DiagnosticReporter reporter) { | 2646 void addToScope(Element element, DiagnosticReporter reporter) { |
2736 if (element.isField && element.name == name) { | 2647 if (element.isField && element.name == name) { |
2737 reporter.reportErrorMessage( | 2648 reporter.reportErrorMessage(element, MessageKind.MEMBER_USES_CLASS_NAME); |
2738 element, MessageKind.MEMBER_USES_CLASS_NAME); | |
2739 } | 2649 } |
2740 localScope.add(element, reporter); | 2650 localScope.add(element, reporter); |
2741 } | 2651 } |
2742 | 2652 |
2743 Element localLookup(String elementName) { | 2653 Element localLookup(String elementName) { |
2744 Element result = localScope.lookup(elementName); | 2654 Element result = localScope.lookup(elementName); |
2745 if (result == null && isPatch) { | 2655 if (result == null && isPatch) { |
2746 result = origin.localLookup(elementName); | 2656 result = origin.localLookup(elementName); |
2747 } | 2657 } |
2748 return result; | 2658 return result; |
2749 } | 2659 } |
2750 | 2660 |
2751 void forEachLocalMember(void f(Element member)) { | 2661 void forEachLocalMember(void f(Element member)) { |
2752 localMembers.forEach(f); | 2662 localMembers.forEach(f); |
2753 } | 2663 } |
2754 | 2664 |
2755 bool get hasConstructor { | 2665 bool get hasConstructor { |
2756 // Search in scope to be sure we search patched constructors. | 2666 // Search in scope to be sure we search patched constructors. |
2757 for (var element in localScope.values) { | 2667 for (var element in localScope.values) { |
2758 if (element.isConstructor) return true; | 2668 if (element.isConstructor) return true; |
2759 } | 2669 } |
2760 return false; | 2670 return false; |
2761 } | 2671 } |
2762 | 2672 |
2763 void setDefaultConstructor(FunctionElement constructor, | 2673 void setDefaultConstructor( |
2764 DiagnosticReporter reporter) { | 2674 FunctionElement constructor, DiagnosticReporter reporter) { |
2765 // The default constructor, although synthetic, is part of a class' API. | 2675 // The default constructor, although synthetic, is part of a class' API. |
2766 addMember(constructor, reporter); | 2676 addMember(constructor, reporter); |
2767 } | 2677 } |
2768 | 2678 |
2769 List<DartType> computeTypeParameters(Parsing parsing) { | 2679 List<DartType> computeTypeParameters(Parsing parsing) { |
2770 ClassNode node = parseNode(parsing); | 2680 ClassNode node = parseNode(parsing); |
2771 return createTypeVariables(node.typeParameters); | 2681 return createTypeVariables(node.typeParameters); |
2772 } | 2682 } |
2773 | 2683 |
2774 Scope buildScope() => new ClassScope(enclosingElement.buildScope(), this); | 2684 Scope buildScope() => new ClassScope(enclosingElement.buildScope(), this); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2823 _enumValues = values; | 2733 _enumValues = values; |
2824 } | 2734 } |
2825 | 2735 |
2826 @override | 2736 @override |
2827 DeclarationSite get declarationSite => this; | 2737 DeclarationSite get declarationSite => this; |
2828 } | 2738 } |
2829 | 2739 |
2830 class EnumConstructorElementX extends ConstructorElementX { | 2740 class EnumConstructorElementX extends ConstructorElementX { |
2831 final FunctionExpression node; | 2741 final FunctionExpression node; |
2832 | 2742 |
2833 EnumConstructorElementX(EnumClassElementX enumClass, | 2743 EnumConstructorElementX( |
2834 Modifiers modifiers, | 2744 EnumClassElementX enumClass, Modifiers modifiers, this.node) |
2835 this.node) | 2745 : super( |
2836 : super('', // Name. | 2746 '', // Name. |
2837 ElementKind.GENERATIVE_CONSTRUCTOR, | 2747 ElementKind.GENERATIVE_CONSTRUCTOR, |
2838 modifiers, | 2748 modifiers, |
2839 enumClass); | 2749 enumClass); |
2840 | 2750 |
2841 @override | 2751 @override |
2842 bool get hasNode => true; | 2752 bool get hasNode => true; |
2843 | 2753 |
2844 @override | 2754 @override |
2845 FunctionExpression parseNode(Parsing parsing) => node; | 2755 FunctionExpression parseNode(Parsing parsing) => node; |
2846 } | 2756 } |
2847 | 2757 |
2848 class EnumMethodElementX extends MethodElementX { | 2758 class EnumMethodElementX extends MethodElementX { |
2849 final FunctionExpression node; | 2759 final FunctionExpression node; |
2850 | 2760 |
2851 EnumMethodElementX(String name, | 2761 EnumMethodElementX( |
2852 EnumClassElementX enumClass, | 2762 String name, EnumClassElementX enumClass, Modifiers modifiers, this.node) |
2853 Modifiers modifiers, | |
2854 this.node) | |
2855 : super(name, ElementKind.FUNCTION, modifiers, enumClass, true); | 2763 : super(name, ElementKind.FUNCTION, modifiers, enumClass, true); |
2856 | 2764 |
2857 @override | 2765 @override |
2858 bool get hasNode => true; | 2766 bool get hasNode => true; |
2859 | 2767 |
2860 @override | 2768 @override |
2861 FunctionExpression parseNode(Parsing parsing) => node; | 2769 FunctionExpression parseNode(Parsing parsing) => node; |
2862 } | 2770 } |
2863 | 2771 |
2864 class EnumFormalElementX extends InitializingFormalElementX { | 2772 class EnumFormalElementX extends InitializingFormalElementX { |
2865 EnumFormalElementX(ConstructorElement constructor, | 2773 EnumFormalElementX( |
2866 VariableDefinitions variables, | 2774 ConstructorElement constructor, |
2867 Identifier identifier, | 2775 VariableDefinitions variables, |
2868 EnumFieldElementX fieldElement) | 2776 Identifier identifier, |
| 2777 EnumFieldElementX fieldElement) |
2869 : super(constructor, variables, identifier, null, fieldElement) { | 2778 : super(constructor, variables, identifier, null, fieldElement) { |
2870 typeCache = fieldElement.type; | 2779 typeCache = fieldElement.type; |
2871 } | 2780 } |
2872 } | 2781 } |
2873 | 2782 |
2874 class EnumFieldElementX extends FieldElementX { | 2783 class EnumFieldElementX extends FieldElementX { |
2875 | 2784 EnumFieldElementX(Identifier name, EnumClassElementX enumClass, |
2876 EnumFieldElementX(Identifier name, | 2785 VariableList variableList, Node definition, |
2877 EnumClassElementX enumClass, | 2786 [Expression initializer]) |
2878 VariableList variableList, | |
2879 Node definition, | |
2880 [Expression initializer]) | |
2881 : super(name, enumClass, variableList) { | 2787 : super(name, enumClass, variableList) { |
2882 definitionsCache = new VariableDefinitions(null, | 2788 definitionsCache = new VariableDefinitions( |
2883 variableList.modifiers, new NodeList.singleton(definition)); | 2789 null, variableList.modifiers, new NodeList.singleton(definition)); |
2884 initializerCache = initializer; | 2790 initializerCache = initializer; |
2885 } | 2791 } |
2886 } | 2792 } |
2887 | 2793 |
2888 abstract class MixinApplicationElementX extends BaseClassElementX | 2794 abstract class MixinApplicationElementX extends BaseClassElementX |
2889 with MixinApplicationElementCommon | 2795 with MixinApplicationElementCommon |
2890 implements MixinApplicationElement { | 2796 implements MixinApplicationElement { |
2891 Link<ConstructorElement> constructors = new Link<ConstructorElement>(); | 2797 Link<ConstructorElement> constructors = new Link<ConstructorElement>(); |
2892 | 2798 |
2893 InterfaceType mixinType; | 2799 InterfaceType mixinType; |
(...skipping 22 matching lines...) Expand all Loading... |
2916 } | 2822 } |
2917 | 2823 |
2918 void addToScope(Element element, DiagnosticReporter reporter) { | 2824 void addToScope(Element element, DiagnosticReporter reporter) { |
2919 reporter.internalError(this, 'Cannot add to scope of $this.'); | 2825 reporter.internalError(this, 'Cannot add to scope of $this.'); |
2920 } | 2826 } |
2921 | 2827 |
2922 void addConstructor(FunctionElement constructor) { | 2828 void addConstructor(FunctionElement constructor) { |
2923 constructors = constructors.prepend(constructor); | 2829 constructors = constructors.prepend(constructor); |
2924 } | 2830 } |
2925 | 2831 |
2926 void setDefaultConstructor(FunctionElement constructor, | 2832 void setDefaultConstructor( |
2927 DiagnosticReporter reporter) { | 2833 FunctionElement constructor, DiagnosticReporter reporter) { |
2928 assert(!hasConstructor); | 2834 assert(!hasConstructor); |
2929 addConstructor(constructor); | 2835 addConstructor(constructor); |
2930 } | 2836 } |
2931 | 2837 |
2932 List<DartType> computeTypeParameters(Parsing parsing) { | 2838 List<DartType> computeTypeParameters(Parsing parsing) { |
2933 NamedMixinApplication named = node.asNamedMixinApplication(); | 2839 NamedMixinApplication named = node.asNamedMixinApplication(); |
2934 if (named == null) { | 2840 if (named == null) { |
2935 throw new SpannableAssertionFailure(node, | 2841 throw new SpannableAssertionFailure( |
| 2842 node, |
2936 "Type variables on unnamed mixin applications must be set on " | 2843 "Type variables on unnamed mixin applications must be set on " |
2937 "creation."); | 2844 "creation."); |
2938 } | 2845 } |
2939 return createTypeVariables(named.typeParameters); | 2846 return createTypeVariables(named.typeParameters); |
2940 } | 2847 } |
2941 | 2848 |
2942 accept(ElementVisitor visitor, arg) { | 2849 accept(ElementVisitor visitor, arg) { |
2943 return visitor.visitMixinApplicationElement(this, arg); | 2850 return visitor.visitMixinApplicationElement(this, arg); |
2944 } | 2851 } |
2945 } | 2852 } |
2946 | 2853 |
2947 class NamedMixinApplicationElementX extends MixinApplicationElementX | 2854 class NamedMixinApplicationElementX extends MixinApplicationElementX |
2948 implements DeclarationSite { | 2855 implements DeclarationSite { |
2949 final NamedMixinApplication node; | 2856 final NamedMixinApplication node; |
2950 | 2857 |
2951 NamedMixinApplicationElementX( | 2858 NamedMixinApplicationElementX( |
2952 String name, | 2859 String name, CompilationUnitElement enclosing, int id, this.node) |
2953 CompilationUnitElement enclosing, | |
2954 int id, | |
2955 this.node) | |
2956 : super(name, enclosing, id); | 2860 : super(name, enclosing, id); |
2957 | 2861 |
2958 Modifiers get modifiers => node.modifiers; | 2862 Modifiers get modifiers => node.modifiers; |
2959 | 2863 |
2960 DeclarationSite get declarationSite => this; | 2864 DeclarationSite get declarationSite => this; |
2961 } | 2865 } |
2962 | 2866 |
2963 class UnnamedMixinApplicationElementX extends MixinApplicationElementX { | 2867 class UnnamedMixinApplicationElementX extends MixinApplicationElementX { |
2964 final Node node; | 2868 final Node node; |
2965 | 2869 |
2966 UnnamedMixinApplicationElementX( | 2870 UnnamedMixinApplicationElementX( |
2967 String name, | 2871 String name, CompilationUnitElement enclosing, int id, this.node) |
2968 CompilationUnitElement enclosing, | |
2969 int id, | |
2970 this.node) | |
2971 : super(name, enclosing, id); | 2872 : super(name, enclosing, id); |
2972 | 2873 |
2973 bool get isAbstract => true; | 2874 bool get isAbstract => true; |
2974 } | 2875 } |
2975 | 2876 |
2976 class LabelDefinitionX implements LabelDefinition { | 2877 class LabelDefinitionX implements LabelDefinition { |
2977 final Label label; | 2878 final Label label; |
2978 final String labelName; | 2879 final String labelName; |
2979 final JumpTarget target; | 2880 final JumpTarget target; |
2980 bool isBreakTarget = false; | 2881 bool isBreakTarget = false; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3021 LabelDefinition result = new LabelDefinitionX(label, labelName, this); | 2922 LabelDefinition result = new LabelDefinitionX(label, labelName, this); |
3022 labels = labels.prepend(result); | 2923 labels = labels.prepend(result); |
3023 return result; | 2924 return result; |
3024 } | 2925 } |
3025 | 2926 |
3026 bool get isSwitch => statement is SwitchStatement; | 2927 bool get isSwitch => statement is SwitchStatement; |
3027 | 2928 |
3028 String toString() => 'Target:$statement'; | 2929 String toString() => 'Target:$statement'; |
3029 } | 2930 } |
3030 | 2931 |
3031 class TypeVariableElementX extends ElementX with AstElementMixin | 2932 class TypeVariableElementX extends ElementX |
| 2933 with AstElementMixin |
3032 implements TypeVariableElement { | 2934 implements TypeVariableElement { |
3033 final int index; | 2935 final int index; |
3034 final Node node; | 2936 final Node node; |
3035 TypeVariableType typeCache; | 2937 TypeVariableType typeCache; |
3036 DartType boundCache; | 2938 DartType boundCache; |
3037 | 2939 |
3038 TypeVariableElementX(String name, | 2940 TypeVariableElementX( |
3039 TypeDeclarationElement enclosing, | 2941 String name, TypeDeclarationElement enclosing, this.index, this.node) |
3040 this.index, | 2942 : super(name, ElementKind.TYPE_VARIABLE, enclosing); |
3041 this.node) | |
3042 : super(name, ElementKind.TYPE_VARIABLE, enclosing); | |
3043 | 2943 |
3044 TypeDeclarationElement get typeDeclaration => enclosingElement; | 2944 TypeDeclarationElement get typeDeclaration => enclosingElement; |
3045 | 2945 |
3046 TypeVariableType computeType(Resolution resolution) => type; | 2946 TypeVariableType computeType(Resolution resolution) => type; |
3047 | 2947 |
3048 TypeVariableType get type { | 2948 TypeVariableType get type { |
3049 assert(invariant(this, typeCache != null, | 2949 assert(invariant(this, typeCache != null, |
3050 message: "Type has not been set on $this.")); | 2950 message: "Type has not been set on $this.")); |
3051 return typeCache; | 2951 return typeCache; |
3052 } | 2952 } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3142 bool get hasNode => true; | 3042 bool get hasNode => true; |
3143 | 3043 |
3144 Metadata get node => metadata; | 3044 Metadata get node => metadata; |
3145 } | 3045 } |
3146 | 3046 |
3147 /// Mixin for the implementation of patched elements. | 3047 /// Mixin for the implementation of patched elements. |
3148 /// | 3048 /// |
3149 /// See [:patch_parser.dart:] for a description of the terminology. | 3049 /// See [:patch_parser.dart:] for a description of the terminology. |
3150 abstract class PatchMixin<E extends Element> implements Element { | 3050 abstract class PatchMixin<E extends Element> implements Element { |
3151 // TODO(johnniwinther): Use type variables when issue 18630 is fixed. | 3051 // TODO(johnniwinther): Use type variables when issue 18630 is fixed. |
3152 Element/*E*/ patch = null; | 3052 Element /*E*/ patch = null; |
3153 Element/*E*/ origin = null; | 3053 Element /*E*/ origin = null; |
3154 | 3054 |
3155 bool get isPatch => origin != null; | 3055 bool get isPatch => origin != null; |
3156 bool get isPatched => patch != null; | 3056 bool get isPatched => patch != null; |
3157 | 3057 |
3158 bool get isImplementation => !isPatched; | 3058 bool get isImplementation => !isPatched; |
3159 bool get isDeclaration => !isPatch; | 3059 bool get isDeclaration => !isPatch; |
3160 | 3060 |
3161 Element/*E*/ get implementation => isPatched ? patch : this; | 3061 Element /*E*/ get implementation => isPatched ? patch : this; |
3162 Element/*E*/ get declaration => isPatch ? origin : this; | 3062 Element /*E*/ get declaration => isPatch ? origin : this; |
3163 | 3063 |
3164 /// Applies a patch to this element. This method must be called at most once. | 3064 /// Applies a patch to this element. This method must be called at most once. |
3165 void applyPatch(PatchMixin<E> patch) { | 3065 void applyPatch(PatchMixin<E> patch) { |
3166 assert(invariant(this, this.patch == null, | 3066 assert(invariant(this, this.patch == null, |
3167 message: "Element is patched twice.")); | 3067 message: "Element is patched twice.")); |
3168 assert(invariant(this, this.origin == null, | 3068 assert(invariant(this, this.origin == null, |
3169 message: "Origin element is a patch.")); | 3069 message: "Origin element is a patch.")); |
3170 assert(invariant(patch, patch.origin == null, | 3070 assert(invariant(patch, patch.origin == null, |
3171 message: "Element is patched twice.")); | 3071 message: "Element is patched twice.")); |
3172 assert(invariant(patch, patch.patch == null, | 3072 assert(invariant(patch, patch.patch == null, |
3173 message: "Patch element is patched.")); | 3073 message: "Patch element is patched.")); |
3174 this.patch = patch; | 3074 this.patch = patch; |
3175 patch.origin = this; | 3075 patch.origin = this; |
3176 } | 3076 } |
3177 } | 3077 } |
3178 | 3078 |
3179 /// Abstract implementation of the [AstElement] interface. | 3079 /// Abstract implementation of the [AstElement] interface. |
3180 abstract class AstElementMixin implements AstElement { | 3080 abstract class AstElementMixin implements AstElement { |
3181 /// The element whose node defines this element. | 3081 /// The element whose node defines this element. |
3182 /// | 3082 /// |
3183 /// For patched functions the defining element is the patch element found | 3083 /// For patched functions the defining element is the patch element found |
3184 /// through [implementation] since its node define the implementation of the | 3084 /// through [implementation] since its node define the implementation of the |
3185 /// function. For patched classes the defining element is the origin element | 3085 /// function. For patched classes the defining element is the origin element |
3186 /// found through [declaration] since its node define the inheritance relation | 3086 /// found through [declaration] since its node define the inheritance relation |
3187 /// for the class. For unpatched elements the defining element is the element | 3087 /// for the class. For unpatched elements the defining element is the element |
3188 /// itself. | 3088 /// itself. |
3189 AstElement get definingElement; | 3089 AstElement get definingElement; |
3190 | 3090 |
3191 bool get hasResolvedAst => definingElement.hasTreeElements; | 3091 bool get hasResolvedAst => definingElement.hasTreeElements; |
3192 | 3092 |
3193 ResolvedAst get resolvedAst { | 3093 ResolvedAst get resolvedAst { |
3194 return new ResolvedAst(declaration, | 3094 return new ResolvedAst( |
3195 definingElement.node, definingElement.treeElements); | 3095 declaration, definingElement.node, definingElement.treeElements); |
3196 } | 3096 } |
3197 | |
3198 } | 3097 } |
OLD | NEW |