Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: observatory_pub_packages/analyzer/src/generated/element.dart

Issue 816693004: Add observatory_pub_packages snapshot to third_party (Closed) Base URL: http://dart.googlecode.com/svn/third_party/
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information.
7
8 library engine.element;
9
10 import 'dart:collection';
11 import 'java_core.dart';
12 import 'java_engine.dart';
13 import 'utilities_collection.dart';
14 import 'source.dart';
15 import 'scanner.dart' show Keyword;
16 import 'ast.dart';
17 import 'sdk.dart' show DartSdk;
18 import 'html.dart' show XmlAttributeNode, XmlTagNode;
19 import 'engine.dart' show AnalysisContext, AnalysisEngine, AnalysisException;
20 import 'constant.dart' show EvaluationResultImpl;
21 import 'resolver.dart';
22 import 'utilities_dart.dart';
23
24 /**
25 * Information about Angular application.
26 */
27 class AngularApplication {
28 final Source entryPoint;
29
30 final Set<Source> _librarySources;
31
32 final List<AngularElement> elements;
33
34 final List<Source> elementSources;
35
36 AngularApplication(this.entryPoint, this._librarySources, this.elements, this. elementSources);
37
38 /**
39 * Checks if this application depends on the library with the given [Source].
40 */
41 bool dependsOn(Source librarySource) => _librarySources.contains(librarySource );
42 }
43
44 /**
45 * The interface `AngularControllerElement` defines the Angular component descri bed by
46 * <code>Component</code> annotation.
47 */
48 abstract class AngularComponentElement implements AngularHasSelectorElement, Ang ularHasTemplateElement {
49 /**
50 * Return an array containing all of the properties declared by this component .
51 */
52 List<AngularPropertyElement> get properties;
53
54 /**
55 * Return an array containing all of the scope properties set in the implement ation of this
56 * component.
57 */
58 List<AngularScopePropertyElement> get scopeProperties;
59
60 /**
61 * Returns the CSS file URI.
62 */
63 String get styleUri;
64
65 /**
66 * Return the offset of the [getStyleUri] in the [getSource].
67 *
68 * @return the offset of the style URI
69 */
70 int get styleUriOffset;
71 }
72
73 /**
74 * Implementation of `AngularComponentElement`.
75 */
76 class AngularComponentElementImpl extends AngularHasSelectorElementImpl implemen ts AngularComponentElement {
77 /**
78 * The offset of the defining <code>Component</code> annotation.
79 */
80 final int _annotationOffset;
81
82 /**
83 * The array containing all of the properties declared by this component.
84 */
85 List<AngularPropertyElement> _properties = AngularPropertyElement.EMPTY_ARRAY;
86
87 /**
88 * The array containing all of the scope properties set by this component.
89 */
90 List<AngularScopePropertyElement> _scopeProperties = AngularScopePropertyEleme nt.EMPTY_ARRAY;
91
92 /**
93 * The the CSS file URI.
94 */
95 String styleUri;
96
97 /**
98 * The offset of the [styleUri] in the [getSource].
99 */
100 int styleUriOffset = 0;
101
102 /**
103 * The HTML template URI.
104 */
105 String templateUri;
106
107 /**
108 * The HTML template source.
109 */
110 Source templateSource;
111
112 /**
113 * The offset of the [templateUri] in the [getSource].
114 */
115 int templateUriOffset = 0;
116
117 /**
118 * Initialize a newly created Angular component to have the given name.
119 *
120 * @param name the name of this element
121 * @param nameOffset the offset of the name of this element in the file that c ontains the
122 * declaration of this element
123 */
124 AngularComponentElementImpl(String name, int nameOffset, this._annotationOffse t) : super(name, nameOffset);
125
126 @override
127 accept(ElementVisitor visitor) => visitor.visitAngularComponentElement(this);
128
129 @override
130 ElementKind get kind => ElementKind.ANGULAR_COMPONENT;
131
132 @override
133 List<AngularPropertyElement> get properties => _properties;
134
135 @override
136 List<AngularScopePropertyElement> get scopeProperties => _scopeProperties;
137
138 /**
139 * Set an array containing all of the properties declared by this component.
140 *
141 * @param properties the properties to set
142 */
143 void set properties(List<AngularPropertyElement> properties) {
144 for (AngularPropertyElement property in properties) {
145 encloseElement(property as AngularPropertyElementImpl);
146 }
147 this._properties = properties;
148 }
149
150 /**
151 * Set an array containing all of the scope properties declared by this compon ent.
152 *
153 * @param properties the properties to set
154 */
155 void set scopeProperties(List<AngularScopePropertyElement> properties) {
156 for (AngularScopePropertyElement property in properties) {
157 encloseElement(property as AngularScopePropertyElementImpl);
158 }
159 this._scopeProperties = properties;
160 }
161
162 @override
163 void visitChildren(ElementVisitor visitor) {
164 safelyVisitChildren(_properties, visitor);
165 safelyVisitChildren(_scopeProperties, visitor);
166 super.visitChildren(visitor);
167 }
168
169 @override
170 String get identifier => "AngularComponent@${_annotationOffset}";
171 }
172
173 /**
174 * The interface `AngularControllerElement` defines the Angular controller descr ibed by
175 * <code>Controller</code> annotation.
176 */
177 abstract class AngularControllerElement implements AngularHasSelectorElement {
178 }
179
180 /**
181 * Implementation of `AngularControllerElement`.
182 */
183 class AngularControllerElementImpl extends AngularHasSelectorElementImpl impleme nts AngularControllerElement {
184 /**
185 * Initialize a newly created Angular controller to have the given name.
186 *
187 * @param name the name of this element
188 * @param nameOffset the offset of the name of this element in the file that c ontains the
189 * declaration of this element
190 */
191 AngularControllerElementImpl(String name, int nameOffset) : super(name, nameOf fset);
192
193 @override
194 accept(ElementVisitor visitor) => visitor.visitAngularControllerElement(this);
195
196 @override
197 ElementKind get kind => ElementKind.ANGULAR_CONTROLLER;
198 }
199
200 /**
201 * The interface `AngularDirectiveElement` defines the Angular controller descri bed by
202 * <code>Decorator</code> annotation.
203 */
204 abstract class AngularDecoratorElement implements AngularHasSelectorElement {
205 /**
206 * Return an array containing all of the properties declared by this directive .
207 */
208 List<AngularPropertyElement> get properties;
209
210 /**
211 * Checks if this directive is implemented by the class with given name.
212 */
213 bool isClass(String name);
214 }
215
216 /**
217 * Implementation of `AngularDirectiveElement`.
218 */
219 class AngularDecoratorElementImpl extends AngularHasSelectorElementImpl implemen ts AngularDecoratorElement {
220 /**
221 * The offset of the annotation that defines this directive.
222 */
223 final int _offset;
224
225 /**
226 * The array containing all of the properties declared by this directive.
227 */
228 List<AngularPropertyElement> _properties = AngularPropertyElement.EMPTY_ARRAY;
229
230 /**
231 * Initialize a newly created Angular directive to have the given name.
232 *
233 * @param offset the offset of the annotation that defines this directive
234 */
235 AngularDecoratorElementImpl(this._offset) : super(null, -1);
236
237 @override
238 accept(ElementVisitor visitor) => visitor.visitAngularDirectiveElement(this);
239
240 @override
241 String get displayName => selector.displayName;
242
243 @override
244 ElementKind get kind => ElementKind.ANGULAR_DIRECTIVE;
245
246 @override
247 List<AngularPropertyElement> get properties => _properties;
248
249 @override
250 bool isClass(String name) {
251 Element enclosing = enclosingElement;
252 return enclosing is ClassElement && enclosing.name == name;
253 }
254
255 /**
256 * Set an array containing all of the properties declared by this directive.
257 *
258 * @param properties the properties to set
259 */
260 void set properties(List<AngularPropertyElement> properties) {
261 for (AngularPropertyElement property in properties) {
262 encloseElement(property as AngularPropertyElementImpl);
263 }
264 this._properties = properties;
265 }
266
267 @override
268 void visitChildren(ElementVisitor visitor) {
269 safelyVisitChildren(_properties, visitor);
270 super.visitChildren(visitor);
271 }
272
273 @override
274 String get identifier => "Decorator@${_offset}";
275 }
276
277 /**
278 * The interface `AngularElement` defines the behavior of objects representing i nformation
279 * about an Angular specific element.
280 */
281 abstract class AngularElement implements ToolkitObjectElement {
282 /**
283 * An empty array of Angular elements.
284 */
285 static final List<AngularElement> EMPTY_ARRAY = new List<AngularElement>(0);
286
287 /**
288 * Returns the [AngularApplication] this element is used in.
289 *
290 * @return the [AngularApplication] this element is used in
291 */
292 AngularApplication get application;
293 }
294
295 /**
296 * Implementation of `AngularElement`.
297 */
298 abstract class AngularElementImpl extends ToolkitObjectElementImpl implements An gularElement {
299 /**
300 * The [AngularApplication] this element is used in.
301 */
302 AngularApplication _application;
303
304 /**
305 * Initialize a newly created Angular element to have the given name.
306 *
307 * @param name the name of this element
308 * @param nameOffset the offset of the name of this element in the file that c ontains the
309 * declaration of this element
310 */
311 AngularElementImpl(String name, int nameOffset) : super(name, nameOffset);
312
313 @override
314 AngularApplication get application => _application;
315
316 /**
317 * Set the [AngularApplication] this element is used in.
318 */
319 void set application(AngularApplication application) {
320 this._application = application;
321 }
322 }
323
324 /**
325 * The interface `AngularFormatterElement` defines the Angular formatter describ ed by
326 * <code>Formatter</code> annotation.
327 */
328 abstract class AngularFormatterElement implements AngularElement {
329 }
330
331 /**
332 * Implementation of `AngularFormatterElement`.
333 */
334 class AngularFormatterElementImpl extends AngularElementImpl implements AngularF ormatterElement {
335 /**
336 * Initialize a newly created Angular formatter to have the given name.
337 *
338 * @param name the name of this element
339 * @param nameOffset the offset of the name of this element in the file that c ontains the
340 * declaration of this element
341 */
342 AngularFormatterElementImpl(String name, int nameOffset) : super(name, nameOff set);
343
344 @override
345 accept(ElementVisitor visitor) => visitor.visitAngularFormatterElement(this);
346
347 @override
348 ElementKind get kind => ElementKind.ANGULAR_FORMATTER;
349 }
350
351 /**
352 * [AngularSelectorElement] based on presence of attribute.
353 */
354 abstract class AngularHasAttributeSelectorElement implements AngularSelectorElem ent {
355 }
356
357 /**
358 * [AngularSelectorElement] based on presence of a class.
359 */
360 abstract class AngularHasClassSelectorElement implements AngularSelectorElement {
361 }
362
363 /**
364 * Implementation of [AngularSelectorElement] based on presence of a class.
365 */
366 class AngularHasClassSelectorElementImpl extends AngularSelectorElementImpl impl ements AngularHasClassSelectorElement {
367 AngularHasClassSelectorElementImpl(String name, int offset) : super(name, offs et);
368
369 @override
370 bool apply(XmlTagNode node) {
371 XmlAttributeNode attribute = node.getAttribute("class");
372 if (attribute != null) {
373 String text = attribute.text;
374 if (text != null) {
375 String name = this.name;
376 for (String className in StringUtils.split(text)) {
377 if (className == name) {
378 return true;
379 }
380 }
381 }
382 }
383 return false;
384 }
385
386 @override
387 void appendTo(JavaStringBuilder builder) {
388 builder.append(".");
389 builder.append(name);
390 }
391 }
392
393 /**
394 * The interface `AngularElement` defines the behavior of objects representing i nformation
395 * about an Angular element which is applied conditionally using some [AngularSe lectorElement].
396 */
397 abstract class AngularHasSelectorElement implements AngularElement {
398 /**
399 * Returns the selector specified for this element.
400 *
401 * @return the [AngularSelectorElement] specified for this element
402 */
403 AngularSelectorElement get selector;
404 }
405
406 /**
407 * Implementation of `AngularSelectorElement`.
408 */
409 abstract class AngularHasSelectorElementImpl extends AngularElementImpl implemen ts AngularHasSelectorElement {
410 /**
411 * The selector of this element.
412 */
413 AngularSelectorElement _selector;
414
415 /**
416 * Initialize a newly created Angular element to have the given name.
417 *
418 * @param name the name of this element
419 * @param nameOffset the offset of the name of this element in the file that c ontains the
420 * declaration of this element
421 */
422 AngularHasSelectorElementImpl(String name, int nameOffset) : super(name, nameO ffset);
423
424 @override
425 AngularSelectorElement get selector => _selector;
426
427 /**
428 * Set the selector of this selector-based element.
429 *
430 * @param selector the selector to set
431 */
432 void set selector(AngularSelectorElement selector) {
433 encloseElement(selector as AngularSelectorElementImpl);
434 this._selector = selector;
435 }
436
437 @override
438 void visitChildren(ElementVisitor visitor) {
439 safelyVisitChild(_selector, visitor);
440 super.visitChildren(visitor);
441 }
442 }
443
444 /**
445 * The interface `AngularHasTemplateElement` defines common behavior for
446 * [AngularElement] that have template URI / [Source].
447 */
448 abstract class AngularHasTemplateElement implements AngularElement {
449 /**
450 * Returns the HTML template [Source], `null` if not resolved.
451 */
452 Source get templateSource;
453
454 /**
455 * Returns the HTML template URI.
456 */
457 String get templateUri;
458
459 /**
460 * Return the offset of the [getTemplateUri] in the [getSource].
461 *
462 * @return the offset of the template URI
463 */
464 int get templateUriOffset;
465 }
466
467 /**
468 * The interface `AngularPropertyElement` defines a single property in
469 * [AngularComponentElement].
470 */
471 abstract class AngularPropertyElement implements AngularElement {
472 /**
473 * An empty array of property elements.
474 */
475 static final List<AngularPropertyElement> EMPTY_ARRAY = [];
476
477 /**
478 * Returns the field this property is mapped to.
479 *
480 * @return the field this property is mapped to.
481 */
482 FieldElement get field;
483
484 /**
485 * Return the offset of the field name of this property in the property map, o r `-1` if
486 * property was created using annotation on [FieldElement].
487 *
488 * @return the offset of the field name of this property
489 */
490 int get fieldNameOffset;
491
492 /**
493 * Returns the kind of this property.
494 *
495 * @return the kind of this property
496 */
497 AngularPropertyKind get propertyKind;
498 }
499
500 /**
501 * Implementation of `AngularPropertyElement`.
502 */
503 class AngularPropertyElementImpl extends AngularElementImpl implements AngularPr opertyElement {
504 /**
505 * The [FieldElement] to which this property is bound.
506 */
507 FieldElement field;
508
509 /**
510 * The offset of the field name in the property map.
511 */
512 int fieldNameOffset = -1;
513
514 AngularPropertyKind propertyKind;
515
516 /**
517 * Initialize a newly created Angular property to have the given name.
518 *
519 * @param name the name of this element
520 * @param nameOffset the offset of the name of this element in the file that c ontains the
521 * declaration of this element
522 */
523 AngularPropertyElementImpl(String name, int nameOffset) : super(name, nameOffs et);
524
525 @override
526 accept(ElementVisitor visitor) => visitor.visitAngularPropertyElement(this);
527
528 @override
529 ElementKind get kind => ElementKind.ANGULAR_PROPERTY;
530 }
531
532 /**
533 * The enumeration `AngularPropertyKind` defines the different kinds of property bindings.
534 */
535 class AngularPropertyKind extends Enum<AngularPropertyKind> {
536 /**
537 * `@` - Map the DOM attribute string. The attribute string will be taken lite rally or
538 * interpolated if it contains binding {{}} syntax and assigned to the express ion. (cost: 0
539 * watches)
540 */
541 static const AngularPropertyKind ATTR = const AngularPropertyKind('ATTR', 0);
542
543 /**
544 * `&` - Treat the DOM attribute value as an expression. Assign a closure func tion into the field.
545 * This allows the component to control the invocation of the closure. This is useful for passing
546 * expressions into controllers which act like callbacks. (cost: 0 watches)
547 */
548 static const AngularPropertyKind CALLBACK = const AngularPropertyKind('CALLBAC K', 1);
549
550 /**
551 * `=>` - Treat the DOM attribute value as an expression. Set up a watch, whic h will read the
552 * expression in the attribute and assign the value to destination expression. (cost: 1 watch)
553 */
554 static const AngularPropertyKind ONE_WAY = const AngularPropertyKind('ONE_WAY' , 2);
555
556 /**
557 * `=>!` - Treat the DOM attribute value as an expression. Set up a one time w atch on expression.
558 * Once the expression turns not null it will no longer update. (cost: 1 watch es until not null,
559 * then 0 watches)
560 */
561 static const AngularPropertyKind ONE_WAY_ONE_TIME = const AngularPropertyKind( 'ONE_WAY_ONE_TIME', 3);
562
563 /**
564 * `<=>` - Treat the DOM attribute value as an expression. Set up a watch on b oth outside as well
565 * as component scope to keep the source and destination in sync. (cost: 2 wat ches)
566 */
567 static const AngularPropertyKind TWO_WAY = const AngularPropertyKind_TWO_WAY(' TWO_WAY', 4);
568
569 static const List<AngularPropertyKind> values = const [ATTR, CALLBACK, ONE_WAY , ONE_WAY_ONE_TIME, TWO_WAY];
570
571 /**
572 * Returns `true` if property of this kind calls field getter.
573 */
574 bool callsGetter() => false;
575
576 /**
577 * Returns `true` if property of this kind calls field setter.
578 */
579 bool callsSetter() => true;
580
581 const AngularPropertyKind(String name, int ordinal) : super(name, ordinal);
582 }
583
584 class AngularPropertyKind_TWO_WAY extends AngularPropertyKind {
585 const AngularPropertyKind_TWO_WAY(String name, int ordinal) : super(name, ordi nal);
586
587 @override
588 bool callsGetter() => true;
589 }
590
591 /**
592 * The interface `AngularScopeVariableElement` defines the Angular <code>Scope</ code>
593 * property. They are created for every <code>scope['property'] = value;</code> code snippet.
594 */
595 abstract class AngularScopePropertyElement implements AngularElement {
596 /**
597 * An empty array of scope property elements.
598 */
599 static final List<AngularScopePropertyElement> EMPTY_ARRAY = [];
600
601 /**
602 * Returns the type of this property, not `null`, maybe <code>dynamic</code>.
603 *
604 * @return the type of this property.
605 */
606 DartType get type;
607 }
608
609 /**
610 * Implementation of `AngularScopePropertyElement`.
611 */
612 class AngularScopePropertyElementImpl extends AngularElementImpl implements Angu larScopePropertyElement {
613 /**
614 * The type of the property
615 */
616 final DartType type;
617
618 /**
619 * Initialize a newly created Angular scope property to have the given name.
620 *
621 * @param name the name of this element
622 * @param nameOffset the offset of the name of this element in the file that c ontains the
623 * declaration of this element
624 */
625 AngularScopePropertyElementImpl(String name, int nameOffset, this.type) : supe r(name, nameOffset);
626
627 @override
628 accept(ElementVisitor visitor) => visitor.visitAngularScopePropertyElement(thi s);
629
630 @override
631 ElementKind get kind => ElementKind.ANGULAR_SCOPE_PROPERTY;
632 }
633
634 /**
635 * [AngularSelectorElement] is used to decide when Angular object should be appl ied.
636 *
637 * This class is an [Element] to support renaming component tag names, which are identifiers
638 * in selectors.
639 */
640 abstract class AngularSelectorElement implements AngularElement {
641 /**
642 * Checks if the given [XmlTagNode] matches this selector.
643 *
644 * @param node the [XmlTagNode] to check
645 * @return `true` if the given [XmlTagNode] matches, or `false` otherwise
646 */
647 bool apply(XmlTagNode node);
648 }
649
650 /**
651 * Implementation of `AngularFormatterElement`.
652 */
653 abstract class AngularSelectorElementImpl extends AngularElementImpl implements AngularSelectorElement {
654 /**
655 * Initialize a newly created Angular selector to have the given name.
656 *
657 * @param name the name of this element
658 * @param nameOffset the offset of the name of this element in the file that c ontains the
659 * declaration of this element
660 */
661 AngularSelectorElementImpl(String name, int nameOffset) : super(name, nameOffs et);
662
663 @override
664 accept(ElementVisitor visitor) => visitor.visitAngularSelectorElement(this);
665
666 @override
667 ElementKind get kind => ElementKind.ANGULAR_SELECTOR;
668 }
669
670 /**
671 * [AngularSelectorElement] based on tag name.
672 */
673 abstract class AngularTagSelectorElement implements AngularSelectorElement {
674 }
675
676 /**
677 * Implementation of [AngularSelectorElement] based on tag name.
678 */
679 class AngularTagSelectorElementImpl extends AngularSelectorElementImpl implement s AngularTagSelectorElement {
680 AngularTagSelectorElementImpl(String name, int offset) : super(name, offset);
681
682 @override
683 bool apply(XmlTagNode node) {
684 String tagName = name;
685 return node.tag == tagName;
686 }
687
688 @override
689 AngularApplication get application => (enclosingElement as AngularElementImpl) .application;
690 }
691
692 /**
693 * The interface `AngularViewElement` defines the Angular view defined using inv ocation like
694 * <code>view('views/create.html')</code>.
695 */
696 abstract class AngularViewElement implements AngularHasTemplateElement {
697 /**
698 * An empty array of view elements.
699 */
700 static final List<AngularViewElement> EMPTY_ARRAY = new List<AngularViewElemen t>(0);
701 }
702
703 /**
704 * Implementation of `AngularViewElement`.
705 */
706 class AngularViewElementImpl extends AngularElementImpl implements AngularViewEl ement {
707 /**
708 * The HTML template URI.
709 */
710 final String templateUri;
711
712 /**
713 * The offset of the [templateUri] in the [getSource].
714 */
715 final int templateUriOffset;
716
717 /**
718 * The HTML template source.
719 */
720 Source templateSource;
721
722 /**
723 * Initialize a newly created Angular view.
724 */
725 AngularViewElementImpl(this.templateUri, this.templateUriOffset) : super(null, -1);
726
727 @override
728 accept(ElementVisitor visitor) => visitor.visitAngularViewElement(this);
729
730 @override
731 ElementKind get kind => ElementKind.ANGULAR_VIEW;
732
733 @override
734 String get identifier => "AngularView@${templateUriOffset}";
735 }
736
737 /**
738 * For AST nodes that could be in both the getter and setter contexts ([IndexExp ression]s and
739 * [SimpleIdentifier]s), the additional resolved elements are stored in the AST node, in an
740 * [AuxiliaryElements]. Since resolved elements are either statically resolved o r resolved
741 * using propagated type information, this class is a wrapper for a pair of
742 * [ExecutableElement]s, not just a single [ExecutableElement].
743 */
744 class AuxiliaryElements {
745 /**
746 * The element based on propagated type information, or `null` if the AST stru cture has not
747 * been resolved or if this identifier could not be resolved.
748 */
749 final ExecutableElement propagatedElement;
750
751 /**
752 * The element associated with this identifier based on static type informatio n, or `null`
753 * if the AST structure has not been resolved or if this identifier could not be resolved.
754 */
755 final ExecutableElement staticElement;
756
757 /**
758 * Create the [AuxiliaryElements] with a static and propagated [ExecutableElem ent].
759 *
760 * @param staticElement the static element
761 * @param propagatedElement the propagated element
762 */
763 AuxiliaryElements(this.staticElement, this.propagatedElement);
764 }
765
766 /**
767 * The unique instance of the class `BottomTypeImpl` implements the type `bottom `.
768 */
769 class BottomTypeImpl extends TypeImpl {
770 /**
771 * The unique instance of this class.
772 */
773 static BottomTypeImpl _INSTANCE = new BottomTypeImpl();
774
775 /**
776 * Return the unique instance of this class.
777 *
778 * @return the unique instance of this class
779 */
780 static BottomTypeImpl get instance => _INSTANCE;
781
782 /**
783 * Prevent the creation of instances of this class.
784 */
785 BottomTypeImpl() : super(null, "<bottom>");
786
787 @override
788 bool operator ==(Object object) => identical(object, this);
789
790 @override
791 int get hashCode => 0;
792
793 @override
794 bool get isBottom => true;
795
796 @override
797 bool isSupertypeOf(DartType type) => false;
798
799 @override
800 BottomTypeImpl substitute2(List<DartType> argumentTypes, List<DartType> parame terTypes) => this;
801
802 @override
803 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => id entical(object, this);
804
805 @override
806 bool internalIsMoreSpecificThan(DartType type, bool withDynamic, Set<TypeImpl_ TypePair> visitedTypePairs) => true;
807
808 @override
809 bool internalIsSubtypeOf(DartType type, Set<TypeImpl_TypePair> visitedTypePair s) => true;
810 }
811
812 /**
813 * The interface `ClassElement` defines the behavior of elements that represent a class.
814 */
815 abstract class ClassElement implements Element {
816 /**
817 * Return an array containing all of the accessors (getters and setters) decla red in this class.
818 *
819 * @return the accessors declared in this class
820 */
821 List<PropertyAccessorElement> get accessors;
822
823 /**
824 * Return an array containing all the supertypes defined for this class and it s supertypes. This
825 * includes superclasses, mixins and interfaces.
826 *
827 * @return all the supertypes of this class, including mixins
828 */
829 List<InterfaceType> get allSupertypes;
830
831 /**
832 * Return an array containing all of the constructors declared in this class.
833 *
834 * @return the constructors declared in this class
835 */
836 List<ConstructorElement> get constructors;
837
838 /**
839 * Return the field (synthetic or explicit) defined in this class that has the given name, or
840 * `null` if this class does not define a field with the given name.
841 *
842 * @param fieldName the name of the field to be returned
843 * @return the field with the given name that is defined in this class
844 */
845 FieldElement getField(String fieldName);
846
847 /**
848 * Return an array containing all of the fields declared in this class.
849 *
850 * @return the fields declared in this class
851 */
852 List<FieldElement> get fields;
853
854 /**
855 * Return the element representing the getter with the given name that is decl ared in this class,
856 * or `null` if this class does not declare a getter with the given name.
857 *
858 * @param getterName the name of the getter to be returned
859 * @return the getter declared in this class with the given name
860 */
861 PropertyAccessorElement getGetter(String getterName);
862
863 /**
864 * Return an array containing all of the interfaces that are implemented by th is class.
865 *
866 * <b>Note:</b> Because the element model represents the state of the code, it is possible for it
867 * to be semantically invalid. In particular, it is not safe to assume that th e inheritance
868 * structure of a class does not contain a cycle. Clients that traverse the in heritance structure
869 * must explicitly guard against infinite loops.
870 *
871 * @return the interfaces that are implemented by this class
872 */
873 List<InterfaceType> get interfaces;
874
875 /**
876 * Return the element representing the method with the given name that is decl ared in this class,
877 * or `null` if this class does not declare a method with the given name.
878 *
879 * @param methodName the name of the method to be returned
880 * @return the method declared in this class with the given name
881 */
882 MethodElement getMethod(String methodName);
883
884 /**
885 * Return an array containing all of the methods declared in this class.
886 *
887 * @return the methods declared in this class
888 */
889 List<MethodElement> get methods;
890
891 /**
892 * Return an array containing all of the mixins that are applied to the class being extended in
893 * order to derive the superclass of this class.
894 *
895 * <b>Note:</b> Because the element model represents the state of the code, it is possible for it
896 * to be semantically invalid. In particular, it is not safe to assume that th e inheritance
897 * structure of a class does not contain a cycle. Clients that traverse the in heritance structure
898 * must explicitly guard against infinite loops.
899 *
900 * @return the mixins that are applied to derive the superclass of this class
901 */
902 List<InterfaceType> get mixins;
903
904 /**
905 * Return the named constructor declared in this class with the given name, or `null` if
906 * this class does not declare a named constructor with the given name.
907 *
908 * @param name the name of the constructor to be returned
909 * @return the element representing the specified constructor
910 */
911 ConstructorElement getNamedConstructor(String name);
912
913 /**
914 * Return the resolved [ClassDeclaration] node that declares this [ClassElemen t].
915 *
916 * This method is expensive, because resolved AST might be evicted from cache, so parsing and
917 * resolving will be performed.
918 *
919 * @return the resolved [ClassDeclaration], not `null`.
920 */
921 @override
922 ClassDeclaration get node;
923
924 /**
925 * Return the element representing the setter with the given name that is decl ared in this class,
926 * or `null` if this class does not declare a setter with the given name.
927 *
928 * @param setterName the name of the getter to be returned
929 * @return the setter declared in this class with the given name
930 */
931 PropertyAccessorElement getSetter(String setterName);
932
933 /**
934 * Return the superclass of this class, or `null` if the class represents the class
935 * 'Object'. All other classes will have a non-`null` superclass. If the super class was not
936 * explicitly declared then the implicit superclass 'Object' will be returned.
937 *
938 * <b>Note:</b> Because the element model represents the state of the code, it is possible for it
939 * to be semantically invalid. In particular, it is not safe to assume that th e inheritance
940 * structure of a class does not contain a cycle. Clients that traverse the in heritance structure
941 * must explicitly guard against infinite loops.
942 *
943 * @return the superclass of this class
944 */
945 InterfaceType get supertype;
946
947 /**
948 * Return an array containing all of the toolkit specific objects associated w ith this class. The
949 * array will be empty if the class does not have any toolkit specific objects or if the
950 * compilation unit containing the class has not yet had toolkit references re solved.
951 *
952 * @return the toolkit objects associated with this class
953 */
954 List<ToolkitObjectElement> get toolkitObjects;
955
956 /**
957 * Return the type defined by the class.
958 *
959 * @return the type defined by the class
960 */
961 InterfaceType get type;
962
963 /**
964 * Return an array containing all of the type parameters declared for this cla ss.
965 *
966 * @return the type parameters declared for this class
967 */
968 List<TypeParameterElement> get typeParameters;
969
970 /**
971 * Return the unnamed constructor declared in this class, or `null` if this cl ass does not
972 * declare an unnamed constructor but does declare named constructors. The ret urned constructor
973 * will be synthetic if this class does not declare any constructors, in which case it will
974 * represent the default constructor for the class.
975 *
976 * @return the unnamed constructor defined in this class
977 */
978 ConstructorElement get unnamedConstructor;
979
980 /**
981 * Return `true` if this class or its superclass declares a non-final instance field.
982 *
983 * @return `true` if this class or its superclass declares a non-final instanc e field
984 */
985 bool get hasNonFinalField;
986
987 /**
988 * Return `true` if this class has reference to super (so, for example, cannot be used as a
989 * mixin).
990 *
991 * @return `true` if this class has reference to super
992 */
993 bool get hasReferenceToSuper;
994
995 /**
996 * Return `true` if this class declares a static member.
997 *
998 * @return `true` if this class declares a static member
999 */
1000 bool get hasStaticMember;
1001
1002 /**
1003 * Return `true` if this class is abstract. A class is abstract if it has an e xplicit
1004 * `abstract` modifier. Note, that this definition of <i>abstract</i> is diffe rent from
1005 * <i>has unimplemented members</i>.
1006 *
1007 * @return `true` if this class is abstract
1008 */
1009 bool get isAbstract;
1010
1011 /**
1012 * Return `true` if this class is defined by an enum declaration.
1013 *
1014 * @return `true` if this class is defined by an enum declaration
1015 */
1016 bool get isEnum;
1017
1018 /**
1019 * Return `true` if this class [isProxy], or if it inherits the proxy annotati on
1020 * from a supertype.
1021 *
1022 * @return `true` if this class defines or inherits a proxy
1023 */
1024 bool get isOrInheritsProxy;
1025
1026 /**
1027 * Return `true` if this element has an annotation of the form '@proxy'.
1028 *
1029 * @return `true` if this element defines a proxy
1030 */
1031 bool get isProxy;
1032
1033 /**
1034 * Return `true` if this class is defined by a typedef construct.
1035 *
1036 * @return `true` if this class is defined by a typedef construct
1037 */
1038 bool get isTypedef;
1039
1040 /**
1041 * Return `true` if this class can validly be used as a mixin when defining an other class.
1042 * The behavior of this method is defined by the Dart Language Specification i n section 9:
1043 * <blockquote>It is a compile-time error if a declared or derived mixin refer s to super. It is a
1044 * compile-time error if a declared or derived mixin explicitly declares a con structor. It is a
1045 * compile-time error if a mixin is derived from a class whose superclass is n ot
1046 * Object.</blockquote>
1047 *
1048 * @return `true` if this class can validly be used as a mixin
1049 */
1050 bool get isValidMixin;
1051
1052 /**
1053 * Return the element representing the method that results from looking up the given method in
1054 * this class with respect to the given library, ignoring abstract methods, or `null` if the
1055 * look up fails. The behavior of this method is defined by the Dart Language Specification in
1056 * section 12.15.1: <blockquote> The result of looking up method <i>m</i> in c lass <i>C</i> with
1057 * respect to library <i>L</i> is:
1058 * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
1059 * that method is the result of the lookup. Otherwise, if <i>C</i> has a super class <i>S</i>, then
1060 * the result of the lookup is the result of looking up method <i>m</i> in <i> S</i> with respect
1061 * to <i>L</i>. Otherwise, we say that the lookup has failed.
1062 * </blockquote>
1063 *
1064 * @param methodName the name of the method being looked up
1065 * @param library the library with respect to which the lookup is being perfor med
1066 * @return the result of looking up the given method in this class with respec t to the given
1067 * library
1068 */
1069 MethodElement lookUpConcreteMethod(String methodName, LibraryElement library);
1070
1071 /**
1072 * Return the element representing the getter that results from looking up the given getter in
1073 * this class with respect to the given library, or `null` if the look up fail s. The
1074 * behavior of this method is defined by the Dart Language Specification in se ction 12.15.1:
1075 * <blockquote>The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
1076 * with respect to library <i>L</i> is:
1077 * * If <i>C</i> declares an instance getter (respectively setter) named <i>m< /i> that is
1078 * accessible to <i>L</i>, then that getter (respectively setter) is the resul t of the lookup.
1079 * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lo okup is the result
1080 * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respec t to <i>L</i>.
1081 * Otherwise, we say that the lookup has failed.
1082 * </blockquote>
1083 *
1084 * @param getterName the name of the getter being looked up
1085 * @param library the library with respect to which the lookup is being perfor med
1086 * @return the result of looking up the given getter in this class with respec t to the given
1087 * library
1088 */
1089 PropertyAccessorElement lookUpGetter(String getterName, LibraryElement library );
1090
1091 /**
1092 * Return the element representing the getter that results from looking up the given getter in the
1093 * superclass of this class with respect to the given library, ignoring abstra ct getters, or
1094 * `null` if the look up fails. The behavior of this method is defined by the Dart Language
1095 * Specification in section 12.15.1: <blockquote>The result of looking up gett er (respectively
1096 * setter) <i>m</i> in class <i>C</i> with respect to library <i>L</i> is:
1097 * * If <i>C</i> declares an instance getter (respectively setter) named <i>m< /i> that is
1098 * accessible to <i>L</i>, then that getter (respectively setter) is the resul t of the lookup.
1099 * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lo okup is the result
1100 * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respec t to <i>L</i>.
1101 * Otherwise, we say that the lookup has failed.
1102 * </blockquote>
1103 *
1104 * @param getterName the name of the getter being looked up
1105 * @param library the library with respect to which the lookup is being perfor med
1106 * @return the result of looking up the given getter in this class with respec t to the given
1107 * library
1108 */
1109 PropertyAccessorElement lookUpInheritedConcreteGetter(String getterName, Libra ryElement library);
1110
1111 /**
1112 * Return the element representing the method that results from looking up the given method in the
1113 * superclass of this class with respect to the given library, ignoring abstra ct methods, or
1114 * `null` if the look up fails. The behavior of this method is defined by the Dart Language
1115 * Specification in section 12.15.1: <blockquote> The result of looking up met hod <i>m</i> in
1116 * class <i>C</i> with respect to library <i>L</i> is:
1117 * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
1118 * that method is the result of the lookup. Otherwise, if <i>C</i> has a super class <i>S</i>, then
1119 * the result of the lookup is the result of looking up method <i>m</i> in <i> S</i> with respect
1120 * to <i>L</i>. Otherwise, we say that the lookup has failed.
1121 * </blockquote>
1122 *
1123 * @param methodName the name of the method being looked up
1124 * @param library the library with respect to which the lookup is being perfor med
1125 * @return the result of looking up the given method in the superclass of this class with respect
1126 * to the given library
1127 */
1128 MethodElement lookUpInheritedConcreteMethod(String methodName, LibraryElement library);
1129
1130 /**
1131 * Return the element representing the setter that results from looking up the given setter in the
1132 * superclass of this class with respect to the given library, ignoring abstra ct setters, or
1133 * `null` if the look up fails. The behavior of this method is defined by the Dart Language
1134 * Specification in section 12.16: <blockquote> The result of looking up gette r (respectively
1135 * setter) <i>m</i> in class <i>C</i> with respect to library <i>L</i> is:
1136 * * If <i>C</i> declares an instance getter (respectively setter) named <i>m< /i> that is
1137 * accessible to <i>L</i>, then that getter (respectively setter) is the resul t of the lookup.
1138 * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lo okup is the result
1139 * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respec t to <i>L</i>.
1140 * Otherwise, we say that the lookup has failed.
1141 * </blockquote>
1142 *
1143 * @param setterName the name of the setter being looked up
1144 * @param library the library with respect to which the lookup is being perfor med
1145 * @return the result of looking up the given setter in this class with respec t to the given
1146 * library
1147 */
1148 PropertyAccessorElement lookUpInheritedConcreteSetter(String setterName, Libra ryElement library);
1149
1150 /**
1151 * Return the element representing the method that results from looking up the given method in the
1152 * superclass of this class with respect to the given library, or `null` if th e look up
1153 * fails. The behavior of this method is defined by the Dart Language Specific ation in section
1154 * 12.15.1: <blockquote> The result of looking up method <i>m</i> in class <i> C</i> with respect
1155 * to library <i>L</i> is:
1156 * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
1157 * that method is the result of the lookup. Otherwise, if <i>C</i> has a super class <i>S</i>, then
1158 * the result of the lookup is the result of looking up method <i>m</i> in <i> S</i> with respect
1159 * to <i>L</i>. Otherwise, we say that the lookup has failed.
1160 * </blockquote>
1161 *
1162 * @param methodName the name of the method being looked up
1163 * @param library the library with respect to which the lookup is being perfor med
1164 * @return the result of looking up the given method in the superclass of this class with respect
1165 * to the given library
1166 */
1167 MethodElement lookUpInheritedMethod(String methodName, LibraryElement library) ;
1168
1169 /**
1170 * Return the element representing the method that results from looking up the given method in
1171 * this class with respect to the given library, or `null` if the look up fail s. The
1172 * behavior of this method is defined by the Dart Language Specification in se ction 12.15.1:
1173 * <blockquote> The result of looking up method <i>m</i> in class <i>C</i> wit h respect to library
1174 * <i>L</i> is:
1175 * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
1176 * that method is the result of the lookup. Otherwise, if <i>C</i> has a super class <i>S</i>, then
1177 * the result of the lookup is the result of looking up method <i>m</i> in <i> S</i> with respect
1178 * to <i>L</i>. Otherwise, we say that the lookup has failed.
1179 * </blockquote>
1180 *
1181 * @param methodName the name of the method being looked up
1182 * @param library the library with respect to which the lookup is being perfor med
1183 * @return the result of looking up the given method in this class with respec t to the given
1184 * library
1185 */
1186 MethodElement lookUpMethod(String methodName, LibraryElement library);
1187
1188 /**
1189 * Return the element representing the setter that results from looking up the given setter in
1190 * this class with respect to the given library, or `null` if the look up fail s. The
1191 * behavior of this method is defined by the Dart Language Specification in se ction 12.16:
1192 * <blockquote> The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
1193 * with respect to library <i>L</i> is:
1194 * * If <i>C</i> declares an instance getter (respectively setter) named <i>m< /i> that is
1195 * accessible to <i>L</i>, then that getter (respectively setter) is the resul t of the lookup.
1196 * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lo okup is the result
1197 * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respec t to <i>L</i>.
1198 * Otherwise, we say that the lookup has failed.
1199 * </blockquote>
1200 *
1201 * @param setterName the name of the setter being looked up
1202 * @param library the library with respect to which the lookup is being perfor med
1203 * @return the result of looking up the given setter in this class with respec t to the given
1204 * library
1205 */
1206 PropertyAccessorElement lookUpSetter(String setterName, LibraryElement library );
1207 }
1208
1209 /**
1210 * Instances of the class `ClassElementImpl` implement a `ClassElement`.
1211 */
1212 class ClassElementImpl extends ElementImpl implements ClassElement {
1213 /**
1214 * An array containing all of the accessors (getters and setters) contained in this class.
1215 */
1216 List<PropertyAccessorElement> _accessors = PropertyAccessorElementImpl.EMPTY_A RRAY;
1217
1218 /**
1219 * An array containing all of the constructors contained in this class.
1220 */
1221 List<ConstructorElement> _constructors = ConstructorElementImpl.EMPTY_ARRAY;
1222
1223 /**
1224 * An array containing all of the fields contained in this class.
1225 */
1226 List<FieldElement> _fields = FieldElementImpl.EMPTY_ARRAY;
1227
1228 /**
1229 * An array containing all of the mixins that are applied to the class being e xtended in order to
1230 * derive the superclass of this class.
1231 */
1232 List<InterfaceType> mixins = InterfaceType.EMPTY_ARRAY;
1233
1234 /**
1235 * An array containing all of the interfaces that are implemented by this clas s.
1236 */
1237 List<InterfaceType> interfaces = InterfaceType.EMPTY_ARRAY;
1238
1239 /**
1240 * An array containing all of the methods contained in this class.
1241 */
1242 List<MethodElement> _methods = MethodElementImpl.EMPTY_ARRAY;
1243
1244 /**
1245 * The superclass of the class, or `null` if the class does not have an explic it superclass.
1246 */
1247 InterfaceType supertype;
1248
1249 /**
1250 * An array containing all of the toolkit objects attached to this class.
1251 */
1252 List<ToolkitObjectElement> _toolkitObjects = ToolkitObjectElement.EMPTY_ARRAY;
1253
1254 /**
1255 * The type defined by the class.
1256 */
1257 InterfaceType type;
1258
1259 /**
1260 * An array containing all of the type parameters defined for this class.
1261 */
1262 List<TypeParameterElement> _typeParameters = TypeParameterElementImpl.EMPTY_AR RAY;
1263
1264 /**
1265 * An empty array of class elements.
1266 */
1267 static List<ClassElement> EMPTY_ARRAY = new List<ClassElement>(0);
1268
1269 /**
1270 * Initialize a newly created class element to have the given name.
1271 *
1272 * @param name the name of this element
1273 */
1274 ClassElementImpl.forNode(Identifier name) : super.forNode(name);
1275
1276 /**
1277 * Initialize a newly created class element to have the given name.
1278 *
1279 * @param name the name of this element
1280 * @param nameOffset the offset of the name of this element in the file that c ontains the
1281 * declaration of this element
1282 */
1283 ClassElementImpl(String name, int nameOffset) : super(name, nameOffset);
1284
1285 @override
1286 accept(ElementVisitor visitor) => visitor.visitClassElement(this);
1287
1288 /**
1289 * Set the toolkit specific information objects attached to this class.
1290 *
1291 * @param toolkitObjects the toolkit objects attached to this class
1292 */
1293 void addToolkitObjects(ToolkitObjectElement toolkitObject) {
1294 (toolkitObject as ToolkitObjectElementImpl).enclosingElement = this;
1295 _toolkitObjects = ArrayUtils.add(_toolkitObjects, toolkitObject);
1296 }
1297
1298 @override
1299 List<PropertyAccessorElement> get accessors => _accessors;
1300
1301 @override
1302 List<InterfaceType> get allSupertypes {
1303 List<InterfaceType> list = new List<InterfaceType>();
1304 _collectAllSupertypes(list);
1305 return new List.from(list);
1306 }
1307
1308 @override
1309 ElementImpl getChild(String identifier) {
1310 //
1311 // The casts in this method are safe because the set methods would have thro wn a CCE if any of
1312 // the elements in the arrays were not of the expected types.
1313 //
1314 for (PropertyAccessorElement accessor in _accessors) {
1315 if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
1316 return accessor as PropertyAccessorElementImpl;
1317 }
1318 }
1319 for (ConstructorElement constructor in _constructors) {
1320 if ((constructor as ConstructorElementImpl).identifier == identifier) {
1321 return constructor as ConstructorElementImpl;
1322 }
1323 }
1324 for (FieldElement field in _fields) {
1325 if ((field as FieldElementImpl).identifier == identifier) {
1326 return field as FieldElementImpl;
1327 }
1328 }
1329 for (MethodElement method in _methods) {
1330 if ((method as MethodElementImpl).identifier == identifier) {
1331 return method as MethodElementImpl;
1332 }
1333 }
1334 for (TypeParameterElement typeParameter in _typeParameters) {
1335 if ((typeParameter as TypeParameterElementImpl).identifier == identifier) {
1336 return typeParameter as TypeParameterElementImpl;
1337 }
1338 }
1339 return null;
1340 }
1341
1342 @override
1343 List<ConstructorElement> get constructors => _constructors;
1344
1345 @override
1346 FieldElement getField(String name) {
1347 for (FieldElement fieldElement in _fields) {
1348 if (name == fieldElement.name) {
1349 return fieldElement;
1350 }
1351 }
1352 return null;
1353 }
1354
1355 @override
1356 List<FieldElement> get fields => _fields;
1357
1358 @override
1359 PropertyAccessorElement getGetter(String getterName) {
1360 for (PropertyAccessorElement accessor in _accessors) {
1361 if (accessor.isGetter && accessor.name == getterName) {
1362 return accessor;
1363 }
1364 }
1365 return null;
1366 }
1367
1368 @override
1369 ElementKind get kind => ElementKind.CLASS;
1370
1371 @override
1372 MethodElement getMethod(String methodName) {
1373 for (MethodElement method in _methods) {
1374 if (method.name == methodName) {
1375 return method;
1376 }
1377 }
1378 return null;
1379 }
1380
1381 @override
1382 List<MethodElement> get methods => _methods;
1383
1384 @override
1385 ConstructorElement getNamedConstructor(String name) {
1386 for (ConstructorElement element in constructors) {
1387 String elementName = element.name;
1388 if (elementName != null && elementName == name) {
1389 return element;
1390 }
1391 }
1392 return null;
1393 }
1394
1395 @override
1396 ClassDeclaration get node => getNodeMatching((node) => node is ClassDeclaratio n);
1397
1398 @override
1399 PropertyAccessorElement getSetter(String setterName) {
1400 // TODO (jwren) revisit- should we append '=' here or require clients to inc lude it?
1401 // Do we need the check for isSetter below?
1402 if (!StringUtilities.endsWithChar(setterName, 0x3D)) {
1403 setterName += '=';
1404 }
1405 for (PropertyAccessorElement accessor in _accessors) {
1406 if (accessor.isSetter && accessor.name == setterName) {
1407 return accessor;
1408 }
1409 }
1410 return null;
1411 }
1412
1413 @override
1414 List<ToolkitObjectElement> get toolkitObjects => _toolkitObjects;
1415
1416 @override
1417 List<TypeParameterElement> get typeParameters => _typeParameters;
1418
1419 @override
1420 ConstructorElement get unnamedConstructor {
1421 for (ConstructorElement element in constructors) {
1422 String name = element.displayName;
1423 if (name == null || name.isEmpty) {
1424 return element;
1425 }
1426 }
1427 return null;
1428 }
1429
1430 @override
1431 bool get hasNonFinalField {
1432 List<ClassElement> classesToVisit = new List<ClassElement>();
1433 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
1434 classesToVisit.add(this);
1435 while (!classesToVisit.isEmpty) {
1436 ClassElement currentElement = classesToVisit.removeAt(0);
1437 if (visitedClasses.add(currentElement)) {
1438 // check fields
1439 for (FieldElement field in currentElement.fields) {
1440 if (!field.isFinal && !field.isConst && !field.isStatic && !field.isSy nthetic) {
1441 return true;
1442 }
1443 }
1444 // check mixins
1445 for (InterfaceType mixinType in currentElement.mixins) {
1446 ClassElement mixinElement = mixinType.element;
1447 classesToVisit.add(mixinElement);
1448 }
1449 // check super
1450 InterfaceType supertype = currentElement.supertype;
1451 if (supertype != null) {
1452 ClassElement superElement = supertype.element;
1453 if (superElement != null) {
1454 classesToVisit.add(superElement);
1455 }
1456 }
1457 }
1458 }
1459 // not found
1460 return false;
1461 }
1462
1463 @override
1464 bool get hasReferenceToSuper => hasModifier(Modifier.REFERENCES_SUPER);
1465
1466 @override
1467 bool get hasStaticMember {
1468 for (MethodElement method in _methods) {
1469 if (method.isStatic) {
1470 return true;
1471 }
1472 }
1473 for (PropertyAccessorElement accessor in _accessors) {
1474 if (accessor.isStatic) {
1475 return true;
1476 }
1477 }
1478 return false;
1479 }
1480
1481 @override
1482 bool get isAbstract => hasModifier(Modifier.ABSTRACT);
1483
1484 @override
1485 bool get isEnum => hasModifier(Modifier.ENUM);
1486
1487 @override
1488 bool get isOrInheritsProxy => _safeIsOrInheritsProxy(this, new HashSet<ClassEl ement>());
1489
1490 @override
1491 bool get isProxy {
1492 for (ElementAnnotation annotation in metadata) {
1493 if (annotation.isProxy) {
1494 return true;
1495 }
1496 }
1497 return false;
1498 }
1499
1500 @override
1501 bool get isTypedef => hasModifier(Modifier.TYPEDEF);
1502
1503 @override
1504 bool get isValidMixin => hasModifier(Modifier.MIXIN);
1505
1506 @override
1507 MethodElement lookUpConcreteMethod(String methodName, LibraryElement library) => _internalLookUpConcreteMethod(methodName, library, true);
1508
1509 @override
1510 PropertyAccessorElement lookUpGetter(String getterName, LibraryElement library ) => _internalLookUpGetter(getterName, library, true);
1511
1512 @override
1513 PropertyAccessorElement lookUpInheritedConcreteGetter(String getterName, Libra ryElement library) => _internalLookUpConcreteGetter(getterName, library, false);
1514
1515 @override
1516 MethodElement lookUpInheritedConcreteMethod(String methodName, LibraryElement library) => _internalLookUpConcreteMethod(methodName, library, false);
1517
1518 @override
1519 PropertyAccessorElement lookUpInheritedConcreteSetter(String setterName, Libra ryElement library) => _internalLookUpConcreteSetter(setterName, library, false);
1520
1521 @override
1522 MethodElement lookUpInheritedMethod(String methodName, LibraryElement library) => _internalLookUpMethod(methodName, library, false);
1523
1524 @override
1525 MethodElement lookUpMethod(String methodName, LibraryElement library) => _inte rnalLookUpMethod(methodName, library, true);
1526
1527 @override
1528 PropertyAccessorElement lookUpSetter(String setterName, LibraryElement library ) => _internalLookUpSetter(setterName, library, true);
1529
1530 /**
1531 * Set whether this class is abstract to correspond to the given value.
1532 *
1533 * @param isAbstract `true` if the class is abstract
1534 */
1535 void set abstract(bool isAbstract) {
1536 setModifier(Modifier.ABSTRACT, isAbstract);
1537 }
1538
1539 /**
1540 * Set the accessors contained in this class to the given accessors.
1541 *
1542 * @param accessors the accessors contained in this class
1543 */
1544 void set accessors(List<PropertyAccessorElement> accessors) {
1545 for (PropertyAccessorElement accessor in accessors) {
1546 (accessor as PropertyAccessorElementImpl).enclosingElement = this;
1547 }
1548 this._accessors = accessors;
1549 }
1550
1551 /**
1552 * Set the constructors contained in this class to the given constructors.
1553 *
1554 * @param constructors the constructors contained in this class
1555 */
1556 void set constructors(List<ConstructorElement> constructors) {
1557 for (ConstructorElement constructor in constructors) {
1558 (constructor as ConstructorElementImpl).enclosingElement = this;
1559 }
1560 this._constructors = constructors;
1561 }
1562
1563 /**
1564 * Set whether this class is defined by an enum declaration to correspond to t he given value.
1565 *
1566 * @param isEnum `true` if the class is defined by an enum declaration
1567 */
1568 void set enum2(bool isEnum) {
1569 setModifier(Modifier.ENUM, isEnum);
1570 }
1571
1572 /**
1573 * Set the fields contained in this class to the given fields.
1574 *
1575 * @param fields the fields contained in this class
1576 */
1577 void set fields(List<FieldElement> fields) {
1578 for (FieldElement field in fields) {
1579 (field as FieldElementImpl).enclosingElement = this;
1580 }
1581 this._fields = fields;
1582 }
1583
1584 /**
1585 * Set whether this class references 'super' to the given value.
1586 *
1587 * @param isReferencedSuper `true` references 'super'
1588 */
1589 void set hasReferenceToSuper(bool isReferencedSuper) {
1590 setModifier(Modifier.REFERENCES_SUPER, isReferencedSuper);
1591 }
1592
1593 /**
1594 * Set the methods contained in this class to the given methods.
1595 *
1596 * @param methods the methods contained in this class
1597 */
1598 void set methods(List<MethodElement> methods) {
1599 for (MethodElement method in methods) {
1600 (method as MethodElementImpl).enclosingElement = this;
1601 }
1602 this._methods = methods;
1603 }
1604
1605 /**
1606 * Set whether this class is defined by a typedef construct to correspond to t he given value.
1607 *
1608 * @param isTypedef `true` if the class is defined by a typedef construct
1609 */
1610 void set typedef(bool isTypedef) {
1611 setModifier(Modifier.TYPEDEF, isTypedef);
1612 }
1613
1614 /**
1615 * Set the type parameters defined for this class to the given type parameters .
1616 *
1617 * @param typeParameters the type parameters defined for this class
1618 */
1619 void set typeParameters(List<TypeParameterElement> typeParameters) {
1620 for (TypeParameterElement typeParameter in typeParameters) {
1621 (typeParameter as TypeParameterElementImpl).enclosingElement = this;
1622 }
1623 this._typeParameters = typeParameters;
1624 }
1625
1626 /**
1627 * Set whether this class is a valid mixin to correspond to the given value.
1628 *
1629 * @param isValidMixin `true` if this class can be used as a mixin
1630 */
1631 void set validMixin(bool isValidMixin) {
1632 setModifier(Modifier.MIXIN, isValidMixin);
1633 }
1634
1635 @override
1636 void visitChildren(ElementVisitor visitor) {
1637 super.visitChildren(visitor);
1638 safelyVisitChildren(_accessors, visitor);
1639 safelyVisitChildren(_constructors, visitor);
1640 safelyVisitChildren(_fields, visitor);
1641 safelyVisitChildren(_methods, visitor);
1642 safelyVisitChildren(_toolkitObjects, visitor);
1643 safelyVisitChildren(_typeParameters, visitor);
1644 }
1645
1646 @override
1647 void appendTo(JavaStringBuilder builder) {
1648 String name = displayName;
1649 if (name == null) {
1650 builder.append("{unnamed class}");
1651 } else {
1652 builder.append(name);
1653 }
1654 int variableCount = _typeParameters.length;
1655 if (variableCount > 0) {
1656 builder.append("<");
1657 for (int i = 0; i < variableCount; i++) {
1658 if (i > 0) {
1659 builder.append(", ");
1660 }
1661 (_typeParameters[i] as TypeParameterElementImpl).appendTo(builder);
1662 }
1663 builder.append(">");
1664 }
1665 }
1666
1667 void _collectAllSupertypes(List<InterfaceType> supertypes) {
1668 List<InterfaceType> typesToVisit = new List<InterfaceType>();
1669 List<ClassElement> visitedClasses = new List<ClassElement>();
1670 typesToVisit.add(this.type);
1671 while (!typesToVisit.isEmpty) {
1672 InterfaceType currentType = typesToVisit.removeAt(0);
1673 ClassElement currentElement = currentType.element;
1674 if (!visitedClasses.contains(currentElement)) {
1675 visitedClasses.add(currentElement);
1676 if (!identical(currentType, this.type)) {
1677 supertypes.add(currentType);
1678 }
1679 InterfaceType supertype = currentType.superclass;
1680 if (supertype != null) {
1681 typesToVisit.add(supertype);
1682 }
1683 for (InterfaceType type in currentElement.interfaces) {
1684 typesToVisit.add(type);
1685 }
1686 for (InterfaceType type in currentElement.mixins) {
1687 ClassElement element = type.element;
1688 if (!visitedClasses.contains(element)) {
1689 supertypes.add(type);
1690 }
1691 }
1692 }
1693 }
1694 }
1695
1696 PropertyAccessorElement _internalLookUpConcreteGetter(String getterName, Libra ryElement library, bool includeThisClass) {
1697 PropertyAccessorElement getter = _internalLookUpGetter(getterName, library, includeThisClass);
1698 while (getter != null && getter.isAbstract) {
1699 Element definingClass = getter.enclosingElement;
1700 if (definingClass is! ClassElementImpl) {
1701 return null;
1702 }
1703 getter = (definingClass as ClassElementImpl)._internalLookUpGetter(getterN ame, library, false);
1704 }
1705 return getter;
1706 }
1707
1708 MethodElement _internalLookUpConcreteMethod(String methodName, LibraryElement library, bool includeThisClass) {
1709 MethodElement method = _internalLookUpMethod(methodName, library, includeThi sClass);
1710 while (method != null && method.isAbstract) {
1711 ClassElement definingClass = method.enclosingElement;
1712 if (definingClass == null) {
1713 return null;
1714 }
1715 method = definingClass.lookUpInheritedMethod(methodName, library);
1716 }
1717 return method;
1718 }
1719
1720 PropertyAccessorElement _internalLookUpConcreteSetter(String setterName, Libra ryElement library, bool includeThisClass) {
1721 PropertyAccessorElement setter = _internalLookUpSetter(setterName, library, includeThisClass);
1722 while (setter != null && setter.isAbstract) {
1723 Element definingClass = setter.enclosingElement;
1724 if (definingClass is! ClassElementImpl) {
1725 return null;
1726 }
1727 setter = (definingClass as ClassElementImpl)._internalLookUpSetter(setterN ame, library, false);
1728 }
1729 return setter;
1730 }
1731
1732 PropertyAccessorElement _internalLookUpGetter(String getterName, LibraryElemen t library, bool includeThisClass) {
1733 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
1734 ClassElement currentElement = this;
1735 if (includeThisClass) {
1736 PropertyAccessorElement element = currentElement.getGetter(getterName);
1737 if (element != null && element.isAccessibleIn(library)) {
1738 return element;
1739 }
1740 }
1741 while (currentElement != null && visitedClasses.add(currentElement)) {
1742 for (InterfaceType mixin in currentElement.mixins) {
1743 ClassElement mixinElement = mixin.element;
1744 if (mixinElement != null) {
1745 PropertyAccessorElement element = mixinElement.getGetter(getterName);
1746 if (element != null && element.isAccessibleIn(library)) {
1747 return element;
1748 }
1749 }
1750 }
1751 InterfaceType supertype = currentElement.supertype;
1752 if (supertype == null) {
1753 return null;
1754 }
1755 currentElement = supertype.element;
1756 PropertyAccessorElement element = currentElement.getGetter(getterName);
1757 if (element != null && element.isAccessibleIn(library)) {
1758 return element;
1759 }
1760 }
1761 return null;
1762 }
1763
1764 MethodElement _internalLookUpMethod(String methodName, LibraryElement library, bool includeThisClass) {
1765 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
1766 ClassElement currentElement = this;
1767 if (includeThisClass) {
1768 MethodElement element = currentElement.getMethod(methodName);
1769 if (element != null && element.isAccessibleIn(library)) {
1770 return element;
1771 }
1772 }
1773 while (currentElement != null && visitedClasses.add(currentElement)) {
1774 for (InterfaceType mixin in currentElement.mixins) {
1775 ClassElement mixinElement = mixin.element;
1776 if (mixinElement != null) {
1777 MethodElement element = mixinElement.getMethod(methodName);
1778 if (element != null && element.isAccessibleIn(library)) {
1779 return element;
1780 }
1781 }
1782 }
1783 InterfaceType supertype = currentElement.supertype;
1784 if (supertype == null) {
1785 return null;
1786 }
1787 currentElement = supertype.element;
1788 MethodElement element = currentElement.getMethod(methodName);
1789 if (element != null && element.isAccessibleIn(library)) {
1790 return element;
1791 }
1792 }
1793 return null;
1794 }
1795
1796 PropertyAccessorElement _internalLookUpSetter(String setterName, LibraryElemen t library, bool includeThisClass) {
1797 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
1798 ClassElement currentElement = this;
1799 if (includeThisClass) {
1800 PropertyAccessorElement element = currentElement.getSetter(setterName);
1801 if (element != null && element.isAccessibleIn(library)) {
1802 return element;
1803 }
1804 }
1805 while (currentElement != null && visitedClasses.add(currentElement)) {
1806 for (InterfaceType mixin in currentElement.mixins) {
1807 ClassElement mixinElement = mixin.element;
1808 if (mixinElement != null) {
1809 PropertyAccessorElement element = mixinElement.getSetter(setterName);
1810 if (element != null && element.isAccessibleIn(library)) {
1811 return element;
1812 }
1813 }
1814 }
1815 InterfaceType supertype = currentElement.supertype;
1816 if (supertype == null) {
1817 return null;
1818 }
1819 currentElement = supertype.element;
1820 PropertyAccessorElement element = currentElement.getSetter(setterName);
1821 if (element != null && element.isAccessibleIn(library)) {
1822 return element;
1823 }
1824 }
1825 return null;
1826 }
1827
1828 bool _safeIsOrInheritsProxy(ClassElement classElt, HashSet<ClassElement> visit edClassElts) {
1829 if (visitedClassElts.contains(classElt)) {
1830 return false;
1831 }
1832 visitedClassElts.add(classElt);
1833 if (classElt.isProxy) {
1834 return true;
1835 } else if (classElt.supertype != null && _safeIsOrInheritsProxy(classElt.sup ertype.element, visitedClassElts)) {
1836 return true;
1837 }
1838 List<InterfaceType> supertypes = classElt.interfaces;
1839 for (int i = 0; i < supertypes.length; i++) {
1840 if (_safeIsOrInheritsProxy(supertypes[i].element, visitedClassElts)) {
1841 return true;
1842 }
1843 }
1844 supertypes = classElt.mixins;
1845 for (int i = 0; i < supertypes.length; i++) {
1846 if (_safeIsOrInheritsProxy(supertypes[i].element, visitedClassElts)) {
1847 return true;
1848 }
1849 }
1850 return false;
1851 }
1852 }
1853
1854 /**
1855 * The interface `ClassMemberElement` defines the behavior of elements that are contained
1856 * within a [ClassElement].
1857 */
1858 abstract class ClassMemberElement implements Element {
1859 /**
1860 * Return the type in which this member is defined.
1861 *
1862 * @return the type in which this member is defined
1863 */
1864 @override
1865 ClassElement get enclosingElement;
1866
1867 /**
1868 * Return `true` if this element is a static element. A static element is an e lement that is
1869 * not associated with a particular instance, but rather with an entire librar y or class.
1870 *
1871 * @return `true` if this executable element is a static element
1872 */
1873 bool get isStatic;
1874 }
1875
1876 /**
1877 * The interface `CompilationUnitElement` defines the behavior of elements repre senting a
1878 * compilation unit.
1879 */
1880 abstract class CompilationUnitElement implements Element, UriReferencedElement {
1881 /**
1882 * Return an array containing all of the top-level accessors (getters and sett ers) contained in
1883 * this compilation unit.
1884 *
1885 * @return the top-level accessors contained in this compilation unit
1886 */
1887 List<PropertyAccessorElement> get accessors;
1888
1889 /**
1890 * Return an array containing all of the Angular views defined in this compila tion unit. The array
1891 * will be empty if the element does not have any Angular views or if the comp ilation unit has not
1892 * yet had toolkit references resolved.
1893 *
1894 * @return the Angular views defined in this compilation unit.
1895 */
1896 List<AngularViewElement> get angularViews;
1897
1898 /**
1899 * Return the library in which this compilation unit is defined.
1900 *
1901 * @return the library in which this compilation unit is defined
1902 */
1903 @override
1904 LibraryElement get enclosingElement;
1905
1906 /**
1907 * Return the enum defined in this compilation unit that has the given name, o r `null` if
1908 * this compilation unit does not define an enum with the given name.
1909 *
1910 * @param enumName the name of the enum to be returned
1911 * @return the enum with the given name that is defined in this compilation un it
1912 */
1913 ClassElement getEnum(String enumName);
1914
1915 /**
1916 * Return an array containing all of the enums contained in this compilation u nit.
1917 *
1918 * @return an array containing all of the enums contained in this compilation unit
1919 */
1920 List<ClassElement> get enums;
1921
1922 /**
1923 * Return an array containing all of the top-level functions contained in this compilation unit.
1924 *
1925 * @return the top-level functions contained in this compilation unit
1926 */
1927 List<FunctionElement> get functions;
1928
1929 /**
1930 * Return an array containing all of the function type aliases contained in th is compilation unit.
1931 *
1932 * @return the function type aliases contained in this compilation unit
1933 */
1934 List<FunctionTypeAliasElement> get functionTypeAliases;
1935
1936 /**
1937 * Return the resolved [CompilationUnit] node that declares this element.
1938 *
1939 * This method is expensive, because resolved AST might be evicted from cache, so parsing and
1940 * resolving will be performed.
1941 *
1942 * @return the resolved [CompilationUnit], not `null`.
1943 */
1944 @override
1945 CompilationUnit get node;
1946
1947 /**
1948 * Return an array containing all of the top-level variables contained in this compilation unit.
1949 *
1950 * @return the top-level variables contained in this compilation unit
1951 */
1952 List<TopLevelVariableElement> get topLevelVariables;
1953
1954 /**
1955 * Return the class defined in this compilation unit that has the given name, or `null` if
1956 * this compilation unit does not define a class with the given name.
1957 *
1958 * @param className the name of the class to be returned
1959 * @return the class with the given name that is defined in this compilation u nit
1960 */
1961 ClassElement getType(String className);
1962
1963 /**
1964 * Return an array containing all of the classes contained in this compilation unit.
1965 *
1966 * @return the classes contained in this compilation unit
1967 */
1968 List<ClassElement> get types;
1969
1970 /**
1971 * Return `true` if this compilation unit defines a top-level function named
1972 * `loadLibrary`.
1973 *
1974 * @return `true` if this compilation unit defines a top-level function named
1975 * `loadLibrary`
1976 */
1977 bool get hasLoadLibraryFunction;
1978 }
1979
1980 /**
1981 * Instances of the class `CompilationUnitElementImpl` implement a
1982 * [CompilationUnitElement].
1983 */
1984 class CompilationUnitElementImpl extends UriReferencedElementImpl implements Com pilationUnitElement {
1985 /**
1986 * An empty array of compilation unit elements.
1987 */
1988 static List<CompilationUnitElement> EMPTY_ARRAY = new List<CompilationUnitElem ent>(0);
1989
1990 /**
1991 * The source that corresponds to this compilation unit.
1992 */
1993 Source source;
1994
1995 /**
1996 * An array containing all of the top-level accessors (getters and setters) co ntained in this
1997 * compilation unit.
1998 */
1999 List<PropertyAccessorElement> _accessors = PropertyAccessorElementImpl.EMPTY_A RRAY;
2000
2001 /**
2002 * An array containing all of the enums contained in this compilation unit.
2003 */
2004 List<ClassElement> _enums = ClassElementImpl.EMPTY_ARRAY;
2005
2006 /**
2007 * An array containing all of the top-level functions contained in this compil ation unit.
2008 */
2009 List<FunctionElement> _functions = FunctionElementImpl.EMPTY_ARRAY;
2010
2011 /**
2012 * A table mapping elements to associated toolkit objects.
2013 */
2014 Map<Element, List<ToolkitObjectElement>> _toolkitObjects = {};
2015
2016 /**
2017 * An array containing all of the function type aliases contained in this comp ilation unit.
2018 */
2019 List<FunctionTypeAliasElement> _typeAliases = FunctionTypeAliasElementImpl.EMP TY_ARRAY;
2020
2021 /**
2022 * An array containing all of the types contained in this compilation unit.
2023 */
2024 List<ClassElement> _types = ClassElementImpl.EMPTY_ARRAY;
2025
2026 /**
2027 * An array containing all of the variables contained in this compilation unit .
2028 */
2029 List<TopLevelVariableElement> _variables = TopLevelVariableElementImpl.EMPTY_A RRAY;
2030
2031 /**
2032 * An array containing all of the Angular views contained in this compilation unit.
2033 */
2034 List<AngularViewElement> _angularViews = AngularViewElement.EMPTY_ARRAY;
2035
2036 /**
2037 * Initialize a newly created compilation unit element to have the given name.
2038 *
2039 * @param name the name of this element
2040 */
2041 CompilationUnitElementImpl(String name) : super(name, -1);
2042
2043 @override
2044 accept(ElementVisitor visitor) => visitor.visitCompilationUnitElement(this);
2045
2046 @override
2047 bool operator ==(Object object) => object != null && runtimeType == object.run timeType && source == (object as CompilationUnitElementImpl).source;
2048
2049 @override
2050 List<PropertyAccessorElement> get accessors => _accessors;
2051
2052 @override
2053 List<AngularViewElement> get angularViews => _angularViews;
2054
2055 @override
2056 ElementImpl getChild(String identifier) {
2057 //
2058 // The casts in this method are safe because the set methods would have thro wn a CCE if any of
2059 // the elements in the arrays were not of the expected types.
2060 //
2061 for (PropertyAccessorElement accessor in _accessors) {
2062 if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
2063 return accessor as PropertyAccessorElementImpl;
2064 }
2065 }
2066 for (VariableElement variable in _variables) {
2067 if ((variable as VariableElementImpl).identifier == identifier) {
2068 return variable as VariableElementImpl;
2069 }
2070 }
2071 for (ExecutableElement function in _functions) {
2072 if ((function as ExecutableElementImpl).identifier == identifier) {
2073 return function as ExecutableElementImpl;
2074 }
2075 }
2076 for (FunctionTypeAliasElement typeAlias in _typeAliases) {
2077 if ((typeAlias as FunctionTypeAliasElementImpl).identifier == identifier) {
2078 return typeAlias as FunctionTypeAliasElementImpl;
2079 }
2080 }
2081 for (ClassElement type in _types) {
2082 if ((type as ClassElementImpl).identifier == identifier) {
2083 return type as ClassElementImpl;
2084 }
2085 }
2086 return null;
2087 }
2088
2089 @override
2090 LibraryElement get enclosingElement => super.enclosingElement as LibraryElemen t;
2091
2092 @override
2093 ClassElement getEnum(String enumName) {
2094 for (ClassElement enumDeclaration in _enums) {
2095 if (enumDeclaration.name == enumName) {
2096 return enumDeclaration;
2097 }
2098 }
2099 return null;
2100 }
2101
2102 @override
2103 List<ClassElement> get enums => _enums;
2104
2105 @override
2106 List<FunctionElement> get functions => _functions;
2107
2108 @override
2109 List<FunctionTypeAliasElement> get functionTypeAliases => _typeAliases;
2110
2111 @override
2112 ElementKind get kind => ElementKind.COMPILATION_UNIT;
2113
2114 @override
2115 CompilationUnit get node => unit;
2116
2117 @override
2118 List<TopLevelVariableElement> get topLevelVariables => _variables;
2119
2120 @override
2121 ClassElement getType(String className) {
2122 for (ClassElement type in _types) {
2123 if (type.name == className) {
2124 return type;
2125 }
2126 }
2127 return null;
2128 }
2129
2130 @override
2131 List<ClassElement> get types => _types;
2132
2133 @override
2134 int get hashCode => source.hashCode;
2135
2136 @override
2137 bool get hasLoadLibraryFunction {
2138 for (int i = 0; i < _functions.length; i++) {
2139 if (_functions[i].name == FunctionElement.LOAD_LIBRARY_NAME) {
2140 return true;
2141 }
2142 }
2143 return false;
2144 }
2145
2146 /**
2147 * Set the top-level accessors (getters and setters) contained in this compila tion unit to the
2148 * given accessors.
2149 *
2150 * @param the top-level accessors (getters and setters) contained in this comp ilation unit
2151 */
2152 void set accessors(List<PropertyAccessorElement> accessors) {
2153 for (PropertyAccessorElement accessor in accessors) {
2154 (accessor as PropertyAccessorElementImpl).enclosingElement = this;
2155 }
2156 this._accessors = accessors;
2157 }
2158
2159 /**
2160 * Set the Angular views defined in this compilation unit.
2161 *
2162 * @param angularViews the Angular views defined in this compilation unit
2163 */
2164 void set angularViews(List<AngularViewElement> angularViews) {
2165 for (AngularViewElement view in angularViews) {
2166 (view as AngularViewElementImpl).enclosingElement = this;
2167 }
2168 this._angularViews = angularViews;
2169 }
2170
2171 /**
2172 * Set the enums contained in this compilation unit to the given enums.
2173 *
2174 * @param enums enums contained in this compilation unit
2175 */
2176 void set enums(List<ClassElement> enums) {
2177 for (ClassElement enumDeclaration in enums) {
2178 (enumDeclaration as ClassElementImpl).enclosingElement = this;
2179 }
2180 this._enums = enums;
2181 }
2182
2183 /**
2184 * Set the top-level functions contained in this compilation unit to the given functions.
2185 *
2186 * @param functions the top-level functions contained in this compilation unit
2187 */
2188 void set functions(List<FunctionElement> functions) {
2189 for (FunctionElement function in functions) {
2190 (function as FunctionElementImpl).enclosingElement = this;
2191 }
2192 this._functions = functions;
2193 }
2194
2195 /**
2196 * Set the top-level variables contained in this compilation unit to the given variables.
2197 *
2198 * @param variables the top-level variables contained in this compilation unit
2199 */
2200 void set topLevelVariables(List<TopLevelVariableElement> variables) {
2201 for (TopLevelVariableElement field in variables) {
2202 (field as TopLevelVariableElementImpl).enclosingElement = this;
2203 }
2204 this._variables = variables;
2205 }
2206
2207 /**
2208 * Set the function type aliases contained in this compilation unit to the giv en type aliases.
2209 *
2210 * @param typeAliases the function type aliases contained in this compilation unit
2211 */
2212 void set typeAliases(List<FunctionTypeAliasElement> typeAliases) {
2213 for (FunctionTypeAliasElement typeAlias in typeAliases) {
2214 (typeAlias as FunctionTypeAliasElementImpl).enclosingElement = this;
2215 }
2216 this._typeAliases = typeAliases;
2217 }
2218
2219 /**
2220 * Set the types contained in this compilation unit to the given types.
2221 *
2222 * @param types types contained in this compilation unit
2223 */
2224 void set types(List<ClassElement> types) {
2225 for (ClassElement type in types) {
2226 (type as ClassElementImpl).enclosingElement = this;
2227 }
2228 this._types = types;
2229 }
2230
2231 @override
2232 void visitChildren(ElementVisitor visitor) {
2233 super.visitChildren(visitor);
2234 safelyVisitChildren(_accessors, visitor);
2235 safelyVisitChildren(_functions, visitor);
2236 safelyVisitChildren(_typeAliases, visitor);
2237 safelyVisitChildren(_types, visitor);
2238 safelyVisitChildren(_variables, visitor);
2239 safelyVisitChildren(_angularViews, visitor);
2240 }
2241
2242 @override
2243 void appendTo(JavaStringBuilder builder) {
2244 if (source == null) {
2245 builder.append("{compilation unit}");
2246 } else {
2247 builder.append(source.fullName);
2248 }
2249 }
2250
2251 @override
2252 String get identifier => source.encoding;
2253
2254 /**
2255 * Returns the associated toolkit objects.
2256 *
2257 * @param element the [Element] to get toolkit objects for
2258 * @return the associated toolkit objects, may be empty, but not `null`
2259 */
2260 List<ToolkitObjectElement> _getToolkitObjects(Element element) {
2261 List<ToolkitObjectElement> objects = _toolkitObjects[element];
2262 if (objects != null) {
2263 return objects;
2264 }
2265 return ToolkitObjectElement.EMPTY_ARRAY;
2266 }
2267
2268 /**
2269 * Sets the toolkit objects that are associated with the given [Element].
2270 *
2271 * @param element the [Element] to associate toolkit objects with
2272 * @param objects the toolkit objects to associate
2273 */
2274 void _setToolkitObjects(Element element, List<ToolkitObjectElement> objects) {
2275 _toolkitObjects[element] = objects;
2276 }
2277 }
2278
2279 /**
2280 * Instances of the class `ConstFieldElementImpl` implement a `FieldElement` for a
2281 * 'const' field that has an initializer.
2282 */
2283 class ConstFieldElementImpl extends FieldElementImpl {
2284 /**
2285 * The result of evaluating this variable's initializer.
2286 */
2287 EvaluationResultImpl _result;
2288
2289 /**
2290 * Initialize a newly created field element to have the given name.
2291 *
2292 * @param name the name of this element
2293 */
2294 ConstFieldElementImpl.con1(Identifier name) : super.forNode(name);
2295
2296 /**
2297 * Initialize a newly created synthetic field element to have the given name.
2298 *
2299 * @param name the name of this element
2300 * @param nameOffset the offset of the name of this element in the file that c ontains the
2301 * declaration of this element
2302 */
2303 ConstFieldElementImpl.con2(String name, int offset) : super(name, offset);
2304
2305 @override
2306 EvaluationResultImpl get evaluationResult => _result;
2307
2308 @override
2309 void set evaluationResult(EvaluationResultImpl result) {
2310 this._result = result;
2311 }
2312 }
2313
2314 /**
2315 * Instances of the class `ConstLocalVariableElementImpl` implement a
2316 * `LocalVariableElement` for a local 'const' variable that has an initializer.
2317 */
2318 class ConstLocalVariableElementImpl extends LocalVariableElementImpl {
2319 /**
2320 * The result of evaluating this variable's initializer.
2321 */
2322 EvaluationResultImpl _result;
2323
2324 /**
2325 * Initialize a newly created local variable element to have the given name.
2326 *
2327 * @param name the name of this element
2328 */
2329 ConstLocalVariableElementImpl(Identifier name) : super.forNode(name);
2330
2331 @override
2332 EvaluationResultImpl get evaluationResult => _result;
2333
2334 @override
2335 void set evaluationResult(EvaluationResultImpl result) {
2336 this._result = result;
2337 }
2338 }
2339
2340 /**
2341 * Instances of the class `ConstTopLevelVariableElementImpl` implement a
2342 * `TopLevelVariableElement` for a top-level 'const' variable that has an initia lizer.
2343 */
2344 class ConstTopLevelVariableElementImpl extends TopLevelVariableElementImpl {
2345 /**
2346 * The result of evaluating this variable's initializer.
2347 */
2348 EvaluationResultImpl _result;
2349
2350 /**
2351 * Initialize a newly created top-level variable element to have the given nam e.
2352 *
2353 * @param name the name of this element
2354 */
2355 ConstTopLevelVariableElementImpl(Identifier name) : super.forNode(name);
2356
2357 @override
2358 EvaluationResultImpl get evaluationResult => _result;
2359
2360 @override
2361 void set evaluationResult(EvaluationResultImpl result) {
2362 this._result = result;
2363 }
2364 }
2365
2366 /**
2367 * The interface `ConstructorElement` defines the behavior of elements represent ing a
2368 * constructor or a factory method defined within a type.
2369 */
2370 abstract class ConstructorElement implements ClassMemberElement, ExecutableEleme nt {
2371 /**
2372 * Return the resolved [ConstructorDeclaration] node that declares this
2373 * [ConstructorElement] .
2374 *
2375 * This method is expensive, because resolved AST might be evicted from cache, so parsing and
2376 * resolving will be performed.
2377 *
2378 * @return the resolved [ConstructorDeclaration], not `null`.
2379 */
2380 @override
2381 ConstructorDeclaration get node;
2382
2383 /**
2384 * Return the constructor to which this constructor is redirecting, or `null` if this
2385 * constructor does not redirect to another constructor or if the library cont aining this
2386 * constructor has not yet been resolved.
2387 *
2388 * @return the constructor to which this constructor is redirecting
2389 */
2390 ConstructorElement get redirectedConstructor;
2391
2392 /**
2393 * Return `true` if this constructor is a const constructor.
2394 *
2395 * @return `true` if this constructor is a const constructor
2396 */
2397 bool get isConst;
2398
2399 /**
2400 * Return `true` if this constructor can be used as a default constructor - un named and has
2401 * no required parameters.
2402 *
2403 * @return `true` if this constructor can be used as a default constructor.
2404 */
2405 bool get isDefaultConstructor;
2406
2407 /**
2408 * Return `true` if this constructor represents a factory constructor.
2409 *
2410 * @return `true` if this constructor represents a factory constructor
2411 */
2412 bool get isFactory;
2413 }
2414
2415 /**
2416 * Instances of the class `ConstructorElementImpl` implement a `ConstructorEleme nt`.
2417 */
2418 class ConstructorElementImpl extends ExecutableElementImpl implements Constructo rElement {
2419 /**
2420 * An empty array of constructor elements.
2421 */
2422 static List<ConstructorElement> EMPTY_ARRAY = new List<ConstructorElement>(0);
2423
2424 /**
2425 * The constructor to which this constructor is redirecting.
2426 */
2427 ConstructorElement redirectedConstructor;
2428
2429 /**
2430 * The initializers for this constructor (used for evaluating constant instanc e creation
2431 * expressions).
2432 */
2433 List<ConstructorInitializer> constantInitializers;
2434
2435 /**
2436 * Initialize a newly created constructor element to have the given name.
2437 *
2438 * @param name the name of this element
2439 */
2440 ConstructorElementImpl.forNode(Identifier name) : super.forNode(name);
2441
2442 /**
2443 * Initialize a newly created constructor element to have the given name.
2444 *
2445 * @param name the name of this element
2446 * @param nameOffset the offset of the name of this element in the file that c ontains the
2447 * declaration of this element
2448 */
2449 ConstructorElementImpl(String name, int nameOffset) : super(name, nameOffset);
2450
2451 @override
2452 accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
2453
2454 @override
2455 ClassElement get enclosingElement => super.enclosingElement as ClassElement;
2456
2457 @override
2458 ElementKind get kind => ElementKind.CONSTRUCTOR;
2459
2460 @override
2461 ConstructorDeclaration get node => getNodeMatching((node) => node is Construct orDeclaration);
2462
2463 @override
2464 bool get isConst => hasModifier(Modifier.CONST);
2465
2466 @override
2467 bool get isDefaultConstructor {
2468 // unnamed
2469 String name = this.name;
2470 if (name != null && name.length != 0) {
2471 return false;
2472 }
2473 // no required parameters
2474 for (ParameterElement parameter in parameters) {
2475 if (parameter.parameterKind == ParameterKind.REQUIRED) {
2476 return false;
2477 }
2478 }
2479 // OK, can be used as default constructor
2480 return true;
2481 }
2482
2483 @override
2484 bool get isFactory => hasModifier(Modifier.FACTORY);
2485
2486 @override
2487 bool get isStatic => false;
2488
2489 /**
2490 * Set whether this constructor represents a 'const' constructor to the given value.
2491 *
2492 * @param isConst `true` if this constructor represents a 'const' constructor
2493 */
2494 void set const2(bool isConst) {
2495 setModifier(Modifier.CONST, isConst);
2496 }
2497
2498 /**
2499 * Set whether this constructor represents a factory method to the given value .
2500 *
2501 * @param isFactory `true` if this constructor represents a factory method
2502 */
2503 void set factory(bool isFactory) {
2504 setModifier(Modifier.FACTORY, isFactory);
2505 }
2506
2507 @override
2508 void appendTo(JavaStringBuilder builder) {
2509 builder.append(enclosingElement.displayName);
2510 String name = displayName;
2511 if (name != null && !name.isEmpty) {
2512 builder.append(".");
2513 builder.append(name);
2514 }
2515 super.appendTo(builder);
2516 }
2517 }
2518
2519 /**
2520 * Instances of the class `ConstructorMember` represent a constructor element de fined in a
2521 * parameterized type where the values of the type parameters are known.
2522 */
2523 class ConstructorMember extends ExecutableMember implements ConstructorElement {
2524 /**
2525 * If the given constructor's type is different when any type parameters from the defining type's
2526 * declaration are replaced with the actual type arguments from the defining t ype, create a
2527 * constructor member representing the given constructor. Return the member th at was created, or
2528 * the base constructor if no member was created.
2529 *
2530 * @param baseConstructor the base constructor for which a member might be cre ated
2531 * @param definingType the type defining the parameters and arguments to be us ed in the
2532 * substitution
2533 * @return the constructor element that will return the correctly substituted types
2534 */
2535 static ConstructorElement from(ConstructorElement baseConstructor, InterfaceTy pe definingType) {
2536 if (baseConstructor == null || definingType.typeArguments.length == 0) {
2537 return baseConstructor;
2538 }
2539 FunctionType baseType = baseConstructor.type;
2540 if (baseType == null) {
2541 // TODO(brianwilkerson) We need to understand when this can happen.
2542 return baseConstructor;
2543 }
2544 List<DartType> argumentTypes = definingType.typeArguments;
2545 List<DartType> parameterTypes = definingType.element.type.typeArguments;
2546 FunctionType substitutedType = baseType.substitute2(argumentTypes, parameter Types);
2547 if (baseType == substitutedType) {
2548 return baseConstructor;
2549 }
2550 // TODO(brianwilkerson) Consider caching the substituted type in the instanc e. It would use more
2551 // memory but speed up some operations. We need to see how often the type is being re-computed.
2552 return new ConstructorMember(baseConstructor, definingType);
2553 }
2554
2555 /**
2556 * Initialize a newly created element to represent a constructor of the given parameterized type.
2557 *
2558 * @param baseElement the element on which the parameterized element was creat ed
2559 * @param definingType the type in which the element is defined
2560 */
2561 ConstructorMember(ConstructorElement baseElement, InterfaceType definingType) : super(baseElement, definingType);
2562
2563 @override
2564 accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
2565
2566 @override
2567 ConstructorElement get baseElement => super.baseElement as ConstructorElement;
2568
2569 @override
2570 ClassElement get enclosingElement => baseElement.enclosingElement;
2571
2572 @override
2573 ConstructorDeclaration get node => baseElement.node;
2574
2575 @override
2576 ConstructorElement get redirectedConstructor => from(baseElement.redirectedCon structor, definingType);
2577
2578 @override
2579 bool get isConst => baseElement.isConst;
2580
2581 @override
2582 bool get isDefaultConstructor => baseElement.isDefaultConstructor;
2583
2584 @override
2585 bool get isFactory => baseElement.isFactory;
2586
2587 @override
2588 String toString() {
2589 ConstructorElement baseElement = this.baseElement;
2590 List<ParameterElement> parameters = this.parameters;
2591 FunctionType type = this.type;
2592 JavaStringBuilder builder = new JavaStringBuilder();
2593 builder.append(baseElement.enclosingElement.displayName);
2594 String name = displayName;
2595 if (name != null && !name.isEmpty) {
2596 builder.append(".");
2597 builder.append(name);
2598 }
2599 builder.append("(");
2600 int parameterCount = parameters.length;
2601 for (int i = 0; i < parameterCount; i++) {
2602 if (i > 0) {
2603 builder.append(", ");
2604 }
2605 builder.append(parameters[i]).toString();
2606 }
2607 builder.append(")");
2608 if (type != null) {
2609 builder.append(Element.RIGHT_ARROW);
2610 builder.append(type.returnType);
2611 }
2612 return builder.toString();
2613 }
2614
2615 @override
2616 InterfaceType get definingType => super.definingType as InterfaceType;
2617 }
2618
2619 /**
2620 * The interface `Type` defines the behavior of objects representing the declare d type of
2621 * elements in the element model.
2622 */
2623 abstract class DartType {
2624 /**
2625 * Return the name of this type as it should appear when presented to users in contexts such as
2626 * error messages.
2627 *
2628 * @return the name of this type
2629 */
2630 String get displayName;
2631
2632 /**
2633 * Return the element representing the declaration of this type, or `null` if the type has
2634 * not, or cannot, be associated with an element. The former case will occur i f the element model
2635 * is not yet complete; the latter case will occur if this object represents a n undefined type.
2636 *
2637 * @return the element representing the declaration of this type
2638 */
2639 Element get element;
2640
2641 /**
2642 * Return the least upper bound of this type and the given type, or `null` if there is no
2643 * least upper bound.
2644 *
2645 * @param type the other type used to compute the least upper bound
2646 * @return the least upper bound of this type and the given type
2647 */
2648 DartType getLeastUpperBound(DartType type);
2649
2650 /**
2651 * Return the name of this type, or `null` if the type does not have a name, s uch as when
2652 * the type represents the type of an unnamed function.
2653 *
2654 * @return the name of this type
2655 */
2656 String get name;
2657
2658 /**
2659 * Return `true` if this type is assignable to the given type. A type <i>T</i> may be
2660 * assigned to a type <i>S</i>, written <i>T</i> &hArr; <i>S</i>, iff either < i>T</i> <: <i>S</i>
2661 * or <i>S</i> <: <i>T</i>.
2662 *
2663 * @param type the type being compared with this type
2664 * @return `true` if this type is assignable to the given type
2665 */
2666 bool isAssignableTo(DartType type);
2667
2668 /**
2669 * Return `true` if this type represents the bottom type.
2670 *
2671 * @return `true` if this type represents the bottom type
2672 */
2673 bool get isBottom;
2674
2675 /**
2676 * Return `true` if this type represents the type 'Function' defined in the da rt:core
2677 * library.
2678 *
2679 * @return `true` if this type represents the type 'Function' defined in the d art:core
2680 * library
2681 */
2682 bool get isDartCoreFunction;
2683
2684 /**
2685 * Return `true` if this type represents the type 'dynamic'.
2686 *
2687 * @return `true` if this type represents the type 'dynamic'
2688 */
2689 bool get isDynamic;
2690
2691 /**
2692 * Return `true` if this type is more specific than the given type.
2693 *
2694 * @param type the type being compared with this type
2695 * @return `true` if this type is more specific than the given type
2696 */
2697 bool isMoreSpecificThan(DartType type);
2698
2699 /**
2700 * Return `true` if this type represents the type 'Object'.
2701 *
2702 * @return `true` if this type represents the type 'Object'
2703 */
2704 bool get isObject;
2705
2706 /**
2707 * Return `true` if this type is a subtype of the given type.
2708 *
2709 * @param type the type being compared with this type
2710 * @return `true` if this type is a subtype of the given type
2711 */
2712 bool isSubtypeOf(DartType type);
2713
2714 /**
2715 * Return `true` if this type is a supertype of the given type. A type <i>S</i > is a
2716 * supertype of <i>T</i>, written <i>S</i> :> <i>T</i>, iff <i>T</i> is a subt ype of <i>S</i>.
2717 *
2718 * @param type the type being compared with this type
2719 * @return `true` if this type is a supertype of the given type
2720 */
2721 bool isSupertypeOf(DartType type);
2722
2723 /**
2724 * Return `true` if this type represents the type 'void'.
2725 *
2726 * @return `true` if this type represents the type 'void'
2727 */
2728 bool get isVoid;
2729
2730 /**
2731 * Return the type resulting from substituting the given arguments for the giv en parameters in
2732 * this type. The specification defines this operation in section 2: <blockquo te> The notation
2733 * <i>[x<sub>1</sub>, ..., x<sub>n</sub>/y<sub>1</sub>, ..., y<sub>n</sub>]E</ i> denotes a copy of
2734 * <i>E</i> in which all occurrences of <i>y<sub>i</sub>, 1 <= i <= n</i> have been replaced with
2735 * <i>x<sub>i</sub></i>.</blockquote> Note that, contrary to the specification , this method will
2736 * not create a copy of this type if no substitutions were required, but will return this type
2737 * directly.
2738 *
2739 * @param argumentTypes the actual type arguments being substituted for the pa rameters
2740 * @param parameterTypes the parameters to be replaced
2741 * @return the result of performing the substitution
2742 */
2743 DartType substitute2(List<DartType> argumentTypes, List<DartType> parameterTyp es);
2744 }
2745
2746 /**
2747 * Instances of the class `DefaultFieldFormalParameterElementImpl` implement a
2748 * `FieldFormalParameterElementImpl` for parameters that have an initializer.
2749 */
2750 class DefaultFieldFormalParameterElementImpl extends FieldFormalParameterElement Impl {
2751 /**
2752 * The result of evaluating this variable's initializer.
2753 */
2754 EvaluationResultImpl _result;
2755
2756 /**
2757 * Initialize a newly created parameter element to have the given name.
2758 *
2759 * @param name the name of this element
2760 */
2761 DefaultFieldFormalParameterElementImpl(Identifier name) : super(name);
2762
2763 @override
2764 EvaluationResultImpl get evaluationResult => _result;
2765
2766 @override
2767 void set evaluationResult(EvaluationResultImpl result) {
2768 this._result = result;
2769 }
2770 }
2771
2772 /**
2773 * Instances of the class `DefaultParameterElementImpl` implement a `ParameterEl ement`
2774 * for parameters that have an initializer.
2775 */
2776 class DefaultParameterElementImpl extends ParameterElementImpl {
2777 /**
2778 * The result of evaluating this variable's initializer.
2779 */
2780 EvaluationResultImpl _result;
2781
2782 /**
2783 * Initialize a newly created parameter element to have the given name.
2784 *
2785 * @param name the name of this element
2786 */
2787 DefaultParameterElementImpl(Identifier name) : super.forNode(name);
2788
2789 @override
2790 EvaluationResultImpl get evaluationResult => _result;
2791
2792 @override
2793 void set evaluationResult(EvaluationResultImpl result) {
2794 this._result = result;
2795 }
2796 }
2797
2798 /**
2799 * Instances of the class `DynamicElementImpl` represent the synthetic element r epresenting
2800 * the declaration of the type `dynamic`.
2801 */
2802 class DynamicElementImpl extends ElementImpl {
2803 /**
2804 * Return the unique instance of this class.
2805 *
2806 * @return the unique instance of this class
2807 */
2808 static DynamicElementImpl get instance => DynamicTypeImpl.instance.element as DynamicElementImpl;
2809
2810 /**
2811 * The type defined by this element.
2812 */
2813 DynamicTypeImpl type;
2814
2815 /**
2816 * Initialize a newly created instance of this class. Instances of this class should <b>not</b> be
2817 * created except as part of creating the type associated with this element. T he single instance
2818 * of this class should be accessed through the method [getInstance].
2819 */
2820 DynamicElementImpl() : super(Keyword.DYNAMIC.syntax, -1) {
2821 setModifier(Modifier.SYNTHETIC, true);
2822 }
2823
2824 @override
2825 accept(ElementVisitor visitor) => null;
2826
2827 @override
2828 ElementKind get kind => ElementKind.DYNAMIC;
2829 }
2830
2831 /**
2832 * The unique instance of the class `DynamicTypeImpl` implements the type `dynam ic`.
2833 */
2834 class DynamicTypeImpl extends TypeImpl {
2835 /**
2836 * The unique instance of this class.
2837 */
2838 static DynamicTypeImpl _INSTANCE = new DynamicTypeImpl();
2839
2840 /**
2841 * Return the unique instance of this class.
2842 *
2843 * @return the unique instance of this class
2844 */
2845 static DynamicTypeImpl get instance => _INSTANCE;
2846
2847 /**
2848 * Prevent the creation of instances of this class.
2849 */
2850 DynamicTypeImpl() : super(new DynamicElementImpl(), Keyword.DYNAMIC.syntax) {
2851 (element as DynamicElementImpl).type = this;
2852 }
2853
2854 @override
2855 bool operator ==(Object object) => identical(object, this);
2856
2857 @override
2858 int get hashCode => 1;
2859
2860 @override
2861 bool get isDynamic => true;
2862
2863 @override
2864 bool isSupertypeOf(DartType type) => true;
2865
2866 @override
2867 DartType substitute2(List<DartType> argumentTypes, List<DartType> parameterTyp es) {
2868 int length = parameterTypes.length;
2869 for (int i = 0; i < length; i++) {
2870 if (parameterTypes[i] == this) {
2871 return argumentTypes[i];
2872 }
2873 }
2874 return this;
2875 }
2876
2877 @override
2878 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => id entical(object, this);
2879
2880 @override
2881 bool internalIsMoreSpecificThan(DartType type, bool withDynamic, Set<TypeImpl_ TypePair> visitedTypePairs) {
2882 // T is S
2883 if (identical(this, type)) {
2884 return true;
2885 }
2886 // else
2887 return withDynamic;
2888 }
2889
2890 @override
2891 bool internalIsSubtypeOf(DartType type, Set<TypeImpl_TypePair> visitedTypePair s) => true;
2892 }
2893
2894 /**
2895 * The interface `Element` defines the behavior common to all of the elements in the element
2896 * model. Generally speaking, the element model is a semantic model of the progr am that represents
2897 * things that are declared with a name and hence can be referenced elsewhere in the code.
2898 *
2899 * There are two exceptions to the general case. First, there are elements in th e element model that
2900 * are created for the convenience of various kinds of analysis but that do not have any
2901 * corresponding declaration within the source code. Such elements are marked as being
2902 * <i>synthetic</i>. Examples of synthetic elements include
2903 * * default constructors in classes that do not define any explicit constructor s,
2904 * * getters and setters that are induced by explicit field declarations,
2905 * * fields that are induced by explicit declarations of getters and setters, an d
2906 * * functions representing the initialization expression for a variable.
2907 *
2908 * Second, there are elements in the element model that do not have a name. Thes e correspond to
2909 * unnamed functions and exist in order to more accurately represent the semanti c structure of the
2910 * program.
2911 */
2912 abstract class Element {
2913 /**
2914 * An Unicode right arrow.
2915 */
2916 static final String RIGHT_ARROW = " \u2192 ";
2917
2918 /**
2919 * A comparator that can be used to sort elements by their name offset. Elemen ts with a smaller
2920 * offset will be sorted to be before elements with a larger name offset.
2921 */
2922 static final Comparator<Element> SORT_BY_OFFSET = (Element firstElement, Eleme nt secondElement) => firstElement.nameOffset - secondElement.nameOffset;
2923
2924 /**
2925 * Use the given visitor to visit this element.
2926 *
2927 * @param visitor the visitor that will visit this element
2928 * @return the value returned by the visitor as a result of visiting this elem ent
2929 */
2930 accept(ElementVisitor visitor);
2931
2932 /**
2933 * Return the documentation comment for this element as it appears in the orig inal source
2934 * (complete with the beginning and ending delimiters), or `null` if this elem ent does not
2935 * have a documentation comment associated with it. This can be a long-running operation if the
2936 * information needed to access the comment is not cached.
2937 *
2938 * @return this element's documentation comment
2939 * @throws AnalysisException if the documentation comment could not be determi ned because the
2940 * analysis could not be performed
2941 */
2942 String computeDocumentationComment();
2943
2944 /**
2945 * Return the element of the given class that most immediately encloses this e lement, or
2946 * `null` if there is no enclosing element of the given class.
2947 *
2948 * @param elementClass the class of the element to be returned
2949 * @return the element that encloses this element
2950 */
2951 Element getAncestor(Predicate<Element> predicate);
2952
2953 /**
2954 * Return the analysis context in which this element is defined.
2955 *
2956 * @return the analysis context in which this element is defined
2957 */
2958 AnalysisContext get context;
2959
2960 /**
2961 * Return the display name of this element, or `null` if this element does not have a name.
2962 *
2963 * In most cases the name and the display name are the same. Differences thoug h are cases such as
2964 * setters where the name of some setter `set f(x)` is `f=`, instead of `f`.
2965 *
2966 * @return the display name of this element
2967 */
2968 String get displayName;
2969
2970 /**
2971 * Return the element that either physically or logically encloses this elemen t. This will be
2972 * `null` if this element is a library because libraries are the top-level ele ments in the
2973 * model.
2974 *
2975 * @return the element that encloses this element
2976 */
2977 Element get enclosingElement;
2978
2979 /**
2980 * Return a display name for the given element that includes the path to the c ompilation unit in
2981 * which the type is defined.
2982 *
2983 * @param shortName the short display name. If null, [getDisplayName] is used.
2984 * @return a display name that can help distinguish between two types with the same name
2985 */
2986 String getExtendedDisplayName(String shortName);
2987
2988 /**
2989 * Return the kind of element that this is.
2990 *
2991 * @return the kind of this element
2992 */
2993 ElementKind get kind;
2994
2995 /**
2996 * Return the library that contains this element. This will be the element its elf if it is a
2997 * library element. This will be `null` if this element is an HTML file becaus e HTML files
2998 * are not contained in libraries.
2999 *
3000 * @return the library that contains this element
3001 */
3002 LibraryElement get library;
3003
3004 /**
3005 * Return an object representing the location of this element in the element m odel. The object can
3006 * be used to locate this element at a later time.
3007 *
3008 * @return the location of this element in the element model
3009 */
3010 ElementLocation get location;
3011
3012 /**
3013 * Return an array containing all of the metadata associated with this element . The array will be
3014 * empty if the element does not have any metadata or if the library containin g this element has
3015 * not yet been resolved.
3016 *
3017 * @return the metadata associated with this element
3018 */
3019 List<ElementAnnotation> get metadata;
3020
3021 /**
3022 * Return the name of this element, or `null` if this element does not have a name.
3023 *
3024 * @return the name of this element
3025 */
3026 String get name;
3027
3028 /**
3029 * Return the offset of the name of this element in the file that contains the declaration of this
3030 * element, or `-1` if this element is synthetic, does not have a name, or oth erwise does
3031 * not have an offset.
3032 *
3033 * @return the offset of the name of this element
3034 */
3035 int get nameOffset;
3036
3037 /**
3038 * Return the resolved [AstNode] node that declares this [Element].
3039 *
3040 * This method is expensive, because resolved AST might be evicted from cache, so parsing and
3041 * resolving will be performed.
3042 *
3043 * <b>Note:</b> This method cannot be used in an async environment.
3044 *
3045 * @return the resolved [AstNode], maybe `null` if [Element] is synthetic or
3046 * isn't contained in a compilation unit, such as a [LibraryElement].
3047 */
3048 AstNode get node;
3049
3050 /**
3051 * Return the source that contains this element, or `null` if this element is not contained
3052 * in a source.
3053 *
3054 * @return the source that contains this element
3055 */
3056 Source get source;
3057
3058 /**
3059 * Return the resolved [CompilationUnit] that declares this [Element].
3060 *
3061 * This method is expensive, because resolved AST might have been already evic ted from cache, so
3062 * parsing and resolving will be performed.
3063 *
3064 * @return the resolved [CompilationUnit], maybe `null` if synthetic [Element] .
3065 */
3066 CompilationUnit get unit;
3067
3068 /**
3069 * Return `true` if this element, assuming that it is within scope, is accessi ble to code in
3070 * the given library. This is defined by the Dart Language Specification in se ction 3.2:
3071 * <blockquote> A declaration <i>m</i> is accessible to library <i>L</i> if <i >m</i> is declared
3072 * in <i>L</i> or if <i>m</i> is public. </blockquote>
3073 *
3074 * @param library the library in which a possible reference to this element wo uld occur
3075 * @return `true` if this element is accessible to code in the given library
3076 */
3077 bool isAccessibleIn(LibraryElement library);
3078
3079 /**
3080 * Return `true` if this element has an annotation of the form '@deprecated' o r
3081 * '@Deprecated('..')'.
3082 *
3083 * @return `true` if this element is deprecated
3084 */
3085 bool get isDeprecated;
3086
3087 /**
3088 * Return `true` if this element has an annotation of the form '@override'.
3089 *
3090 * @return `true` if this element is overridden
3091 */
3092 bool get isOverride;
3093
3094 /**
3095 * Return `true` if this element is private. Private elements are visible only within the
3096 * library in which they are declared.
3097 *
3098 * @return `true` if this element is private
3099 */
3100 bool get isPrivate;
3101
3102 /**
3103 * Return `true` if this element is public. Public elements are visible within any library
3104 * that imports the library in which they are declared.
3105 *
3106 * @return `true` if this element is public
3107 */
3108 bool get isPublic;
3109
3110 /**
3111 * Return `true` if this element is synthetic. A synthetic element is an eleme nt that is not
3112 * represented in the source code explicitly, but is implied by the source cod e, such as the
3113 * default constructor for a class that does not explicitly define any constru ctors.
3114 *
3115 * @return `true` if this element is synthetic
3116 */
3117 bool get isSynthetic;
3118
3119 /**
3120 * Use the given visitor to visit all of the children of this element. There i s no guarantee of
3121 * the order in which the children will be visited.
3122 *
3123 * @param visitor the visitor that will be used to visit the children of this element
3124 */
3125 void visitChildren(ElementVisitor visitor);
3126 }
3127
3128 /**
3129 * The interface `ElementAnnotation` defines the behavior of objects representin g a single
3130 * annotation associated with an element.
3131 */
3132 abstract class ElementAnnotation {
3133 /**
3134 * Return the element representing the field, variable, or const constructor b eing used as an
3135 * annotation.
3136 *
3137 * @return the field, variable, or constructor being used as an annotation
3138 */
3139 Element get element;
3140
3141 /**
3142 * Return `true` if this annotation marks the associated element as being depr ecated.
3143 *
3144 * @return `true` if this annotation marks the associated element as being dep recated
3145 */
3146 bool get isDeprecated;
3147
3148 /**
3149 * Return `true` if this annotation marks the associated method as being expec ted to
3150 * override an inherited method.
3151 *
3152 * @return `true` if this annotation marks the associated method as overriding another
3153 * method
3154 */
3155 bool get isOverride;
3156
3157 /**
3158 * Return `true` if this annotation marks the associated class as implementing a proxy
3159 * object.
3160 *
3161 * @return `true` if this annotation marks the associated class as implementin g a proxy
3162 * object
3163 */
3164 bool get isProxy;
3165 }
3166
3167 /**
3168 * Instances of the class `ElementAnnotationImpl` implement an [ElementAnnotatio n].
3169 */
3170 class ElementAnnotationImpl implements ElementAnnotation {
3171 /**
3172 * The element representing the field, variable, or constructor being used as an annotation.
3173 */
3174 final Element element;
3175
3176 /**
3177 * An empty array of annotations.
3178 */
3179 static List<ElementAnnotationImpl> EMPTY_ARRAY = new List<ElementAnnotationImp l>(0);
3180
3181 /**
3182 * The name of the class used to mark an element as being deprecated.
3183 */
3184 static String _DEPRECATED_CLASS_NAME = "Deprecated";
3185
3186 /**
3187 * The name of the top-level variable used to mark an element as being depreca ted.
3188 */
3189 static String _DEPRECATED_VARIABLE_NAME = "deprecated";
3190
3191 /**
3192 * The name of the top-level variable used to mark a method as being expected to override an
3193 * inherited method.
3194 */
3195 static String _OVERRIDE_VARIABLE_NAME = "override";
3196
3197 /**
3198 * The name of the top-level variable used to mark a class as implementing a p roxy object.
3199 */
3200 static String PROXY_VARIABLE_NAME = "proxy";
3201
3202 /**
3203 * Initialize a newly created annotation.
3204 *
3205 * @param element the element representing the field, variable, or constructor being used as an
3206 * annotation
3207 */
3208 ElementAnnotationImpl(this.element);
3209
3210 @override
3211 bool get isDeprecated {
3212 if (element != null) {
3213 LibraryElement library = element.library;
3214 if (library != null && library.isDartCore) {
3215 if (element is ConstructorElement) {
3216 ConstructorElement constructorElement = element as ConstructorElement;
3217 if (constructorElement.enclosingElement.name == _DEPRECATED_CLASS_NAME ) {
3218 return true;
3219 }
3220 } else if (element is PropertyAccessorElement && element.name == _DEPREC ATED_VARIABLE_NAME) {
3221 return true;
3222 }
3223 }
3224 }
3225 return false;
3226 }
3227
3228 @override
3229 bool get isOverride {
3230 if (element != null) {
3231 LibraryElement library = element.library;
3232 if (library != null && library.isDartCore) {
3233 if (element is PropertyAccessorElement && element.name == _OVERRIDE_VARI ABLE_NAME) {
3234 return true;
3235 }
3236 }
3237 }
3238 return false;
3239 }
3240
3241 @override
3242 bool get isProxy {
3243 if (element != null) {
3244 LibraryElement library = element.library;
3245 if (library != null && library.isDartCore) {
3246 if (element is PropertyAccessorElement && element.name == PROXY_VARIABLE _NAME) {
3247 return true;
3248 }
3249 }
3250 }
3251 return false;
3252 }
3253
3254 @override
3255 String toString() => "@${element.toString()}";
3256 }
3257
3258 /**
3259 * The abstract class `ElementImpl` implements the behavior common to objects th at implement
3260 * an [Element].
3261 */
3262 abstract class ElementImpl implements Element {
3263 /**
3264 * The enclosing element of this element, or `null` if this element is at the root of the
3265 * element structure.
3266 */
3267 ElementImpl _enclosingElement;
3268
3269 /**
3270 * The name of this element.
3271 */
3272 String _name;
3273
3274 /**
3275 * The offset of the name of this element in the file that contains the declar ation of this
3276 * element.
3277 */
3278 int nameOffset = 0;
3279
3280 /**
3281 * A bit-encoded form of the modifiers associated with this element.
3282 */
3283 int _modifiers = 0;
3284
3285 /**
3286 * An array containing all of the metadata associated with this element.
3287 */
3288 List<ElementAnnotation> metadata = ElementAnnotationImpl.EMPTY_ARRAY;
3289
3290 /**
3291 * A cached copy of the calculated hashCode for this element.
3292 */
3293 int _cachedHashCode = 0;
3294
3295 /**
3296 * Initialize a newly created element to have the given name.
3297 *
3298 * @param name the name of this element
3299 */
3300 ElementImpl.forNode(Identifier name) : this(name == null ? "" : name.name, nam e == null ? -1 : name.offset);
3301
3302 /**
3303 * Initialize a newly created element to have the given name.
3304 *
3305 * @param name the name of this element
3306 * @param nameOffset the offset of the name of this element in the file that c ontains the
3307 * declaration of this element
3308 */
3309 ElementImpl(String name, this.nameOffset) {
3310 this._name = StringUtilities.intern(name);
3311 }
3312
3313 @override
3314 String computeDocumentationComment() {
3315 AnalysisContext context = this.context;
3316 if (context == null) {
3317 return null;
3318 }
3319 return context.computeDocumentationComment(this);
3320 }
3321
3322 @override
3323 bool operator ==(Object object) {
3324 if (identical(this, object)) {
3325 return true;
3326 }
3327 if (object == null || hashCode != object.hashCode) {
3328 return false;
3329 }
3330 return object.runtimeType == runtimeType && (object as Element).location == location;
3331 }
3332
3333 @override
3334 Element getAncestor(Predicate<Element> predicate) {
3335 Element ancestor = _enclosingElement;
3336 while (ancestor != null && !predicate(ancestor)) {
3337 ancestor = ancestor.enclosingElement;
3338 }
3339 return ancestor;
3340 }
3341
3342 /**
3343 * Return the child of this element that is uniquely identified by the given i dentifier, or
3344 * `null` if there is no such child.
3345 *
3346 * @param identifier the identifier used to select a child
3347 * @return the child of this element with the given identifier
3348 */
3349 ElementImpl getChild(String identifier) => null;
3350
3351 @override
3352 AnalysisContext get context {
3353 if (_enclosingElement == null) {
3354 return null;
3355 }
3356 return _enclosingElement.context;
3357 }
3358
3359 @override
3360 String get displayName => _name;
3361
3362 @override
3363 Element get enclosingElement => _enclosingElement;
3364
3365 @override
3366 String getExtendedDisplayName(String shortName) {
3367 if (shortName == null) {
3368 shortName = displayName;
3369 }
3370 Source source = this.source;
3371 if (source != null) {
3372 return "${shortName} (${source.fullName})";
3373 }
3374 return shortName;
3375 }
3376
3377 @override
3378 LibraryElement get library => getAncestor((element) => element is LibraryEleme nt);
3379
3380 @override
3381 ElementLocation get location => new ElementLocationImpl.con1(this);
3382
3383 @override
3384 String get name => _name;
3385
3386 @override
3387 AstNode get node => getNodeMatching((node) => node is AstNode);
3388
3389 @override
3390 Source get source {
3391 if (_enclosingElement == null) {
3392 return null;
3393 }
3394 return _enclosingElement.source;
3395 }
3396
3397 @override
3398 CompilationUnit get unit => context.resolveCompilationUnit(source, library);
3399
3400 @override
3401 int get hashCode {
3402 // TODO: We might want to re-visit this optimization in the future.
3403 // We cache the hash code value as this is a very frequently called method.
3404 if (_cachedHashCode == 0) {
3405 int hashIdentifier = identifier.hashCode;
3406 Element enclosing = enclosingElement;
3407 if (enclosing != null) {
3408 _cachedHashCode = hashIdentifier + enclosing.hashCode;
3409 } else {
3410 _cachedHashCode = hashIdentifier;
3411 }
3412 }
3413 return _cachedHashCode;
3414 }
3415
3416 @override
3417 bool isAccessibleIn(LibraryElement library) {
3418 if (Identifier.isPrivateName(_name)) {
3419 return library == this.library;
3420 }
3421 return true;
3422 }
3423
3424 @override
3425 bool get isDeprecated {
3426 for (ElementAnnotation annotation in metadata) {
3427 if (annotation.isDeprecated) {
3428 return true;
3429 }
3430 }
3431 return false;
3432 }
3433
3434 @override
3435 bool get isOverride {
3436 for (ElementAnnotation annotation in metadata) {
3437 if (annotation.isOverride) {
3438 return true;
3439 }
3440 }
3441 return false;
3442 }
3443
3444 @override
3445 bool get isPrivate {
3446 String name = displayName;
3447 if (name == null) {
3448 return true;
3449 }
3450 return Identifier.isPrivateName(name);
3451 }
3452
3453 @override
3454 bool get isPublic => !isPrivate;
3455
3456 @override
3457 bool get isSynthetic => hasModifier(Modifier.SYNTHETIC);
3458
3459 /**
3460 * Set the enclosing element of this element to the given element.
3461 *
3462 * @param element the enclosing element of this element
3463 */
3464 void set enclosingElement(Element element) {
3465 _enclosingElement = element as ElementImpl;
3466 }
3467
3468 /**
3469 * Set whether this element is synthetic to correspond to the given value.
3470 *
3471 * @param isSynthetic `true` if the element is synthetic
3472 */
3473 void set synthetic(bool isSynthetic) {
3474 setModifier(Modifier.SYNTHETIC, isSynthetic);
3475 }
3476
3477 @override
3478 String toString() {
3479 JavaStringBuilder builder = new JavaStringBuilder();
3480 appendTo(builder);
3481 return builder.toString();
3482 }
3483
3484 @override
3485 void visitChildren(ElementVisitor visitor) {
3486 }
3487
3488 /**
3489 * Append a textual representation of this type to the given builder.
3490 *
3491 * @param builder the builder to which the text is to be appended
3492 */
3493 void appendTo(JavaStringBuilder builder) {
3494 if (_name == null) {
3495 builder.append("<unnamed ");
3496 builder.append(runtimeType.toString());
3497 builder.append(">");
3498 } else {
3499 builder.append(_name);
3500 }
3501 }
3502
3503 /**
3504 * Set this [Element] as an enclosing for given.
3505 *
3506 * @param element the element to enclose, must be [ElementImpl]
3507 */
3508 void encloseElement(ElementImpl element) {
3509 element.enclosingElement = this;
3510 }
3511
3512 /**
3513 * Return an identifier that uniquely identifies this element among the childr en of this element's
3514 * parent.
3515 *
3516 * @return an identifier that uniquely identifies this element relative to its parent
3517 */
3518 String get identifier => name;
3519
3520 /**
3521 * Return the resolved [AstNode] of the given type enclosing [getNameOffset].
3522 */
3523 AstNode getNodeMatching(Predicate<AstNode> predicate) {
3524 CompilationUnit unit = this.unit;
3525 if (unit == null) {
3526 return null;
3527 }
3528 int offset = nameOffset;
3529 AstNode node = new NodeLocator.con1(offset).searchWithin(unit);
3530 if (node == null) {
3531 return null;
3532 }
3533 return node.getAncestor(predicate);
3534 }
3535
3536 /**
3537 * Return `true` if this element has the given modifier associated with it.
3538 *
3539 * @param modifier the modifier being tested for
3540 * @return `true` if this element has the given modifier associated with it
3541 */
3542 bool hasModifier(Modifier modifier) => BooleanArray.getEnum(_modifiers, modifi er);
3543
3544 /**
3545 * If the given child is not `null`, use the given visitor to visit it.
3546 *
3547 * @param child the child to be visited
3548 * @param visitor the visitor to be used to visit the child
3549 */
3550 void safelyVisitChild(Element child, ElementVisitor visitor) {
3551 if (child != null) {
3552 child.accept(visitor);
3553 }
3554 }
3555
3556 /**
3557 * Use the given visitor to visit all of the children in the given array.
3558 *
3559 * @param children the children to be visited
3560 * @param visitor the visitor being used to visit the children
3561 */
3562 void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
3563 if (children != null) {
3564 for (Element child in children) {
3565 child.accept(visitor);
3566 }
3567 }
3568 }
3569
3570 /**
3571 * Set whether the given modifier is associated with this element to correspon d to the given
3572 * value.
3573 *
3574 * @param modifier the modifier to be set
3575 * @param value `true` if the modifier is to be associated with this element
3576 */
3577 void setModifier(Modifier modifier, bool value) {
3578 _modifiers = BooleanArray.setEnum(_modifiers, modifier, value);
3579 }
3580 }
3581
3582 /**
3583 * The enumeration `ElementKind` defines the various kinds of elements in the el ement model.
3584 */
3585 class ElementKind extends Enum<ElementKind> {
3586 static const ElementKind ANGULAR_FORMATTER = const ElementKind('ANGULAR_FORMAT TER', 0, "Angular formatter");
3587
3588 static const ElementKind ANGULAR_COMPONENT = const ElementKind('ANGULAR_COMPON ENT', 1, "Angular component");
3589
3590 static const ElementKind ANGULAR_CONTROLLER = const ElementKind('ANGULAR_CONTR OLLER', 2, "Angular controller");
3591
3592 static const ElementKind ANGULAR_DIRECTIVE = const ElementKind('ANGULAR_DIRECT IVE', 3, "Angular directive");
3593
3594 static const ElementKind ANGULAR_PROPERTY = const ElementKind('ANGULAR_PROPERT Y', 4, "Angular property");
3595
3596 static const ElementKind ANGULAR_SCOPE_PROPERTY = const ElementKind('ANGULAR_S COPE_PROPERTY', 5, "Angular scope property");
3597
3598 static const ElementKind ANGULAR_SELECTOR = const ElementKind('ANGULAR_SELECTO R', 6, "Angular selector");
3599
3600 static const ElementKind ANGULAR_VIEW = const ElementKind('ANGULAR_VIEW', 7, " Angular view");
3601
3602 static const ElementKind CLASS = const ElementKind('CLASS', 8, "class");
3603
3604 static const ElementKind COMPILATION_UNIT = const ElementKind('COMPILATION_UNI T', 9, "compilation unit");
3605
3606 static const ElementKind CONSTRUCTOR = const ElementKind('CONSTRUCTOR', 10, "c onstructor");
3607
3608 static const ElementKind DYNAMIC = const ElementKind('DYNAMIC', 11, "<dynamic> ");
3609
3610 static const ElementKind EMBEDDED_HTML_SCRIPT = const ElementKind('EMBEDDED_HT ML_SCRIPT', 12, "embedded html script");
3611
3612 static const ElementKind ERROR = const ElementKind('ERROR', 13, "<error>");
3613
3614 static const ElementKind EXPORT = const ElementKind('EXPORT', 14, "export dire ctive");
3615
3616 static const ElementKind EXTERNAL_HTML_SCRIPT = const ElementKind('EXTERNAL_HT ML_SCRIPT', 15, "external html script");
3617
3618 static const ElementKind FIELD = const ElementKind('FIELD', 16, "field");
3619
3620 static const ElementKind FUNCTION = const ElementKind('FUNCTION', 17, "functio n");
3621
3622 static const ElementKind GETTER = const ElementKind('GETTER', 18, "getter");
3623
3624 static const ElementKind HTML = const ElementKind('HTML', 19, "html");
3625
3626 static const ElementKind IMPORT = const ElementKind('IMPORT', 20, "import dire ctive");
3627
3628 static const ElementKind LABEL = const ElementKind('LABEL', 21, "label");
3629
3630 static const ElementKind LIBRARY = const ElementKind('LIBRARY', 22, "library") ;
3631
3632 static const ElementKind LOCAL_VARIABLE = const ElementKind('LOCAL_VARIABLE', 23, "local variable");
3633
3634 static const ElementKind METHOD = const ElementKind('METHOD', 24, "method");
3635
3636 static const ElementKind NAME = const ElementKind('NAME', 25, "<name>");
3637
3638 static const ElementKind PARAMETER = const ElementKind('PARAMETER', 26, "param eter");
3639
3640 static const ElementKind POLYMER_ATTRIBUTE = const ElementKind('POLYMER_ATTRIB UTE', 27, "Polymer attribute");
3641
3642 static const ElementKind POLYMER_TAG_DART = const ElementKind('POLYMER_TAG_DAR T', 28, "Polymer Dart tag");
3643
3644 static const ElementKind POLYMER_TAG_HTML = const ElementKind('POLYMER_TAG_HTM L', 29, "Polymer HTML tag");
3645
3646 static const ElementKind PREFIX = const ElementKind('PREFIX', 30, "import pref ix");
3647
3648 static const ElementKind SETTER = const ElementKind('SETTER', 31, "setter");
3649
3650 static const ElementKind TOP_LEVEL_VARIABLE = const ElementKind('TOP_LEVEL_VAR IABLE', 32, "top level variable");
3651
3652 static const ElementKind FUNCTION_TYPE_ALIAS = const ElementKind('FUNCTION_TYP E_ALIAS', 33, "function type alias");
3653
3654 static const ElementKind TYPE_PARAMETER = const ElementKind('TYPE_PARAMETER', 34, "type parameter");
3655
3656 static const ElementKind UNIVERSE = const ElementKind('UNIVERSE', 35, "<univer se>");
3657
3658 static const List<ElementKind> values = const [
3659 ANGULAR_FORMATTER,
3660 ANGULAR_COMPONENT,
3661 ANGULAR_CONTROLLER,
3662 ANGULAR_DIRECTIVE,
3663 ANGULAR_PROPERTY,
3664 ANGULAR_SCOPE_PROPERTY,
3665 ANGULAR_SELECTOR,
3666 ANGULAR_VIEW,
3667 CLASS,
3668 COMPILATION_UNIT,
3669 CONSTRUCTOR,
3670 DYNAMIC,
3671 EMBEDDED_HTML_SCRIPT,
3672 ERROR,
3673 EXPORT,
3674 EXTERNAL_HTML_SCRIPT,
3675 FIELD,
3676 FUNCTION,
3677 GETTER,
3678 HTML,
3679 IMPORT,
3680 LABEL,
3681 LIBRARY,
3682 LOCAL_VARIABLE,
3683 METHOD,
3684 NAME,
3685 PARAMETER,
3686 POLYMER_ATTRIBUTE,
3687 POLYMER_TAG_DART,
3688 POLYMER_TAG_HTML,
3689 PREFIX,
3690 SETTER,
3691 TOP_LEVEL_VARIABLE,
3692 FUNCTION_TYPE_ALIAS,
3693 TYPE_PARAMETER,
3694 UNIVERSE];
3695
3696 /**
3697 * Return the kind of the given element, or [ERROR] if the element is `null`. This is
3698 * a utility method that can reduce the need for null checks in other places.
3699 *
3700 * @param element the element whose kind is to be returned
3701 * @return the kind of the given element
3702 */
3703 static ElementKind of(Element element) {
3704 if (element == null) {
3705 return ERROR;
3706 }
3707 return element.kind;
3708 }
3709
3710 /**
3711 * The name displayed in the UI for this kind of element.
3712 */
3713 final String displayName;
3714
3715 /**
3716 * Initialize a newly created element kind to have the given display name.
3717 *
3718 * @param displayName the name displayed in the UI for this kind of element
3719 */
3720 const ElementKind(String name, int ordinal, this.displayName) : super(name, or dinal);
3721 }
3722
3723 /**
3724 * The interface `ElementLocation` defines the behavior of objects that represen t the location
3725 * of an element within the element model.
3726 */
3727 abstract class ElementLocation {
3728 /**
3729 * Return the path to the element whose location is represented by this object . Clients must not
3730 * modify the returned array.
3731 *
3732 * @return the path to the element whose location is represented by this objec t
3733 */
3734 List<String> get components;
3735
3736 /**
3737 * Return an encoded representation of this location that can be used to creat e a location that is
3738 * equal to this location.
3739 *
3740 * @return an encoded representation of this location
3741 */
3742 String get encoding;
3743 }
3744
3745 /**
3746 * Instances of the class `ElementLocationImpl` implement an [ElementLocation].
3747 */
3748 class ElementLocationImpl implements ElementLocation {
3749 /**
3750 * The path to the element whose location is represented by this object.
3751 */
3752 List<String> _components;
3753
3754 /**
3755 * The character used to separate components in the encoded form.
3756 */
3757 static int _SEPARATOR_CHAR = 0x3B;
3758
3759 /**
3760 * Initialize a newly created location to represent the given element.
3761 *
3762 * @param element the element whose location is being represented
3763 */
3764 ElementLocationImpl.con1(Element element) {
3765 List<String> components = new List<String>();
3766 Element ancestor = element;
3767 while (ancestor != null) {
3768 components.insert(0, (ancestor as ElementImpl).identifier);
3769 ancestor = ancestor.enclosingElement;
3770 }
3771 this._components = new List.from(components);
3772 }
3773
3774 /**
3775 * Initialize a newly created location from the given encoded form.
3776 *
3777 * @param encoding the encoded form of a location
3778 */
3779 ElementLocationImpl.con2(String encoding) {
3780 this._components = _decode(encoding);
3781 }
3782
3783 /**
3784 * Initialize a newly created location from the given components.
3785 *
3786 * @param components the components of a location
3787 */
3788 ElementLocationImpl.con3(List<String> components) {
3789 this._components = components;
3790 }
3791
3792 @override
3793 bool operator ==(Object object) {
3794 if (identical(this, object)) {
3795 return true;
3796 }
3797 if (object is! ElementLocationImpl) {
3798 return false;
3799 }
3800 ElementLocationImpl location = object as ElementLocationImpl;
3801 List<String> otherComponents = location._components;
3802 int length = _components.length;
3803 if (otherComponents.length != length) {
3804 return false;
3805 }
3806 for (int i = 0; i < length; i++) {
3807 if (_components[i] != otherComponents[i]) {
3808 return false;
3809 }
3810 }
3811 return true;
3812 }
3813
3814 @override
3815 List<String> get components => _components;
3816
3817 @override
3818 String get encoding {
3819 JavaStringBuilder builder = new JavaStringBuilder();
3820 int length = _components.length;
3821 for (int i = 0; i < length; i++) {
3822 if (i > 0) {
3823 builder.appendChar(_SEPARATOR_CHAR);
3824 }
3825 _encode(builder, _components[i]);
3826 }
3827 return builder.toString();
3828 }
3829
3830 @override
3831 int get hashCode {
3832 int result = 1;
3833 for (int i = 0; i < _components.length; i++) {
3834 String component = _components[i];
3835 result = 31 * result + component.hashCode;
3836 }
3837 return result;
3838 }
3839
3840 @override
3841 String toString() => encoding;
3842
3843 /**
3844 * Decode the encoded form of a location into an array of components.
3845 *
3846 * @param encoding the encoded form of a location
3847 * @return the components that were encoded
3848 */
3849 List<String> _decode(String encoding) {
3850 List<String> components = new List<String>();
3851 JavaStringBuilder builder = new JavaStringBuilder();
3852 int index = 0;
3853 int length = encoding.length;
3854 while (index < length) {
3855 int currentChar = encoding.codeUnitAt(index);
3856 if (currentChar == _SEPARATOR_CHAR) {
3857 if (index + 1 < length && encoding.codeUnitAt(index + 1) == _SEPARATOR_C HAR) {
3858 builder.appendChar(_SEPARATOR_CHAR);
3859 index += 2;
3860 } else {
3861 components.add(builder.toString());
3862 builder.length = 0;
3863 index++;
3864 }
3865 } else {
3866 builder.appendChar(currentChar);
3867 index++;
3868 }
3869 }
3870 components.add(builder.toString());
3871 return new List.from(components);
3872 }
3873
3874 /**
3875 * Append an encoded form of the given component to the given builder.
3876 *
3877 * @param builder the builder to which the encoded component is to be appended
3878 * @param component the component to be appended to the builder
3879 */
3880 void _encode(JavaStringBuilder builder, String component) {
3881 int length = component.length;
3882 for (int i = 0; i < length; i++) {
3883 int currentChar = component.codeUnitAt(i);
3884 if (currentChar == _SEPARATOR_CHAR) {
3885 builder.appendChar(_SEPARATOR_CHAR);
3886 }
3887 builder.appendChar(currentChar);
3888 }
3889 }
3890 }
3891
3892 /**
3893 * The class `ElementPair` is a pair of [Element]s. [Object#equals] and
3894 * [Object#hashCode] so this class can be used in hashed data structures.
3895 */
3896 class ElementPair {
3897 /**
3898 * The first [Element]
3899 */
3900 final Element _first;
3901
3902 /**
3903 * The second [Element]
3904 */
3905 final Element _second;
3906
3907 /**
3908 * The sole constructor for this class, taking two [Element]s.
3909 *
3910 * @param first the first element
3911 * @param second the second element
3912 */
3913 ElementPair(this._first, this._second);
3914
3915 @override
3916 bool operator ==(Object object) {
3917 if (identical(object, this)) {
3918 return true;
3919 }
3920 if (object is ElementPair) {
3921 ElementPair elementPair = object;
3922 return (_first == elementPair._first) && (_second == elementPair._second);
3923 }
3924 return false;
3925 }
3926
3927 /**
3928 * Return the first element.
3929 *
3930 * @return the first element
3931 */
3932 Element get firstElt => _first;
3933
3934 /**
3935 * Return the second element
3936 *
3937 * @return the second element
3938 */
3939 Element get secondElt => _second;
3940
3941 @override
3942 int get hashCode => ObjectUtilities.combineHashCodes(_first.hashCode, _second. hashCode);
3943 }
3944
3945 /**
3946 * The interface `ElementVisitor` defines the behavior of objects that can be us ed to visit an
3947 * element structure.
3948 */
3949 abstract class ElementVisitor<R> {
3950 R visitAngularComponentElement(AngularComponentElement element);
3951
3952 R visitAngularControllerElement(AngularControllerElement element);
3953
3954 R visitAngularDirectiveElement(AngularDecoratorElement element);
3955
3956 R visitAngularFormatterElement(AngularFormatterElement element);
3957
3958 R visitAngularPropertyElement(AngularPropertyElement element);
3959
3960 R visitAngularScopePropertyElement(AngularScopePropertyElement element);
3961
3962 R visitAngularSelectorElement(AngularSelectorElement element);
3963
3964 R visitAngularViewElement(AngularViewElement element);
3965
3966 R visitClassElement(ClassElement element);
3967
3968 R visitCompilationUnitElement(CompilationUnitElement element);
3969
3970 R visitConstructorElement(ConstructorElement element);
3971
3972 R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element);
3973
3974 R visitExportElement(ExportElement element);
3975
3976 R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element);
3977
3978 R visitFieldElement(FieldElement element);
3979
3980 R visitFieldFormalParameterElement(FieldFormalParameterElement element);
3981
3982 R visitFunctionElement(FunctionElement element);
3983
3984 R visitFunctionTypeAliasElement(FunctionTypeAliasElement element);
3985
3986 R visitHtmlElement(HtmlElement element);
3987
3988 R visitImportElement(ImportElement element);
3989
3990 R visitLabelElement(LabelElement element);
3991
3992 R visitLibraryElement(LibraryElement element);
3993
3994 R visitLocalVariableElement(LocalVariableElement element);
3995
3996 R visitMethodElement(MethodElement element);
3997
3998 R visitMultiplyDefinedElement(MultiplyDefinedElement element);
3999
4000 R visitParameterElement(ParameterElement element);
4001
4002 R visitPolymerAttributeElement(PolymerAttributeElement element);
4003
4004 R visitPolymerTagDartElement(PolymerTagDartElement element);
4005
4006 R visitPolymerTagHtmlElement(PolymerTagHtmlElement element);
4007
4008 R visitPrefixElement(PrefixElement element);
4009
4010 R visitPropertyAccessorElement(PropertyAccessorElement element);
4011
4012 R visitTopLevelVariableElement(TopLevelVariableElement element);
4013
4014 R visitTypeParameterElement(TypeParameterElement element);
4015 }
4016
4017 /**
4018 * The interface `EmbeddedHtmlScriptElement` defines the behavior of elements re presenting a
4019 * script tag in an HTML file having content that defines a Dart library.
4020 */
4021 abstract class EmbeddedHtmlScriptElement implements HtmlScriptElement {
4022 /**
4023 * Return the library element defined by the content of the script tag.
4024 *
4025 * @return the library element (not `null`)
4026 */
4027 LibraryElement get scriptLibrary;
4028 }
4029
4030 /**
4031 * Instances of the class `EmbeddedHtmlScriptElementImpl` implement an
4032 * [EmbeddedHtmlScriptElement].
4033 */
4034 class EmbeddedHtmlScriptElementImpl extends HtmlScriptElementImpl implements Emb eddedHtmlScriptElement {
4035 /**
4036 * The library defined by the script tag's content.
4037 */
4038 LibraryElement _scriptLibrary;
4039
4040 /**
4041 * Initialize a newly created script element to have the specified tag name an d offset.
4042 *
4043 * @param node the XML node from which this element is derived (not `null`)
4044 */
4045 EmbeddedHtmlScriptElementImpl(XmlTagNode node) : super(node);
4046
4047 @override
4048 accept(ElementVisitor visitor) => visitor.visitEmbeddedHtmlScriptElement(this) ;
4049
4050 @override
4051 ElementKind get kind => ElementKind.EMBEDDED_HTML_SCRIPT;
4052
4053 @override
4054 LibraryElement get scriptLibrary => _scriptLibrary;
4055
4056 /**
4057 * Set the script library defined by the script tag's content.
4058 *
4059 * @param scriptLibrary the library or `null` if none
4060 */
4061 void set scriptLibrary(LibraryElementImpl scriptLibrary) {
4062 scriptLibrary.enclosingElement = this;
4063 this._scriptLibrary = scriptLibrary;
4064 }
4065
4066 @override
4067 void visitChildren(ElementVisitor visitor) {
4068 safelyVisitChild(_scriptLibrary, visitor);
4069 }
4070 }
4071
4072 /**
4073 * The interface `ExecutableElement` defines the behavior of elements representi ng an
4074 * executable object, including functions, methods, constructors, getters, and s etters.
4075 */
4076 abstract class ExecutableElement implements Element {
4077 /**
4078 * Return an array containing all of the functions defined within this executa ble element.
4079 *
4080 * @return the functions defined within this executable element
4081 */
4082 List<FunctionElement> get functions;
4083
4084 /**
4085 * Return an array containing all of the labels defined within this executable element.
4086 *
4087 * @return the labels defined within this executable element
4088 */
4089 List<LabelElement> get labels;
4090
4091 /**
4092 * Return an array containing all of the local variables defined within this e xecutable element.
4093 *
4094 * @return the local variables defined within this executable element
4095 */
4096 List<LocalVariableElement> get localVariables;
4097
4098 /**
4099 * Return an array containing all of the parameters defined by this executable element.
4100 *
4101 * @return the parameters defined by this executable element
4102 */
4103 List<ParameterElement> get parameters;
4104
4105 /**
4106 * Return the return type defined by this executable element.
4107 *
4108 * @return the return type defined by this executable element
4109 */
4110 DartType get returnType;
4111
4112 /**
4113 * Return the type of function defined by this executable element.
4114 *
4115 * @return the type of function defined by this executable element
4116 */
4117 FunctionType get type;
4118
4119 /**
4120 * Return `true` if this executable element has body marked as being asynchron ous.
4121 *
4122 * @return `true` if this executable element has body marked as being asynchro nous
4123 */
4124 bool get isAsynchronous;
4125
4126 /**
4127 * Return `true` if this executable element has a body marked as being a gener ator.
4128 *
4129 * @return `true` if this executable element has a body marked as being a gene rator
4130 */
4131 bool get isGenerator;
4132
4133 /**
4134 * Return `true` if this executable element is an operator. The test may be ba sed on the
4135 * name of the executable element, in which case the result will be correct wh en the name is
4136 * legal.
4137 *
4138 * @return `true` if this executable element is an operator
4139 */
4140 bool get isOperator;
4141
4142 /**
4143 * Return `true` if this element is a static element. A static element is an e lement that is
4144 * not associated with a particular instance, but rather with an entire librar y or class.
4145 *
4146 * @return `true` if this executable element is a static element
4147 */
4148 bool get isStatic;
4149
4150 /**
4151 * Return `true` if this executable element has a body marked as being synchro nous.
4152 *
4153 * @return `true` if this executable element has a body marked as being synchr onous
4154 */
4155 bool get isSynchronous;
4156 }
4157
4158 /**
4159 * The abstract class `ExecutableElementImpl` implements the behavior common to
4160 * `ExecutableElement`s.
4161 */
4162 abstract class ExecutableElementImpl extends ElementImpl implements ExecutableEl ement {
4163 /**
4164 * An array containing all of the functions defined within this executable ele ment.
4165 */
4166 List<FunctionElement> _functions = FunctionElementImpl.EMPTY_ARRAY;
4167
4168 /**
4169 * An array containing all of the labels defined within this executable elemen t.
4170 */
4171 List<LabelElement> _labels = LabelElementImpl.EMPTY_ARRAY;
4172
4173 /**
4174 * An array containing all of the local variables defined within this executab le element.
4175 */
4176 List<LocalVariableElement> _localVariables = LocalVariableElementImpl.EMPTY_AR RAY;
4177
4178 /**
4179 * An array containing all of the parameters defined by this executable elemen t.
4180 */
4181 List<ParameterElement> _parameters = ParameterElementImpl.EMPTY_ARRAY;
4182
4183 /**
4184 * The return type defined by this executable element.
4185 */
4186 DartType returnType;
4187
4188 /**
4189 * The type of function defined by this executable element.
4190 */
4191 FunctionType type;
4192
4193 /**
4194 * An empty array of executable elements.
4195 */
4196 static List<ExecutableElement> EMPTY_ARRAY = new List<ExecutableElement>(0);
4197
4198 /**
4199 * Initialize a newly created executable element to have the given name.
4200 *
4201 * @param name the name of this element
4202 */
4203 ExecutableElementImpl.forNode(Identifier name) : super.forNode(name);
4204
4205 /**
4206 * Initialize a newly created executable element to have the given name.
4207 *
4208 * @param name the name of this element
4209 * @param nameOffset the offset of the name of this element in the file that c ontains the
4210 * declaration of this element
4211 */
4212 ExecutableElementImpl(String name, int nameOffset) : super(name, nameOffset);
4213
4214 @override
4215 ElementImpl getChild(String identifier) {
4216 for (ExecutableElement function in _functions) {
4217 if ((function as ExecutableElementImpl).identifier == identifier) {
4218 return function as ExecutableElementImpl;
4219 }
4220 }
4221 for (LabelElement label in _labels) {
4222 if ((label as LabelElementImpl).identifier == identifier) {
4223 return label as LabelElementImpl;
4224 }
4225 }
4226 for (VariableElement variable in _localVariables) {
4227 if ((variable as VariableElementImpl).identifier == identifier) {
4228 return variable as VariableElementImpl;
4229 }
4230 }
4231 for (ParameterElement parameter in _parameters) {
4232 if ((parameter as ParameterElementImpl).identifier == identifier) {
4233 return parameter as ParameterElementImpl;
4234 }
4235 }
4236 return null;
4237 }
4238
4239 @override
4240 List<FunctionElement> get functions => _functions;
4241
4242 @override
4243 List<LabelElement> get labels => _labels;
4244
4245 @override
4246 List<LocalVariableElement> get localVariables => _localVariables;
4247
4248 @override
4249 List<ParameterElement> get parameters => _parameters;
4250
4251 @override
4252 bool get isAsynchronous => hasModifier(Modifier.ASYNCHRONOUS);
4253
4254 @override
4255 bool get isGenerator => hasModifier(Modifier.GENERATOR);
4256
4257 @override
4258 bool get isOperator => false;
4259
4260 @override
4261 bool get isSynchronous => !hasModifier(Modifier.ASYNCHRONOUS);
4262
4263 /**
4264 * Set whether this method's body is asynchronous to correspond to the given v alue.
4265 *
4266 * @param isAsynchronous `true` if the method's body is asynchronous
4267 */
4268 void set asynchronous(bool isAsynchronous) {
4269 setModifier(Modifier.ASYNCHRONOUS, isAsynchronous);
4270 }
4271
4272 /**
4273 * Set the functions defined within this executable element to the given funct ions.
4274 *
4275 * @param functions the functions defined within this executable element
4276 */
4277 void set functions(List<FunctionElement> functions) {
4278 for (FunctionElement function in functions) {
4279 (function as FunctionElementImpl).enclosingElement = this;
4280 }
4281 this._functions = functions;
4282 }
4283
4284 /**
4285 * Set whether this method's body is a generator to correspond to the given va lue.
4286 *
4287 * @param isGenerator `true` if the method's body is a generator
4288 */
4289 void set generator(bool isGenerator) {
4290 setModifier(Modifier.GENERATOR, isGenerator);
4291 }
4292
4293 /**
4294 * Set the labels defined within this executable element to the given labels.
4295 *
4296 * @param labels the labels defined within this executable element
4297 */
4298 void set labels(List<LabelElement> labels) {
4299 for (LabelElement label in labels) {
4300 (label as LabelElementImpl).enclosingElement = this;
4301 }
4302 this._labels = labels;
4303 }
4304
4305 /**
4306 * Set the local variables defined within this executable element to the given variables.
4307 *
4308 * @param localVariables the local variables defined within this executable el ement
4309 */
4310 void set localVariables(List<LocalVariableElement> localVariables) {
4311 for (LocalVariableElement variable in localVariables) {
4312 (variable as LocalVariableElementImpl).enclosingElement = this;
4313 }
4314 this._localVariables = localVariables;
4315 }
4316
4317 /**
4318 * Set the parameters defined by this executable element to the given paramete rs.
4319 *
4320 * @param parameters the parameters defined by this executable element
4321 */
4322 void set parameters(List<ParameterElement> parameters) {
4323 for (ParameterElement parameter in parameters) {
4324 (parameter as ParameterElementImpl).enclosingElement = this;
4325 }
4326 this._parameters = parameters;
4327 }
4328
4329 @override
4330 void visitChildren(ElementVisitor visitor) {
4331 super.visitChildren(visitor);
4332 safelyVisitChildren(_functions, visitor);
4333 safelyVisitChildren(_labels, visitor);
4334 safelyVisitChildren(_localVariables, visitor);
4335 safelyVisitChildren(_parameters, visitor);
4336 }
4337
4338 @override
4339 void appendTo(JavaStringBuilder builder) {
4340 if (this.kind != ElementKind.GETTER) {
4341 builder.append("(");
4342 String closing = null;
4343 ParameterKind kind = ParameterKind.REQUIRED;
4344 int parameterCount = _parameters.length;
4345 for (int i = 0; i < parameterCount; i++) {
4346 if (i > 0) {
4347 builder.append(", ");
4348 }
4349 ParameterElementImpl parameter = _parameters[i] as ParameterElementImpl;
4350 ParameterKind parameterKind = parameter.parameterKind;
4351 if (parameterKind != kind) {
4352 if (closing != null) {
4353 builder.append(closing);
4354 }
4355 if (parameterKind == ParameterKind.POSITIONAL) {
4356 builder.append("[");
4357 closing = "]";
4358 } else if (parameterKind == ParameterKind.NAMED) {
4359 builder.append("{");
4360 closing = "}";
4361 } else {
4362 closing = null;
4363 }
4364 }
4365 kind = parameterKind;
4366 parameter.appendToWithoutDelimiters(builder);
4367 }
4368 if (closing != null) {
4369 builder.append(closing);
4370 }
4371 builder.append(")");
4372 }
4373 if (type != null) {
4374 builder.append(Element.RIGHT_ARROW);
4375 builder.append(type.returnType);
4376 }
4377 }
4378 }
4379
4380 /**
4381 * The abstract class `ExecutableMember` defines the behavior common to members that represent
4382 * an executable element defined in a parameterized type where the values of the type parameters are
4383 * known.
4384 */
4385 abstract class ExecutableMember extends Member implements ExecutableElement {
4386 /**
4387 * Initialize a newly created element to represent an executable element of th e given
4388 * parameterized type.
4389 *
4390 * @param baseElement the element on which the parameterized element was creat ed
4391 * @param definingType the type in which the element is defined
4392 */
4393 ExecutableMember(ExecutableElement baseElement, InterfaceType definingType) : super(baseElement, definingType);
4394
4395 @override
4396 ExecutableElement get baseElement => super.baseElement as ExecutableElement;
4397
4398 @override
4399 List<FunctionElement> get functions {
4400 //
4401 // Elements within this element should have type parameters substituted, jus t like this element.
4402 //
4403 throw new UnsupportedOperationException();
4404 }
4405
4406 @override
4407 List<LabelElement> get labels => baseElement.labels;
4408
4409 @override
4410 List<LocalVariableElement> get localVariables {
4411 //
4412 // Elements within this element should have type parameters substituted, jus t like this element.
4413 //
4414 throw new UnsupportedOperationException();
4415 }
4416
4417 @override
4418 List<ParameterElement> get parameters {
4419 List<ParameterElement> baseParameters = baseElement.parameters;
4420 int parameterCount = baseParameters.length;
4421 if (parameterCount == 0) {
4422 return baseParameters;
4423 }
4424 List<ParameterElement> parameterizedParameters = new List<ParameterElement>( parameterCount);
4425 for (int i = 0; i < parameterCount; i++) {
4426 parameterizedParameters[i] = ParameterMember.from(baseParameters[i], defin ingType);
4427 }
4428 return parameterizedParameters;
4429 }
4430
4431 @override
4432 DartType get returnType => substituteFor(baseElement.returnType);
4433
4434 @override
4435 FunctionType get type => substituteFor(baseElement.type);
4436
4437 @override
4438 bool get isAsynchronous => baseElement.isAsynchronous;
4439
4440 @override
4441 bool get isGenerator => baseElement.isGenerator;
4442
4443 @override
4444 bool get isOperator => baseElement.isOperator;
4445
4446 @override
4447 bool get isStatic => baseElement.isStatic;
4448
4449 @override
4450 bool get isSynchronous => baseElement.isSynchronous;
4451
4452 @override
4453 void visitChildren(ElementVisitor visitor) {
4454 // TODO(brianwilkerson) We need to finish implementing the accessors used be low so that we can
4455 // safely invoke them.
4456 super.visitChildren(visitor);
4457 safelyVisitChildren(baseElement.functions, visitor);
4458 safelyVisitChildren(labels, visitor);
4459 safelyVisitChildren(baseElement.localVariables, visitor);
4460 safelyVisitChildren(parameters, visitor);
4461 }
4462 }
4463
4464 /**
4465 * The interface `ExportElement` defines the behavior of objects representing in formation
4466 * about a single export directive within a library.
4467 */
4468 abstract class ExportElement implements Element, UriReferencedElement {
4469 /**
4470 * An empty array of export elements.
4471 */
4472 static final List<ExportElement> EMPTY_ARRAY = new List<ExportElement>(0);
4473
4474 /**
4475 * Return an array containing the combinators that were specified as part of t he export directive
4476 * in the order in which they were specified.
4477 *
4478 * @return the combinators specified in the export directive
4479 */
4480 List<NamespaceCombinator> get combinators;
4481
4482 /**
4483 * Return the library that is exported from this library by this export direct ive.
4484 *
4485 * @return the library that is exported from this library
4486 */
4487 LibraryElement get exportedLibrary;
4488 }
4489
4490 /**
4491 * Instances of the class `ExportElementImpl` implement an [ExportElement].
4492 */
4493 class ExportElementImpl extends UriReferencedElementImpl implements ExportElemen t {
4494 /**
4495 * The library that is exported from this library by this export directive.
4496 */
4497 LibraryElement exportedLibrary;
4498
4499 /**
4500 * The combinators that were specified as part of the export directive in the order in which they
4501 * were specified.
4502 */
4503 List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_ARRAY;
4504
4505 /**
4506 * Initialize a newly created export element.
4507 */
4508 ExportElementImpl() : super(null, -1);
4509
4510 @override
4511 accept(ElementVisitor visitor) => visitor.visitExportElement(this);
4512
4513 @override
4514 ElementKind get kind => ElementKind.EXPORT;
4515
4516 @override
4517 void appendTo(JavaStringBuilder builder) {
4518 builder.append("export ");
4519 (exportedLibrary as LibraryElementImpl).appendTo(builder);
4520 }
4521
4522 @override
4523 String get identifier => exportedLibrary.name;
4524 }
4525
4526 /**
4527 * The interface `ExternalHtmlScriptElement` defines the behavior of elements re presenting a
4528 * script tag in an HTML file having a `source` attribute that references a Dart library
4529 * source file.
4530 */
4531 abstract class ExternalHtmlScriptElement implements HtmlScriptElement {
4532 /**
4533 * Return the source referenced by this element, or `null` if this element doe s not
4534 * reference a Dart library source file.
4535 *
4536 * @return the source for the external Dart library
4537 */
4538 Source get scriptSource;
4539 }
4540
4541 /**
4542 * Instances of the class `ExternalHtmlScriptElementImpl` implement an
4543 * [ExternalHtmlScriptElement].
4544 */
4545 class ExternalHtmlScriptElementImpl extends HtmlScriptElementImpl implements Ext ernalHtmlScriptElement {
4546 /**
4547 * The source specified in the `source` attribute or `null` if unspecified.
4548 */
4549 Source scriptSource;
4550
4551 /**
4552 * Initialize a newly created script element to have the specified tag name an d offset.
4553 *
4554 * @param node the XML node from which this element is derived (not `null`)
4555 */
4556 ExternalHtmlScriptElementImpl(XmlTagNode node) : super(node);
4557
4558 @override
4559 accept(ElementVisitor visitor) => visitor.visitExternalHtmlScriptElement(this) ;
4560
4561 @override
4562 ElementKind get kind => ElementKind.EXTERNAL_HTML_SCRIPT;
4563 }
4564
4565 /**
4566 * The interface `FieldElement` defines the behavior of elements representing a field defined
4567 * within a type.
4568 */
4569 abstract class FieldElement implements ClassMemberElement, PropertyInducingEleme nt {
4570 }
4571
4572 /**
4573 * Instances of the class `FieldElementImpl` implement a `FieldElement`.
4574 */
4575 class FieldElementImpl extends PropertyInducingElementImpl implements FieldEleme nt {
4576 /**
4577 * An empty array of field elements.
4578 */
4579 static List<FieldElement> EMPTY_ARRAY = new List<FieldElement>(0);
4580
4581 /**
4582 * Initialize a newly created field element to have the given name.
4583 *
4584 * @param name the name of this element
4585 */
4586 FieldElementImpl.forNode(Identifier name) : super.forNode(name);
4587
4588 /**
4589 * Initialize a newly created synthetic field element to have the given name.
4590 *
4591 * @param name the name of this element
4592 * @param nameOffset the offset of the name of this element in the file that c ontains the
4593 * declaration of this element
4594 */
4595 FieldElementImpl(String name, int nameOffset) : super(name, nameOffset);
4596
4597 @override
4598 accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
4599
4600 @override
4601 ClassElement get enclosingElement => super.enclosingElement as ClassElement;
4602
4603 @override
4604 ElementKind get kind => ElementKind.FIELD;
4605
4606 @override
4607 bool get isStatic => hasModifier(Modifier.STATIC);
4608
4609 /**
4610 * Set whether this field is static to correspond to the given value.
4611 *
4612 * @param isStatic `true` if the field is static
4613 */
4614 void set static(bool isStatic) {
4615 setModifier(Modifier.STATIC, isStatic);
4616 }
4617 }
4618
4619 /**
4620 * The interface `FieldFormalParameterElement` defines the behavior of elements representing a
4621 * field formal parameter defined within a constructor element.
4622 */
4623 abstract class FieldFormalParameterElement implements ParameterElement {
4624 /**
4625 * Return the field element associated with this field formal parameter, or `n ull` if the
4626 * parameter references a field that doesn't exist.
4627 *
4628 * @return the field element associated with this field formal parameter
4629 */
4630 FieldElement get field;
4631 }
4632
4633 /**
4634 * Instances of the class `FieldFormalParameterElementImpl` extend
4635 * [ParameterElementImpl] to provide the additional information of the [FieldEle ment]
4636 * associated with the parameter.
4637 */
4638 class FieldFormalParameterElementImpl extends ParameterElementImpl implements Fi eldFormalParameterElement {
4639 /**
4640 * The field associated with this field formal parameter.
4641 */
4642 FieldElement field;
4643
4644 /**
4645 * Initialize a newly created parameter element to have the given name.
4646 *
4647 * @param name the name of this element
4648 */
4649 FieldFormalParameterElementImpl(Identifier name) : super.forNode(name);
4650
4651 @override
4652 accept(ElementVisitor visitor) => visitor.visitFieldFormalParameterElement(thi s);
4653
4654 @override
4655 bool get isInitializingFormal => true;
4656 }
4657
4658 /**
4659 * Instances of the class `FieldFormalParameterMember` represent a parameter ele ment defined
4660 * in a parameterized type where the values of the type parameters are known.
4661 */
4662 class FieldFormalParameterMember extends ParameterMember implements FieldFormalP arameterElement {
4663 /**
4664 * Initialize a newly created element to represent a parameter of the given pa rameterized type.
4665 *
4666 * @param baseElement the element on which the parameterized element was creat ed
4667 * @param definingType the type in which the element is defined
4668 */
4669 FieldFormalParameterMember(FieldFormalParameterElement baseElement, Parameteri zedType definingType) : super(baseElement, definingType);
4670
4671 @override
4672 accept(ElementVisitor visitor) => visitor.visitFieldFormalParameterElement(thi s);
4673
4674 @override
4675 FieldElement get field => (baseElement as FieldFormalParameterElement).field;
4676 }
4677
4678 /**
4679 * Instances of the class `FieldMember` represent a field element defined in a p arameterized
4680 * type where the values of the type parameters are known.
4681 */
4682 class FieldMember extends VariableMember implements FieldElement {
4683 /**
4684 * If the given field's type is different when any type parameters from the de fining type's
4685 * declaration are replaced with the actual type arguments from the defining t ype, create a field
4686 * member representing the given field. Return the member that was created, or the base field if
4687 * no member was created.
4688 *
4689 * @param baseField the base field for which a member might be created
4690 * @param definingType the type defining the parameters and arguments to be us ed in the
4691 * substitution
4692 * @return the field element that will return the correctly substituted types
4693 */
4694 static FieldElement from(FieldElement baseField, InterfaceType definingType) {
4695 if (!_isChangedByTypeSubstitution(baseField, definingType)) {
4696 return baseField;
4697 }
4698 // TODO(brianwilkerson) Consider caching the substituted type in the instanc e. It would use more
4699 // memory but speed up some operations. We need to see how often the type is being re-computed.
4700 return new FieldMember(baseField, definingType);
4701 }
4702
4703 /**
4704 * Determine whether the given field's type is changed when type parameters fr om the defining
4705 * type's declaration are replaced with the actual type arguments from the def ining type.
4706 *
4707 * @param baseField the base field
4708 * @param definingType the type defining the parameters and arguments to be us ed in the
4709 * substitution
4710 * @return true if the type is changed by type substitution.
4711 */
4712 static bool _isChangedByTypeSubstitution(FieldElement baseField, InterfaceType definingType) {
4713 List<DartType> argumentTypes = definingType.typeArguments;
4714 if (baseField != null && argumentTypes.length != 0) {
4715 DartType baseType = baseField.type;
4716 List<DartType> parameterTypes = definingType.element.type.typeArguments;
4717 if (baseType != null) {
4718 DartType substitutedType = baseType.substitute2(argumentTypes, parameter Types);
4719 if (baseType != substitutedType) {
4720 return true;
4721 }
4722 }
4723 // If the field has a propagated type, then we need to check whether the p ropagated type
4724 // needs substitution.
4725 DartType basePropagatedType = baseField.propagatedType;
4726 if (basePropagatedType != null) {
4727 DartType substitutedPropagatedType = basePropagatedType.substitute2(argu mentTypes, parameterTypes);
4728 if (basePropagatedType != substitutedPropagatedType) {
4729 return true;
4730 }
4731 }
4732 }
4733 return false;
4734 }
4735
4736 /**
4737 * Initialize a newly created element to represent a field of the given parame terized type.
4738 *
4739 * @param baseElement the element on which the parameterized element was creat ed
4740 * @param definingType the type in which the element is defined
4741 */
4742 FieldMember(FieldElement baseElement, InterfaceType definingType) : super(base Element, definingType);
4743
4744 @override
4745 accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
4746
4747 @override
4748 FieldElement get baseElement => super.baseElement as FieldElement;
4749
4750 @override
4751 ClassElement get enclosingElement => baseElement.enclosingElement;
4752
4753 @override
4754 PropertyAccessorElement get getter => PropertyAccessorMember.from(baseElement. getter, definingType);
4755
4756 @override
4757 DartType get propagatedType => substituteFor(baseElement.propagatedType);
4758
4759 @override
4760 PropertyAccessorElement get setter => PropertyAccessorMember.from(baseElement. setter, definingType);
4761
4762 @override
4763 bool get isStatic => baseElement.isStatic;
4764
4765 @override
4766 String toString() {
4767 JavaStringBuilder builder = new JavaStringBuilder();
4768 builder.append(type);
4769 builder.append(" ");
4770 builder.append(displayName);
4771 return builder.toString();
4772 }
4773
4774 @override
4775 InterfaceType get definingType => super.definingType as InterfaceType;
4776 }
4777
4778 /**
4779 * The interface `FunctionElement` defines the behavior of elements representing a function.
4780 */
4781 abstract class FunctionElement implements ExecutableElement, LocalElement {
4782 /**
4783 * The name of the method that can be implemented by a class to allow its inst ances to be invoked
4784 * as if they were a function.
4785 */
4786 static final String CALL_METHOD_NAME = "call";
4787
4788 /**
4789 * The name of the method that will be invoked if an attempt is made to invoke an undefined method
4790 * on an object.
4791 */
4792 static final String NO_SUCH_METHOD_METHOD_NAME = "noSuchMethod";
4793
4794 /**
4795 * The name of the synthetic function defined for libraries that are deferred.
4796 */
4797 static final String LOAD_LIBRARY_NAME = "loadLibrary";
4798
4799 /**
4800 * Return the resolved [FunctionDeclaration] node that declares this [Function Element]
4801 * .
4802 *
4803 * This method is expensive, because resolved AST might be evicted from cache, so parsing and
4804 * resolving will be performed.
4805 *
4806 * @return the resolved [FunctionDeclaration], not `null`.
4807 */
4808 @override
4809 FunctionDeclaration get node;
4810 }
4811
4812 /**
4813 * Instances of the class `FunctionElementImpl` implement a `FunctionElement`.
4814 */
4815 class FunctionElementImpl extends ExecutableElementImpl implements FunctionEleme nt {
4816 /**
4817 * The offset to the beginning of the visible range for this element.
4818 */
4819 int _visibleRangeOffset = 0;
4820
4821 /**
4822 * The length of the visible range for this element, or `-1` if this element d oes not have a
4823 * visible range.
4824 */
4825 int _visibleRangeLength = -1;
4826
4827 /**
4828 * An empty array of function elements.
4829 */
4830 static List<FunctionElement> EMPTY_ARRAY = new List<FunctionElement>(0);
4831
4832 /**
4833 * Initialize a newly created function element to have the given name.
4834 *
4835 * @param name the name of this element
4836 */
4837 FunctionElementImpl.forNode(Identifier name) : super.forNode(name);
4838
4839 /**
4840 * Initialize a newly created function element to have no name and the given o ffset. This is used
4841 * for function expressions, which have no name.
4842 *
4843 * @param nameOffset the offset of the name of this element in the file that c ontains the
4844 * declaration of this element
4845 */
4846 FunctionElementImpl.forOffset(int nameOffset) : super("", nameOffset);
4847
4848 /**
4849 * Initialize a newly created function element to have the given name and offs et.
4850 *
4851 * @param name the name of this element
4852 * @param nameOffset the offset of the name of this element in the file that c ontains the
4853 * declaration of this element
4854 */
4855 FunctionElementImpl(String name, int nameOffset) : super(name, nameOffset);
4856
4857 @override
4858 accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
4859
4860 @override
4861 ElementKind get kind => ElementKind.FUNCTION;
4862
4863 @override
4864 FunctionDeclaration get node => getNodeMatching((node) => node is FunctionDecl aration);
4865
4866 @override
4867 SourceRange get visibleRange {
4868 if (_visibleRangeLength < 0) {
4869 return null;
4870 }
4871 return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
4872 }
4873
4874 @override
4875 bool get isStatic => enclosingElement is CompilationUnitElement;
4876
4877 /**
4878 * Set the visible range for this element to the range starting at the given o ffset with the given
4879 * length.
4880 *
4881 * @param offset the offset to the beginning of the visible range for this ele ment
4882 * @param length the length of the visible range for this element, or `-1` if this element
4883 * does not have a visible range
4884 */
4885 void setVisibleRange(int offset, int length) {
4886 _visibleRangeOffset = offset;
4887 _visibleRangeLength = length;
4888 }
4889
4890 @override
4891 void appendTo(JavaStringBuilder builder) {
4892 String name = displayName;
4893 if (name != null) {
4894 builder.append(name);
4895 }
4896 super.appendTo(builder);
4897 }
4898
4899 @override
4900 String get identifier {
4901 String identifier = super.identifier;
4902 if (!isStatic) {
4903 identifier += "@${nameOffset}";
4904 }
4905 return identifier;
4906 }
4907 }
4908
4909 /**
4910 * The interface `FunctionType` defines the behavior common to objects represent ing the type
4911 * of a function, method, constructor, getter, or setter. Function types come in three variations:
4912 * <ol>
4913 * * The types of functions that only have required parameters. These have the g eneral form
4914 * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i>.
4915 * * The types of functions with optional positional parameters. These have the general form
4916 * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>, &hellip;, T<sub >n+k</sub>]) &rarr;
4917 * T</i>.
4918 * * The types of functions with named parameters. These have the general form < i>(T<sub>1</sub>,
4919 * &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;, T<sub>xk</sub> xk}) &r arr; T</i>.
4920 * </ol>
4921 */
4922 abstract class FunctionType implements ParameterizedType {
4923 /**
4924 * Return a map from the names of named parameters to the types of the named p arameters of this
4925 * type of function. The entries in the map will be iterated in the same order as the order in
4926 * which the named parameters were defined. If there were no named parameters declared then the
4927 * map will be empty.
4928 *
4929 * @return a map from the name to the types of the named parameters of this ty pe of function
4930 */
4931 Map<String, DartType> get namedParameterTypes;
4932
4933 /**
4934 * Return an array containing the types of the normal parameters of this type of function. The
4935 * parameter types are in the same order as they appear in the declaration of the function.
4936 *
4937 * @return the types of the normal parameters of this type of function
4938 */
4939 List<DartType> get normalParameterTypes;
4940
4941 /**
4942 * Return a map from the names of optional (positional) parameters to the type s of the optional
4943 * parameters of this type of function. The entries in the map will be iterate d in the same order
4944 * as the order in which the optional parameters were defined. If there were n o optional
4945 * parameters declared then the map will be empty.
4946 *
4947 * @return a map from the name to the types of the optional parameters of this type of function
4948 */
4949 List<DartType> get optionalParameterTypes;
4950
4951 /**
4952 * Return an array containing the parameters elements of this type of function . The parameter
4953 * types are in the same order as they appear in the declaration of the functi on.
4954 *
4955 * @return the parameters elements of this type of function
4956 */
4957 List<ParameterElement> get parameters;
4958
4959 /**
4960 * Return the type of object returned by this type of function.
4961 *
4962 * @return the type of object returned by this type of function
4963 */
4964 DartType get returnType;
4965
4966 /**
4967 * Return `true` if this type is a subtype of the given type.
4968 *
4969 * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i> is a subtype of the
4970 * function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>) &rarr; S</i>, if all of the following
4971 * conditions are met:
4972 * * Either
4973 * * <i>S</i> is void, or
4974 * * <i>T &hArr; S</i>.
4975 *
4976 * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr; S<su b>i</sub></i>.
4977 * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub >, &hellip;,
4978 * T<sub>n+k</sub>]) &rarr; T</i> is a subtype of the function type <i>(S<sub> 1</sub>, &hellip;,
4979 * S<sub>n</sub>, [S<sub>n+1</sub>, &hellip;, S<sub>n+m</sub>]) &rarr; S</i>, if all of the
4980 * following conditions are met:
4981 * * Either
4982 * * <i>S</i> is void, or
4983 * * <i>T &hArr; S</i>.
4984 *
4985 * * <i>k</i> >= <i>m</i> and for all <i>i</i>, 1 <= <i>i</i> <= <i>n+m</i>, < i>T<sub>i</sub>
4986 * &hArr; S<sub>i</sub></i>.
4987 * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;,
4988 * T<sub>xk</sub> xk}) &rarr; T</i> is a subtype of the function type <i>(S<su b>1</sub>, &hellip;,
4989 * S<sub>n</sub>, {S<sub>y1</sub> y1, &hellip;, S<sub>ym</sub> ym}) &rarr; S</ i>, if all of the
4990 * following conditions are met:
4991 * * Either
4992 * * <i>S</i> is void,
4993 * * or <i>T &hArr; S</i>.
4994 *
4995 * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr; S<su b>i</sub></i>.
4996 * * <i>k</i> >= <i>m</i> and <i>y<sub>i</sub></i> in <i>{x<sub>1</sub>, &hell ip;,
4997 * x<sub>k</sub>}</i>, 1 <= <i>i</i> <= <i>m</i>.
4998 * * For all <i>y<sub>i</sub></i> in <i>{y<sub>1</sub>, &hellip;, y<sub>m</sub >}</i>,
4999 * <i>y<sub>i</sub> = x<sub>j</sub> => Tj &hArr; Si</i>.
5000 * In addition, the following subtype rules apply:
5001 *
5002 * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, []) &rarr; T <: (T<sub>1</sub>, &hellip;,
5003 * T<sub>n</sub>) &rarr; T.</i><br>
5004 * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>, &he llip;,
5005 * T<sub>n</sub>, {}) &rarr; T.</i><br>
5006 * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {}) &rarr; T <: (T<sub>1</sub>, &hellip;,
5007 * T<sub>n</sub>) &rarr; T.</i><br>
5008 * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>, &he llip;,
5009 * T<sub>n</sub>, []) &rarr; T.</i>
5010 *
5011 * All functions implement the class `Function`. However not all function type s are a
5012 * subtype of `Function`. If an interface type <i>I</i> includes a method name d
5013 * `call()`, and the type of `call()` is the function type <i>F</i>, then <i>I </i> is
5014 * considered to be a subtype of <i>F</i>.
5015 *
5016 * @param type the type being compared with this type
5017 * @return `true` if this type is a subtype of the given type
5018 */
5019 @override
5020 bool isSubtypeOf(DartType type);
5021
5022 /**
5023 * Return the type resulting from substituting the given arguments for this ty pe's parameters.
5024 * This is fully equivalent to `substitute(argumentTypes, getTypeArguments())` .
5025 *
5026 * @param argumentTypes the actual type arguments being substituted for the ty pe parameters
5027 * @return the result of performing the substitution
5028 */
5029 FunctionType substitute3(List<DartType> argumentTypes);
5030
5031 @override
5032 FunctionType substitute2(List<DartType> argumentTypes, List<DartType> paramete rTypes);
5033 }
5034
5035 /**
5036 * The interface `FunctionTypeAliasElement` defines the behavior of elements rep resenting a
5037 * function type alias (`typedef`).
5038 */
5039 abstract class FunctionTypeAliasElement implements Element {
5040 /**
5041 * Return the compilation unit in which this type alias is defined.
5042 *
5043 * @return the compilation unit in which this type alias is defined
5044 */
5045 @override
5046 CompilationUnitElement get enclosingElement;
5047
5048 /**
5049 * Return the resolved [FunctionTypeAlias] node that declares this
5050 * [FunctionTypeAliasElement] .
5051 *
5052 * This method is expensive, because resolved AST might be evicted from cache, so parsing and
5053 * resolving will be performed.
5054 *
5055 * @return the resolved [FunctionTypeAlias], not `null`.
5056 */
5057 @override
5058 FunctionTypeAlias get node;
5059
5060 /**
5061 * Return an array containing all of the parameters defined by this type alias .
5062 *
5063 * @return the parameters defined by this type alias
5064 */
5065 List<ParameterElement> get parameters;
5066
5067 /**
5068 * Return the return type defined by this type alias.
5069 *
5070 * @return the return type defined by this type alias
5071 */
5072 DartType get returnType;
5073
5074 /**
5075 * Return the type of function defined by this type alias.
5076 *
5077 * @return the type of function defined by this type alias
5078 */
5079 FunctionType get type;
5080
5081 /**
5082 * Return an array containing all of the type parameters defined for this type .
5083 *
5084 * @return the type parameters defined for this type
5085 */
5086 List<TypeParameterElement> get typeParameters;
5087 }
5088
5089 /**
5090 * Instances of the class `FunctionTypeAliasElementImpl` implement a
5091 * `FunctionTypeAliasElement`.
5092 */
5093 class FunctionTypeAliasElementImpl extends ElementImpl implements FunctionTypeAl iasElement {
5094 /**
5095 * An array containing all of the parameters defined by this type alias.
5096 */
5097 List<ParameterElement> _parameters = ParameterElementImpl.EMPTY_ARRAY;
5098
5099 /**
5100 * The return type defined by this type alias.
5101 */
5102 DartType returnType;
5103
5104 /**
5105 * The type of function defined by this type alias.
5106 */
5107 FunctionType type;
5108
5109 /**
5110 * An array containing all of the type parameters defined for this type.
5111 */
5112 List<TypeParameterElement> _typeParameters = TypeParameterElementImpl.EMPTY_AR RAY;
5113
5114 /**
5115 * An empty array of type alias elements.
5116 */
5117 static List<FunctionTypeAliasElement> EMPTY_ARRAY = new List<FunctionTypeAlias Element>(0);
5118
5119 /**
5120 * Initialize a newly created type alias element to have the given name.
5121 *
5122 * @param name the name of this element
5123 */
5124 FunctionTypeAliasElementImpl(Identifier name) : super.forNode(name);
5125
5126 @override
5127 accept(ElementVisitor visitor) => visitor.visitFunctionTypeAliasElement(this);
5128
5129 @override
5130 ElementImpl getChild(String identifier) {
5131 for (VariableElement parameter in _parameters) {
5132 if ((parameter as VariableElementImpl).identifier == identifier) {
5133 return parameter as VariableElementImpl;
5134 }
5135 }
5136 for (TypeParameterElement typeParameter in _typeParameters) {
5137 if ((typeParameter as TypeParameterElementImpl).identifier == identifier) {
5138 return typeParameter as TypeParameterElementImpl;
5139 }
5140 }
5141 return null;
5142 }
5143
5144 @override
5145 CompilationUnitElement get enclosingElement => super.enclosingElement as Compi lationUnitElement;
5146
5147 @override
5148 ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
5149
5150 @override
5151 FunctionTypeAlias get node => getNodeMatching((node) => node is FunctionTypeAl ias);
5152
5153 @override
5154 List<ParameterElement> get parameters => _parameters;
5155
5156 @override
5157 List<TypeParameterElement> get typeParameters => _typeParameters;
5158
5159 /**
5160 * Set the parameters defined by this type alias to the given parameters.
5161 *
5162 * @param parameters the parameters defined by this type alias
5163 */
5164 void set parameters(List<ParameterElement> parameters) {
5165 if (parameters != null) {
5166 for (ParameterElement parameter in parameters) {
5167 (parameter as ParameterElementImpl).enclosingElement = this;
5168 }
5169 }
5170 this._parameters = parameters;
5171 }
5172
5173 /**
5174 * Set the type parameters defined for this type to the given parameters.
5175 *
5176 * @param typeParameters the type parameters defined for this type
5177 */
5178 void set typeParameters(List<TypeParameterElement> typeParameters) {
5179 for (TypeParameterElement typeParameter in typeParameters) {
5180 (typeParameter as TypeParameterElementImpl).enclosingElement = this;
5181 }
5182 this._typeParameters = typeParameters;
5183 }
5184
5185 /**
5186 * Set the parameters defined by this type alias to the given parameters witho ut becoming the
5187 * parent of the parameters. This should only be used by the [TypeResolverVisi tor] when
5188 * creating a synthetic type alias.
5189 *
5190 * @param parameters the parameters defined by this type alias
5191 */
5192 void shareParameters(List<ParameterElement> parameters) {
5193 this._parameters = parameters;
5194 }
5195
5196 /**
5197 * Set the type parameters defined for this type to the given parameters witho ut becoming the
5198 * parent of the parameters. This should only be used by the [TypeResolverVisi tor] when
5199 * creating a synthetic type alias.
5200 *
5201 * @param typeParameters the type parameters defined for this type
5202 */
5203 void shareTypeParameters(List<TypeParameterElement> typeParameters) {
5204 this._typeParameters = typeParameters;
5205 }
5206
5207 @override
5208 void visitChildren(ElementVisitor visitor) {
5209 super.visitChildren(visitor);
5210 safelyVisitChildren(_parameters, visitor);
5211 safelyVisitChildren(_typeParameters, visitor);
5212 }
5213
5214 @override
5215 void appendTo(JavaStringBuilder builder) {
5216 builder.append("typedef ");
5217 builder.append(displayName);
5218 int typeParameterCount = _typeParameters.length;
5219 if (typeParameterCount > 0) {
5220 builder.append("<");
5221 for (int i = 0; i < typeParameterCount; i++) {
5222 if (i > 0) {
5223 builder.append(", ");
5224 }
5225 (_typeParameters[i] as TypeParameterElementImpl).appendTo(builder);
5226 }
5227 builder.append(">");
5228 }
5229 builder.append("(");
5230 int parameterCount = _parameters.length;
5231 for (int i = 0; i < parameterCount; i++) {
5232 if (i > 0) {
5233 builder.append(", ");
5234 }
5235 (_parameters[i] as ParameterElementImpl).appendTo(builder);
5236 }
5237 builder.append(")");
5238 if (type != null) {
5239 builder.append(Element.RIGHT_ARROW);
5240 builder.append(type.returnType);
5241 }
5242 }
5243 }
5244
5245 /**
5246 * Instances of the class `FunctionTypeImpl` defines the behavior common to obje cts
5247 * representing the type of a function, method, constructor, getter, or setter.
5248 */
5249 class FunctionTypeImpl extends TypeImpl implements FunctionType {
5250 /**
5251 * Return `true` if all of the name/type pairs in the first map are equal to t he
5252 * corresponding name/type pairs in the second map. The maps are expected to i terate over their
5253 * entries in the same order in which those entries were added to the map.
5254 *
5255 * @param firstTypes the first map of name/type pairs being compared
5256 * @param secondTypes the second map of name/type pairs being compared
5257 * @param visitedElementPairs a set of visited element pairs
5258 * @return `true` if all of the name/type pairs in the first map are equal to the
5259 * corresponding name/type pairs in the second map
5260 */
5261 static bool _equals(Map<String, DartType> firstTypes, Map<String, DartType> se condTypes, Set<ElementPair> visitedElementPairs) {
5262 if (secondTypes.length != firstTypes.length) {
5263 return false;
5264 }
5265 JavaIterator<MapEntry<String, DartType>> firstIterator = new JavaIterator(ge tMapEntrySet(firstTypes));
5266 JavaIterator<MapEntry<String, DartType>> secondIterator = new JavaIterator(g etMapEntrySet(secondTypes));
5267 while (firstIterator.hasNext) {
5268 MapEntry<String, DartType> firstEntry = firstIterator.next();
5269 MapEntry<String, DartType> secondEntry = secondIterator.next();
5270 if (firstEntry.getKey() != secondEntry.getKey() || !(firstEntry.getValue() as TypeImpl).internalEquals(secondEntry.getValue(), visitedElementPairs)) {
5271 return false;
5272 }
5273 }
5274 return true;
5275 }
5276
5277 /**
5278 * An array containing the actual types of the type arguments.
5279 */
5280 List<DartType> typeArguments = TypeImpl.EMPTY_ARRAY;
5281
5282 /**
5283 * Initialize a newly created function type to be declared by the given elemen t and to have the
5284 * given name.
5285 *
5286 * @param element the element representing the declaration of the function typ e
5287 */
5288 FunctionTypeImpl.con1(ExecutableElement element) : super(element, element == n ull ? null : element.name);
5289
5290 /**
5291 * Initialize a newly created function type to be declared by the given elemen t and to have the
5292 * given name.
5293 *
5294 * @param element the element representing the declaration of the function typ e
5295 */
5296 FunctionTypeImpl.con2(FunctionTypeAliasElement element) : super(element, eleme nt == null ? null : element.name);
5297
5298 @override
5299 bool operator ==(Object object) => internalEquals(object, new HashSet<ElementP air>());
5300
5301 @override
5302 String get displayName {
5303 String name = this.name;
5304 if (name == null || name.length == 0) {
5305 // Function types have an empty name when they are defined implicitly by e ither a closure or
5306 // as part of a parameter declaration.
5307 List<DartType> normalParameterTypes = this.normalParameterTypes;
5308 List<DartType> optionalParameterTypes = this.optionalParameterTypes;
5309 Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
5310 DartType returnType = this.returnType;
5311 JavaStringBuilder builder = new JavaStringBuilder();
5312 builder.append("(");
5313 bool needsComma = false;
5314 if (normalParameterTypes.length > 0) {
5315 for (DartType type in normalParameterTypes) {
5316 if (needsComma) {
5317 builder.append(", ");
5318 } else {
5319 needsComma = true;
5320 }
5321 builder.append(type.displayName);
5322 }
5323 }
5324 if (optionalParameterTypes.length > 0) {
5325 if (needsComma) {
5326 builder.append(", ");
5327 needsComma = false;
5328 }
5329 builder.append("[");
5330 for (DartType type in optionalParameterTypes) {
5331 if (needsComma) {
5332 builder.append(", ");
5333 } else {
5334 needsComma = true;
5335 }
5336 builder.append(type.displayName);
5337 }
5338 builder.append("]");
5339 needsComma = true;
5340 }
5341 if (namedParameterTypes.length > 0) {
5342 if (needsComma) {
5343 builder.append(", ");
5344 needsComma = false;
5345 }
5346 builder.append("{");
5347 for (MapEntry<String, DartType> entry in getMapEntrySet(namedParameterTy pes)) {
5348 if (needsComma) {
5349 builder.append(", ");
5350 } else {
5351 needsComma = true;
5352 }
5353 builder.append(entry.getKey());
5354 builder.append(": ");
5355 builder.append(entry.getValue().displayName);
5356 }
5357 builder.append("}");
5358 needsComma = true;
5359 }
5360 builder.append(")");
5361 builder.append(Element.RIGHT_ARROW);
5362 if (returnType == null) {
5363 builder.append("null");
5364 } else {
5365 builder.append(returnType.displayName);
5366 }
5367 name = builder.toString();
5368 }
5369 return name;
5370 }
5371
5372 @override
5373 Map<String, DartType> get namedParameterTypes {
5374 LinkedHashMap<String, DartType> namedParameterTypes = new LinkedHashMap<Stri ng, DartType>();
5375 List<ParameterElement> parameters = baseParameters;
5376 if (parameters.length == 0) {
5377 return namedParameterTypes;
5378 }
5379 List<DartType> typeParameters = TypeParameterTypeImpl.getTypes(this.typePara meters);
5380 for (ParameterElement parameter in parameters) {
5381 if (parameter.parameterKind == ParameterKind.NAMED) {
5382 DartType type = parameter.type;
5383 if (typeArguments.length != 0 && typeArguments.length == typeParameters. length) {
5384 type = type.substitute2(typeArguments, typeParameters);
5385 }
5386 namedParameterTypes[parameter.name] = type;
5387 }
5388 }
5389 return namedParameterTypes;
5390 }
5391
5392 @override
5393 List<DartType> get normalParameterTypes {
5394 List<ParameterElement> parameters = baseParameters;
5395 if (parameters.length == 0) {
5396 return TypeImpl.EMPTY_ARRAY;
5397 }
5398 List<DartType> typeParameters = TypeParameterTypeImpl.getTypes(this.typePara meters);
5399 List<DartType> types = new List<DartType>();
5400 for (ParameterElement parameter in parameters) {
5401 if (parameter.parameterKind == ParameterKind.REQUIRED) {
5402 DartType type = parameter.type;
5403 if (typeArguments.length != 0 && typeArguments.length == typeParameters. length) {
5404 type = type.substitute2(typeArguments, typeParameters);
5405 }
5406 types.add(type);
5407 }
5408 }
5409 return new List.from(types);
5410 }
5411
5412 @override
5413 List<DartType> get optionalParameterTypes {
5414 List<ParameterElement> parameters = baseParameters;
5415 if (parameters.length == 0) {
5416 return TypeImpl.EMPTY_ARRAY;
5417 }
5418 List<DartType> typeParameters = TypeParameterTypeImpl.getTypes(this.typePara meters);
5419 List<DartType> types = new List<DartType>();
5420 for (ParameterElement parameter in parameters) {
5421 if (parameter.parameterKind == ParameterKind.POSITIONAL) {
5422 DartType type = parameter.type;
5423 if (typeArguments.length != 0 && typeArguments.length == typeParameters. length) {
5424 type = type.substitute2(typeArguments, typeParameters);
5425 }
5426 types.add(type);
5427 }
5428 }
5429 return new List.from(types);
5430 }
5431
5432 @override
5433 List<ParameterElement> get parameters {
5434 List<ParameterElement> baseParameters = this.baseParameters;
5435 // no parameters, quick return
5436 int parameterCount = baseParameters.length;
5437 if (parameterCount == 0) {
5438 return baseParameters;
5439 }
5440 // create specialized parameters
5441 List<ParameterElement> specializedParameters = new List<ParameterElement>(pa rameterCount);
5442 for (int i = 0; i < parameterCount; i++) {
5443 specializedParameters[i] = ParameterMember.from(baseParameters[i], this);
5444 }
5445 return specializedParameters;
5446 }
5447
5448 @override
5449 DartType get returnType {
5450 DartType baseReturnType = this.baseReturnType;
5451 if (baseReturnType == null) {
5452 // TODO(brianwilkerson) This is a patch. The return type should never be n ull and we need to
5453 // understand why it is and fix it.
5454 return DynamicTypeImpl.instance;
5455 }
5456 // If there are no arguments to substitute, or if the arguments size doesn't match the parameter
5457 // size, return the base return type.
5458 if (typeArguments.length == 0 || typeArguments.length != typeParameters.leng th) {
5459 return baseReturnType;
5460 }
5461 return baseReturnType.substitute2(typeArguments, TypeParameterTypeImpl.getTy pes(typeParameters));
5462 }
5463
5464 @override
5465 List<TypeParameterElement> get typeParameters {
5466 Element element = this.element;
5467 if (element is FunctionTypeAliasElement) {
5468 return element.typeParameters;
5469 }
5470 ClassElement definingClass = element.getAncestor((element) => element is Cla ssElement);
5471 if (definingClass != null) {
5472 return definingClass.typeParameters;
5473 }
5474 return TypeParameterElementImpl.EMPTY_ARRAY;
5475 }
5476
5477 @override
5478 int get hashCode {
5479 if (element == null) {
5480 return 0;
5481 }
5482 // Reference the arrays of parameters
5483 List<DartType> normalParameterTypes = this.normalParameterTypes;
5484 List<DartType> optionalParameterTypes = this.optionalParameterTypes;
5485 Iterable<DartType> namedParameterTypes = this.namedParameterTypes.values;
5486 // Generate the hashCode
5487 int hashCode = returnType.hashCode;
5488 for (int i = 0; i < normalParameterTypes.length; i++) {
5489 hashCode = (hashCode << 1) + normalParameterTypes[i].hashCode;
5490 }
5491 for (int i = 0; i < optionalParameterTypes.length; i++) {
5492 hashCode = (hashCode << 1) + optionalParameterTypes[i].hashCode;
5493 }
5494 for (DartType type in namedParameterTypes) {
5495 hashCode = (hashCode << 1) + type.hashCode;
5496 }
5497 return hashCode;
5498 }
5499
5500 @override
5501 bool internalIsMoreSpecificThan(DartType type, bool withDynamic, Set<TypeImpl_ TypePair> visitedTypePairs) {
5502 // trivial base cases
5503 if (type == null) {
5504 return false;
5505 } else if (identical(this, type) || type.isDynamic || type.isDartCoreFunctio n || type.isObject) {
5506 return true;
5507 } else if (type is UnionType) {
5508 return (type as UnionTypeImpl).internalUnionTypeIsMoreSpecificThan(this, w ithDynamic, visitedTypePairs);
5509 } else if (type is! FunctionType) {
5510 return false;
5511 } else if (this == type) {
5512 return true;
5513 }
5514 FunctionType t = this;
5515 FunctionType s = type as FunctionType;
5516 List<DartType> tTypes = t.normalParameterTypes;
5517 List<DartType> tOpTypes = t.optionalParameterTypes;
5518 List<DartType> sTypes = s.normalParameterTypes;
5519 List<DartType> sOpTypes = s.optionalParameterTypes;
5520 // If one function has positional and the other has named parameters, return false.
5521 if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || (tOpTypes.l ength > 0 && s.namedParameterTypes.length > 0)) {
5522 return false;
5523 }
5524 // named parameters case
5525 if (t.namedParameterTypes.length > 0) {
5526 // check that the number of required parameters are equal, and check that every t_i is
5527 // more specific than every s_i
5528 if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
5529 return false;
5530 } else if (t.normalParameterTypes.length > 0) {
5531 for (int i = 0; i < tTypes.length; i++) {
5532 if (!(tTypes[i] as TypeImpl).isMoreSpecificThan2(sTypes[i], withDynami c, visitedTypePairs)) {
5533 return false;
5534 }
5535 }
5536 }
5537 Map<String, DartType> namedTypesT = t.namedParameterTypes;
5538 Map<String, DartType> namedTypesS = s.namedParameterTypes;
5539 // if k >= m is false, return false: the passed function type has more nam ed parameter types than this
5540 if (namedTypesT.length < namedTypesS.length) {
5541 return false;
5542 }
5543 // Loop through each element in S verifying that T has a matching paramete r name and that the
5544 // corresponding type is more specific then the type in S.
5545 JavaIterator<MapEntry<String, DartType>> iteratorS = new JavaIterator(getM apEntrySet(namedTypesS));
5546 while (iteratorS.hasNext) {
5547 MapEntry<String, DartType> entryS = iteratorS.next();
5548 DartType typeT = namedTypesT[entryS.getKey()];
5549 if (typeT == null) {
5550 return false;
5551 }
5552 if (!(typeT as TypeImpl).isMoreSpecificThan2(entryS.getValue(), withDyna mic, visitedTypePairs)) {
5553 return false;
5554 }
5555 }
5556 } else if (s.namedParameterTypes.length > 0) {
5557 return false;
5558 } else {
5559 // positional parameter case
5560 int tArgLength = tTypes.length + tOpTypes.length;
5561 int sArgLength = sTypes.length + sOpTypes.length;
5562 // Check that the total number of parameters in t is greater than or equal to the number of
5563 // parameters in s and that the number of required parameters in s is grea ter than or equal to
5564 // the number of required parameters in t.
5565 if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
5566 return false;
5567 }
5568 if (tOpTypes.length == 0 && sOpTypes.length == 0) {
5569 // No positional arguments, don't copy contents to new array
5570 for (int i = 0; i < sTypes.length; i++) {
5571 if (!(tTypes[i] as TypeImpl).isMoreSpecificThan2(sTypes[i], withDynami c, visitedTypePairs)) {
5572 return false;
5573 }
5574 }
5575 } else {
5576 // Else, we do have positional parameters, copy required and positional parameter types into
5577 // arrays to do the compare (for loop below).
5578 List<DartType> tAllTypes = new List<DartType>(sArgLength);
5579 for (int i = 0; i < tTypes.length; i++) {
5580 tAllTypes[i] = tTypes[i];
5581 }
5582 for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) {
5583 tAllTypes[i] = tOpTypes[j];
5584 }
5585 List<DartType> sAllTypes = new List<DartType>(sArgLength);
5586 for (int i = 0; i < sTypes.length; i++) {
5587 sAllTypes[i] = sTypes[i];
5588 }
5589 for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) {
5590 sAllTypes[i] = sOpTypes[j];
5591 }
5592 for (int i = 0; i < sAllTypes.length; i++) {
5593 if (!(tAllTypes[i] as TypeImpl).isMoreSpecificThan2(sAllTypes[i], with Dynamic, visitedTypePairs)) {
5594 return false;
5595 }
5596 }
5597 }
5598 }
5599 DartType tRetType = t.returnType;
5600 DartType sRetType = s.returnType;
5601 return sRetType.isVoid || (tRetType as TypeImpl).isMoreSpecificThan2(sRetTyp e, withDynamic, visitedTypePairs);
5602 }
5603
5604 /**
5605 * Return `true` if this type is assignable to the given type. A function type <i>T</i> may
5606 * be assigned to a function type <i>S</i>, written <i>T</i> &hArr; <i>S</i>, iff <i>T</i> <:
5607 * <i>S</i> (Function Types section of spec). Note that this is more restricti ve than the
5608 * "may be assigned to" rule for interface types.
5609 *
5610 *
5611 * @param type the type being compared with this type
5612 * @return `true` if this type is assignable to the given type
5613 */
5614 @override
5615 bool isAssignableTo(DartType type) => isSubtypeOf2(type, new HashSet<TypeImpl_ TypePair>());
5616
5617 @override
5618 FunctionTypeImpl substitute3(List<DartType> argumentTypes) => substitute2(argu mentTypes, typeArguments);
5619
5620 @override
5621 FunctionTypeImpl substitute2(List<DartType> argumentTypes, List<DartType> para meterTypes) {
5622 if (argumentTypes.length != parameterTypes.length) {
5623 throw new IllegalArgumentException("argumentTypes.length (${argumentTypes. length}) != parameterTypes.length (${parameterTypes.length})");
5624 }
5625 if (argumentTypes.length == 0) {
5626 return this;
5627 }
5628 Element element = this.element;
5629 FunctionTypeImpl newType = (element is ExecutableElement) ? new FunctionType Impl.con1(element) : new FunctionTypeImpl.con2(element as FunctionTypeAliasEleme nt);
5630 newType.typeArguments = TypeImpl.substitute(typeArguments, argumentTypes, pa rameterTypes);
5631 return newType;
5632 }
5633
5634 @override
5635 void appendTo(JavaStringBuilder builder) {
5636 List<DartType> normalParameterTypes = this.normalParameterTypes;
5637 List<DartType> optionalParameterTypes = this.optionalParameterTypes;
5638 Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
5639 DartType returnType = this.returnType;
5640 builder.append("(");
5641 bool needsComma = false;
5642 if (normalParameterTypes.length > 0) {
5643 for (DartType type in normalParameterTypes) {
5644 if (needsComma) {
5645 builder.append(", ");
5646 } else {
5647 needsComma = true;
5648 }
5649 (type as TypeImpl).appendTo(builder);
5650 }
5651 }
5652 if (optionalParameterTypes.length > 0) {
5653 if (needsComma) {
5654 builder.append(", ");
5655 needsComma = false;
5656 }
5657 builder.append("[");
5658 for (DartType type in optionalParameterTypes) {
5659 if (needsComma) {
5660 builder.append(", ");
5661 } else {
5662 needsComma = true;
5663 }
5664 (type as TypeImpl).appendTo(builder);
5665 }
5666 builder.append("]");
5667 needsComma = true;
5668 }
5669 if (namedParameterTypes.length > 0) {
5670 if (needsComma) {
5671 builder.append(", ");
5672 needsComma = false;
5673 }
5674 builder.append("{");
5675 for (MapEntry<String, DartType> entry in getMapEntrySet(namedParameterType s)) {
5676 if (needsComma) {
5677 builder.append(", ");
5678 } else {
5679 needsComma = true;
5680 }
5681 builder.append(entry.getKey());
5682 builder.append(": ");
5683 (entry.getValue() as TypeImpl).appendTo(builder);
5684 }
5685 builder.append("}");
5686 needsComma = true;
5687 }
5688 builder.append(")");
5689 builder.append(Element.RIGHT_ARROW);
5690 if (returnType == null) {
5691 builder.append("null");
5692 } else {
5693 (returnType as TypeImpl).appendTo(builder);
5694 }
5695 }
5696
5697 /**
5698 * @return the base parameter elements of this function element, not `null`.
5699 */
5700 List<ParameterElement> get baseParameters {
5701 Element element = this.element;
5702 if (element is ExecutableElement) {
5703 return element.parameters;
5704 } else {
5705 return (element as FunctionTypeAliasElement).parameters;
5706 }
5707 }
5708
5709 @override
5710 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) {
5711 if (object is! FunctionTypeImpl) {
5712 return false;
5713 }
5714 FunctionTypeImpl otherType = object as FunctionTypeImpl;
5715 // If the visitedTypePairs already has the pair (this, type), use the elemen ts to determine equality
5716 ElementPair elementPair = new ElementPair(element, otherType.element);
5717 if (!visitedElementPairs.add(elementPair)) {
5718 return elementPair.firstElt == elementPair.secondElt;
5719 }
5720 // Compute the result
5721 bool result = TypeImpl.equalArrays(normalParameterTypes, otherType.normalPar ameterTypes, visitedElementPairs) && TypeImpl.equalArrays(optionalParameterTypes , otherType.optionalParameterTypes, visitedElementPairs) && _equals(namedParamet erTypes, otherType.namedParameterTypes, visitedElementPairs) && (returnType as T ypeImpl).internalEquals(otherType.returnType, visitedElementPairs);
5722 // Remove the pair from our visited pairs list
5723 visitedElementPairs.remove(elementPair);
5724 // Return the result
5725 return result;
5726 }
5727
5728 @override
5729 bool internalIsSubtypeOf(DartType type, Set<TypeImpl_TypePair> visitedTypePair s) {
5730 // trivial base cases
5731 if (type == null) {
5732 return false;
5733 } else if (identical(this, type) || type.isDynamic || type.isDartCoreFunctio n || type.isObject) {
5734 return true;
5735 } else if (type is UnionType) {
5736 return (type as UnionTypeImpl).internalUnionTypeIsSuperTypeOf(this, visite dTypePairs);
5737 } else if (type is! FunctionType) {
5738 return false;
5739 } else if (this == type) {
5740 return true;
5741 }
5742 FunctionType t = this;
5743 FunctionType s = type as FunctionType;
5744 List<DartType> tTypes = t.normalParameterTypes;
5745 List<DartType> tOpTypes = t.optionalParameterTypes;
5746 List<DartType> sTypes = s.normalParameterTypes;
5747 List<DartType> sOpTypes = s.optionalParameterTypes;
5748 // If one function has positional and the other has named parameters, return false.
5749 if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || (tOpTypes.l ength > 0 && s.namedParameterTypes.length > 0)) {
5750 return false;
5751 }
5752 // named parameters case
5753 if (t.namedParameterTypes.length > 0) {
5754 // check that the number of required parameters are equal, and check that every t_i is
5755 // assignable to every s_i
5756 if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
5757 return false;
5758 } else if (t.normalParameterTypes.length > 0) {
5759 for (int i = 0; i < tTypes.length; i++) {
5760 if (!(tTypes[i] as TypeImpl).isAssignableTo2(sTypes[i], visitedTypePai rs)) {
5761 return false;
5762 }
5763 }
5764 }
5765 Map<String, DartType> namedTypesT = t.namedParameterTypes;
5766 Map<String, DartType> namedTypesS = s.namedParameterTypes;
5767 // if k >= m is false, return false: the passed function type has more nam ed parameter types than this
5768 if (namedTypesT.length < namedTypesS.length) {
5769 return false;
5770 }
5771 // Loop through each element in S verifying that T has a matching paramete r name and that the
5772 // corresponding type is assignable to the type in S.
5773 JavaIterator<MapEntry<String, DartType>> iteratorS = new JavaIterator(getM apEntrySet(namedTypesS));
5774 while (iteratorS.hasNext) {
5775 MapEntry<String, DartType> entryS = iteratorS.next();
5776 DartType typeT = namedTypesT[entryS.getKey()];
5777 if (typeT == null) {
5778 return false;
5779 }
5780 if (!(typeT as TypeImpl).isAssignableTo2(entryS.getValue(), visitedTypeP airs)) {
5781 return false;
5782 }
5783 }
5784 } else if (s.namedParameterTypes.length > 0) {
5785 return false;
5786 } else {
5787 // positional parameter case
5788 int tArgLength = tTypes.length + tOpTypes.length;
5789 int sArgLength = sTypes.length + sOpTypes.length;
5790 // Check that the total number of parameters in t is greater than or equal to the number of
5791 // parameters in s and that the number of required parameters in s is grea ter than or equal to
5792 // the number of required parameters in t.
5793 if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
5794 return false;
5795 }
5796 if (tOpTypes.length == 0 && sOpTypes.length == 0) {
5797 // No positional arguments, don't copy contents to new array
5798 for (int i = 0; i < sTypes.length; i++) {
5799 if (!(tTypes[i] as TypeImpl).isAssignableTo2(sTypes[i], visitedTypePai rs)) {
5800 return false;
5801 }
5802 }
5803 } else {
5804 // Else, we do have positional parameters, copy required and positional parameter types into
5805 // arrays to do the compare (for loop below).
5806 List<DartType> tAllTypes = new List<DartType>(sArgLength);
5807 for (int i = 0; i < tTypes.length; i++) {
5808 tAllTypes[i] = tTypes[i];
5809 }
5810 for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) {
5811 tAllTypes[i] = tOpTypes[j];
5812 }
5813 List<DartType> sAllTypes = new List<DartType>(sArgLength);
5814 for (int i = 0; i < sTypes.length; i++) {
5815 sAllTypes[i] = sTypes[i];
5816 }
5817 for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) {
5818 sAllTypes[i] = sOpTypes[j];
5819 }
5820 for (int i = 0; i < sAllTypes.length; i++) {
5821 if (!(tAllTypes[i] as TypeImpl).isAssignableTo2(sAllTypes[i], visitedT ypePairs)) {
5822 return false;
5823 }
5824 }
5825 }
5826 }
5827 DartType tRetType = t.returnType;
5828 DartType sRetType = s.returnType;
5829 return sRetType.isVoid || (tRetType as TypeImpl).isAssignableTo2(sRetType, v isitedTypePairs);
5830 }
5831
5832 /**
5833 * Return the return type defined by this function's element.
5834 *
5835 * @return the return type defined by this function's element
5836 */
5837 DartType get baseReturnType {
5838 Element element = this.element;
5839 if (element is ExecutableElement) {
5840 return element.returnType;
5841 } else {
5842 return (element as FunctionTypeAliasElement).returnType;
5843 }
5844 }
5845 }
5846
5847 /**
5848 * Instances of the class `GeneralizingElementVisitor` implement an element visi tor that will
5849 * recursively visit all of the elements in an element model (like instances of the class
5850 * [RecursiveElementVisitor]). In addition, when an element of a specific type i s visited not
5851 * only will the visit method for that specific type of element be invoked, but additional methods
5852 * for the supertypes of that element will also be invoked. For example, using a n instance of this
5853 * class to visit a [MethodElement] will cause the method
5854 * [visitMethodElement] to be invoked but will also cause the methods
5855 * [visitExecutableElement] and [visitElement] to be
5856 * subsequently invoked. This allows visitors to be written that visit all execu table elements
5857 * without needing to override the visit method for each of the specific subclas ses of
5858 * [ExecutableElement].
5859 *
5860 * Note, however, that unlike many visitors, element visitors visit objects base d on the interfaces
5861 * implemented by those elements. Because interfaces form a graph structure rath er than a tree
5862 * structure the way classes do, and because it is generally undesirable for an object to be visited
5863 * more than once, this class flattens the interface graph into a pseudo-tree. I n particular, this
5864 * class treats elements as if the element types were structured in the followin g way:
5865 *
5866 *
5867 * <pre>
5868 * Element
5869 * ClassElement
5870 * CompilationUnitElement
5871 * ExecutableElement
5872 * ConstructorElement
5873 * LocalElement
5874 * FunctionElement
5875 * MethodElement
5876 * PropertyAccessorElement
5877 * ExportElement
5878 * HtmlElement
5879 * ImportElement
5880 * LabelElement
5881 * LibraryElement
5882 * MultiplyDefinedElement
5883 * PrefixElement
5884 * TypeAliasElement
5885 * TypeParameterElement
5886 * UndefinedElement
5887 * VariableElement
5888 * PropertyInducingElement
5889 * FieldElement
5890 * TopLevelVariableElement
5891 * LocalElement
5892 * LocalVariableElement
5893 * ParameterElement
5894 * FieldFormalParameterElement
5895 * </pre>
5896 *
5897 * Subclasses that override a visit method must either invoke the overridden vis it method or
5898 * explicitly invoke the more general visit method. Failure to do so will cause the visit methods
5899 * for superclasses of the element to not be invoked and will cause the children of the visited node
5900 * to not be visited.
5901 */
5902 class GeneralizingElementVisitor<R> implements ElementVisitor<R> {
5903 @override
5904 R visitAngularComponentElement(AngularComponentElement element) => visitAngula rHasSelectorElement(element);
5905
5906 @override
5907 R visitAngularControllerElement(AngularControllerElement element) => visitAngu larHasSelectorElement(element);
5908
5909 @override
5910 R visitAngularDirectiveElement(AngularDecoratorElement element) => visitAngula rHasSelectorElement(element);
5911
5912 R visitAngularElement(AngularElement element) => visitToolkitObjectElement(ele ment);
5913
5914 @override
5915 R visitAngularFormatterElement(AngularFormatterElement element) => visitAngula rElement(element);
5916
5917 R visitAngularHasSelectorElement(AngularHasSelectorElement element) => visitAn gularElement(element);
5918
5919 @override
5920 R visitAngularPropertyElement(AngularPropertyElement element) => visitAngularE lement(element);
5921
5922 @override
5923 R visitAngularScopePropertyElement(AngularScopePropertyElement element) => vis itAngularElement(element);
5924
5925 @override
5926 R visitAngularSelectorElement(AngularSelectorElement element) => visitAngularE lement(element);
5927
5928 @override
5929 R visitAngularViewElement(AngularViewElement element) => visitAngularElement(e lement);
5930
5931 @override
5932 R visitClassElement(ClassElement element) => visitElement(element);
5933
5934 @override
5935 R visitCompilationUnitElement(CompilationUnitElement element) => visitElement( element);
5936
5937 @override
5938 R visitConstructorElement(ConstructorElement element) => visitExecutableElemen t(element);
5939
5940 R visitElement(Element element) {
5941 element.visitChildren(this);
5942 return null;
5943 }
5944
5945 @override
5946 R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) => visitHt mlScriptElement(element);
5947
5948 R visitExecutableElement(ExecutableElement element) => visitElement(element);
5949
5950 @override
5951 R visitExportElement(ExportElement element) => visitElement(element);
5952
5953 @override
5954 R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) => visitHt mlScriptElement(element);
5955
5956 @override
5957 R visitFieldElement(FieldElement element) => visitPropertyInducingElement(elem ent);
5958
5959 @override
5960 R visitFieldFormalParameterElement(FieldFormalParameterElement element) => vis itParameterElement(element);
5961
5962 @override
5963 R visitFunctionElement(FunctionElement element) => visitLocalElement(element);
5964
5965 @override
5966 R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) => visitElem ent(element);
5967
5968 @override
5969 R visitHtmlElement(HtmlElement element) => visitElement(element);
5970
5971 R visitHtmlScriptElement(HtmlScriptElement element) => visitElement(element);
5972
5973 @override
5974 R visitImportElement(ImportElement element) => visitElement(element);
5975
5976 @override
5977 R visitLabelElement(LabelElement element) => visitElement(element);
5978
5979 @override
5980 R visitLibraryElement(LibraryElement element) => visitElement(element);
5981
5982 R visitLocalElement(LocalElement element) {
5983 if (element is LocalVariableElement) {
5984 return visitVariableElement(element);
5985 } else if (element is ParameterElement) {
5986 return visitVariableElement(element);
5987 } else if (element is FunctionElement) {
5988 return visitExecutableElement(element);
5989 }
5990 return null;
5991 }
5992
5993 @override
5994 R visitLocalVariableElement(LocalVariableElement element) => visitLocalElement (element);
5995
5996 @override
5997 R visitMethodElement(MethodElement element) => visitExecutableElement(element) ;
5998
5999 @override
6000 R visitMultiplyDefinedElement(MultiplyDefinedElement element) => visitElement( element);
6001
6002 @override
6003 R visitParameterElement(ParameterElement element) => visitLocalElement(element );
6004
6005 @override
6006 R visitPolymerAttributeElement(PolymerAttributeElement element) => visitPolyme rElement(element);
6007
6008 R visitPolymerElement(PolymerElement element) => visitToolkitObjectElement(ele ment);
6009
6010 @override
6011 R visitPolymerTagDartElement(PolymerTagDartElement element) => visitPolymerEle ment(element);
6012
6013 @override
6014 R visitPolymerTagHtmlElement(PolymerTagHtmlElement element) => visitPolymerEle ment(element);
6015
6016 @override
6017 R visitPrefixElement(PrefixElement element) => visitElement(element);
6018
6019 @override
6020 R visitPropertyAccessorElement(PropertyAccessorElement element) => visitExecut ableElement(element);
6021
6022 R visitPropertyInducingElement(PropertyInducingElement element) => visitVariab leElement(element);
6023
6024 R visitToolkitObjectElement(ToolkitObjectElement element) => visitElement(elem ent);
6025
6026 @override
6027 R visitTopLevelVariableElement(TopLevelVariableElement element) => visitProper tyInducingElement(element);
6028
6029 @override
6030 R visitTypeParameterElement(TypeParameterElement element) => visitElement(elem ent);
6031
6032 R visitVariableElement(VariableElement element) => visitElement(element);
6033 }
6034
6035 /**
6036 * Implementation of [AngularSelectorElement] based on presence of attribute.
6037 */
6038 class HasAttributeSelectorElementImpl extends AngularSelectorElementImpl impleme nts AngularHasAttributeSelectorElement {
6039 HasAttributeSelectorElementImpl(String attributeName, int offset) : super(attr ibuteName, offset);
6040
6041 @override
6042 bool apply(XmlTagNode node) {
6043 String attributeName = name;
6044 return node.getAttribute(attributeName) != null;
6045 }
6046
6047 @override
6048 void appendTo(JavaStringBuilder builder) {
6049 builder.append("[");
6050 builder.append(name);
6051 builder.append("]");
6052 }
6053 }
6054
6055 /**
6056 * The interface `HideElementCombinator` defines the behavior of combinators tha t cause some
6057 * of the names in a namespace to be hidden when being imported.
6058 */
6059 abstract class HideElementCombinator implements NamespaceCombinator {
6060 /**
6061 * Return an array containing the names that are not to be made visible in the importing library
6062 * even if they are defined in the imported library.
6063 *
6064 * @return the names from the imported library that are hidden from the import ing library
6065 */
6066 List<String> get hiddenNames;
6067 }
6068
6069 /**
6070 * Instances of the class `HideElementCombinatorImpl` implement a
6071 * [HideElementCombinator].
6072 */
6073 class HideElementCombinatorImpl implements HideElementCombinator {
6074 /**
6075 * The names that are not to be made visible in the importing library even if they are defined in
6076 * the imported library.
6077 */
6078 List<String> hiddenNames = StringUtilities.EMPTY_ARRAY;
6079
6080 @override
6081 String toString() {
6082 JavaStringBuilder builder = new JavaStringBuilder();
6083 builder.append("show ");
6084 int count = hiddenNames.length;
6085 for (int i = 0; i < count; i++) {
6086 if (i > 0) {
6087 builder.append(", ");
6088 }
6089 builder.append(hiddenNames[i]);
6090 }
6091 return builder.toString();
6092 }
6093 }
6094
6095 /**
6096 * The interface `HtmlElement` defines the behavior of elements representing an HTML file.
6097 */
6098 abstract class HtmlElement implements Element {
6099 /**
6100 * Return the [CompilationUnitElement] associated with this Angular HTML file, maybe
6101 * `null` if not an Angular file.
6102 */
6103 CompilationUnitElement get angularCompilationUnit;
6104
6105 /**
6106 * Return an array containing all of the [PolymerTagHtmlElement]s defined in t he HTML file.
6107 *
6108 * @return the [PolymerTagHtmlElement]s elements in the HTML file (not `null`,
6109 * contains no `null`s)
6110 */
6111 List<PolymerTagHtmlElement> get polymerTags;
6112
6113 /**
6114 * Return an array containing all of the script elements contained in the HTML file. This includes
6115 * scripts with libraries that are defined by the content of a script tag as w ell as libraries
6116 * that are referenced in the {@core source} attribute of a script tag.
6117 *
6118 * @return the script elements in the HTML file (not `null`, contains no `null `s)
6119 */
6120 List<HtmlScriptElement> get scripts;
6121 }
6122
6123 /**
6124 * Instances of the class `HtmlElementImpl` implement an [HtmlElement].
6125 */
6126 class HtmlElementImpl extends ElementImpl implements HtmlElement {
6127 /**
6128 * An empty array of HTML file elements.
6129 */
6130 static List<HtmlElement> EMPTY_ARRAY = new List<HtmlElement>(0);
6131
6132 /**
6133 * The analysis context in which this library is defined.
6134 */
6135 final AnalysisContext context;
6136
6137 /**
6138 * The scripts contained in or referenced from script tags in the HTML file.
6139 */
6140 List<HtmlScriptElement> _scripts = HtmlScriptElementImpl.EMPTY_ARRAY;
6141
6142 /**
6143 * The [PolymerTagHtmlElement]s defined in the HTML file.
6144 */
6145 List<PolymerTagHtmlElement> _polymerTags = PolymerTagHtmlElement.EMPTY_ARRAY;
6146
6147 /**
6148 * The source that corresponds to this HTML file.
6149 */
6150 Source source;
6151
6152 /**
6153 * The element associated with Dart pieces in this HTML unit or `null` if the receiver is
6154 * not resolved.
6155 */
6156 CompilationUnitElement angularCompilationUnit;
6157
6158 /**
6159 * Initialize a newly created HTML element to have the given name.
6160 *
6161 * @param context the analysis context in which the HTML file is defined
6162 * @param name the name of this element
6163 */
6164 HtmlElementImpl(this.context, String name) : super(name, -1);
6165
6166 @override
6167 accept(ElementVisitor visitor) => visitor.visitHtmlElement(this);
6168
6169 @override
6170 bool operator ==(Object object) {
6171 if (identical(object, this)) {
6172 return true;
6173 }
6174 if (object == null) {
6175 return false;
6176 }
6177 return runtimeType == object.runtimeType && source == (object as HtmlElement Impl).source;
6178 }
6179
6180 @override
6181 ElementKind get kind => ElementKind.HTML;
6182
6183 @override
6184 List<PolymerTagHtmlElement> get polymerTags => _polymerTags;
6185
6186 @override
6187 List<HtmlScriptElement> get scripts => _scripts;
6188
6189 @override
6190 int get hashCode => source.hashCode;
6191
6192 /**
6193 * Set the [PolymerTagHtmlElement]s defined in the HTML file.
6194 */
6195 void set polymerTags(List<PolymerTagHtmlElement> polymerTags) {
6196 if (polymerTags.length == 0) {
6197 this._polymerTags = PolymerTagHtmlElement.EMPTY_ARRAY;
6198 return;
6199 }
6200 for (PolymerTagHtmlElement tag in polymerTags) {
6201 (tag as PolymerTagHtmlElementImpl).enclosingElement = this;
6202 }
6203 this._polymerTags = polymerTags;
6204 }
6205
6206 /**
6207 * Set the scripts contained in the HTML file to the given scripts.
6208 *
6209 * @param scripts the scripts
6210 */
6211 void set scripts(List<HtmlScriptElement> scripts) {
6212 if (scripts.length == 0) {
6213 this._scripts = HtmlScriptElementImpl.EMPTY_ARRAY;
6214 return;
6215 }
6216 for (HtmlScriptElement script in scripts) {
6217 (script as HtmlScriptElementImpl).enclosingElement = this;
6218 }
6219 this._scripts = scripts;
6220 }
6221
6222 @override
6223 void visitChildren(ElementVisitor visitor) {
6224 super.visitChildren(visitor);
6225 safelyVisitChildren(_scripts, visitor);
6226 safelyVisitChildren(_polymerTags, visitor);
6227 }
6228
6229 @override
6230 void appendTo(JavaStringBuilder builder) {
6231 if (source == null) {
6232 builder.append("{HTML file}");
6233 } else {
6234 builder.append(source.fullName);
6235 }
6236 }
6237
6238 @override
6239 String get identifier => source.encoding;
6240 }
6241
6242 /**
6243 * The interface `HtmlScriptElement` defines the behavior of elements representi ng a script
6244 * tag in an HTML file.
6245 *
6246 * @see EmbeddedHtmlScriptElement
6247 * @see ExternalHtmlScriptElement
6248 */
6249 abstract class HtmlScriptElement implements Element {
6250 }
6251
6252 /**
6253 * Instances of the class `HtmlScriptElementImpl` implement an [HtmlScriptElemen t].
6254 */
6255 abstract class HtmlScriptElementImpl extends ElementImpl implements HtmlScriptEl ement {
6256 /**
6257 * An empty array of HTML script elements.
6258 */
6259 static List<HtmlScriptElement> EMPTY_ARRAY = new List<HtmlScriptElement>(0);
6260
6261 /**
6262 * Initialize a newly created script element to have the specified tag name an d offset.
6263 *
6264 * @param node the XML node from which this element is derived (not `null`)
6265 */
6266 HtmlScriptElementImpl(XmlTagNode node) : super(node.tag, node.tagToken.offset) ;
6267 }
6268
6269 /**
6270 * The interface `ImportElement` defines the behavior of objects representing in formation
6271 * about a single import directive within a library.
6272 */
6273 abstract class ImportElement implements Element, UriReferencedElement {
6274 /**
6275 * An empty array of import elements.
6276 */
6277 static final List<ImportElement> EMPTY_ARRAY = new List<ImportElement>(0);
6278
6279 /**
6280 * Return an array containing the combinators that were specified as part of t he import directive
6281 * in the order in which they were specified.
6282 *
6283 * @return the combinators specified in the import directive
6284 */
6285 List<NamespaceCombinator> get combinators;
6286
6287 /**
6288 * Return the library that is imported into this library by this import direct ive.
6289 *
6290 * @return the library that is imported into this library
6291 */
6292 LibraryElement get importedLibrary;
6293
6294 /**
6295 * Return the prefix that was specified as part of the import directive, or `n ull` if there
6296 * was no prefix specified.
6297 *
6298 * @return the prefix that was specified as part of the import directive
6299 */
6300 PrefixElement get prefix;
6301
6302 /**
6303 * Return the offset of the prefix of this import in the file that contains th is import directive,
6304 * or `-1` if this import is synthetic, does not have a prefix, or otherwise d oes not have
6305 * an offset.
6306 *
6307 * @return the offset of the prefix of this import
6308 */
6309 int get prefixOffset;
6310
6311 /**
6312 * Return `true` if this import is for a deferred library.
6313 *
6314 * @return `true` if this import is for a deferred library
6315 */
6316 bool get isDeferred;
6317 }
6318
6319 /**
6320 * Instances of the class `ImportElementImpl` implement an [ImportElement].
6321 */
6322 class ImportElementImpl extends UriReferencedElementImpl implements ImportElemen t {
6323 /**
6324 * The offset of the prefix of this import in the file that contains the this import directive, or
6325 * `-1` if this import is synthetic.
6326 */
6327 int prefixOffset = 0;
6328
6329 /**
6330 * The library that is imported into this library by this import directive.
6331 */
6332 LibraryElement importedLibrary;
6333
6334 /**
6335 * The combinators that were specified as part of the import directive in the order in which they
6336 * were specified.
6337 */
6338 List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_ARRAY;
6339
6340 /**
6341 * The prefix that was specified as part of the import directive, or `null` if there was no
6342 * prefix specified.
6343 */
6344 PrefixElement prefix;
6345
6346 /**
6347 * Initialize a newly created import element.
6348 *
6349 * @param offset the directive offset, may be `-1` if synthetic.
6350 */
6351 ImportElementImpl(int offset) : super(null, offset);
6352
6353 @override
6354 accept(ElementVisitor visitor) => visitor.visitImportElement(this);
6355
6356 @override
6357 ElementKind get kind => ElementKind.IMPORT;
6358
6359 @override
6360 bool get isDeferred => hasModifier(Modifier.DEFERRED);
6361
6362 /**
6363 * Set whether this import is for a deferred library to correspond to the give n value.
6364 *
6365 * @param isDeferred `true` if this import is for a deferred library
6366 */
6367 void set deferred(bool isDeferred) {
6368 setModifier(Modifier.DEFERRED, isDeferred);
6369 }
6370
6371 @override
6372 void visitChildren(ElementVisitor visitor) {
6373 super.visitChildren(visitor);
6374 safelyVisitChild(prefix, visitor);
6375 }
6376
6377 @override
6378 void appendTo(JavaStringBuilder builder) {
6379 builder.append("import ");
6380 (importedLibrary as LibraryElementImpl).appendTo(builder);
6381 }
6382
6383 @override
6384 String get identifier => "${(importedLibrary as LibraryElementImpl).identifier }@${nameOffset}";
6385 }
6386
6387 /**
6388 * The interface `InterfaceType` defines the behavior common to objects represen ting the type
6389 * introduced by either a class or an interface, or a reference to such a type.
6390 */
6391 abstract class InterfaceType implements ParameterizedType {
6392 /**
6393 * An empty array of types.
6394 */
6395 static final List<InterfaceType> EMPTY_ARRAY = new List<InterfaceType>(0);
6396
6397 /**
6398 * Return an array containing all of the accessors (getters and setters) decla red in this type.
6399 *
6400 * @return the accessors declared in this type
6401 */
6402 List<PropertyAccessorElement> get accessors;
6403
6404 @override
6405 ClassElement get element;
6406
6407 /**
6408 * Return the element representing the getter with the given name that is decl ared in this class,
6409 * or `null` if this class does not declare a getter with the given name.
6410 *
6411 * @param getterName the name of the getter to be returned
6412 * @return the getter declared in this class with the given name
6413 */
6414 PropertyAccessorElement getGetter(String getterName);
6415
6416 /**
6417 * Return an array containing all of the interfaces that are implemented by th is interface. Note
6418 * that this is <b>not</b>, in general, equivalent to getting the interfaces f rom this type's
6419 * element because the types returned by this method will have had their type parameters replaced.
6420 *
6421 * @return the interfaces that are implemented by this type
6422 */
6423 List<InterfaceType> get interfaces;
6424
6425 /**
6426 * Return the least upper bound of this type and the given type, or `null` if there is no
6427 * least upper bound.
6428 *
6429 * Given two interfaces <i>I</i> and <i>J</i>, let <i>S<sub>I</sub></i> be the set of
6430 * superinterfaces of <i>I<i>, let <i>S<sub>J</sub></i> be the set of superint erfaces of <i>J</i>
6431 * and let <i>S = (I &cup; S<sub>I</sub>) &cap; (J &cup; S<sub>J</sub>)</i>. F urthermore, we
6432 * define <i>S<sub>n</sub> = {T | T &isin; S &and; depth(T) = n}</i> for any f inite <i>n</i>,
6433 * where <i>depth(T)</i> is the number of steps in the longest inheritance pat h from <i>T</i> to
6434 * <i>Object</i>. Let <i>q</i> be the largest number such that <i>S<sub>q</sub ></i> has
6435 * cardinality one. The least upper bound of <i>I</i> and <i>J</i> is the sole element of
6436 * <i>S<sub>q</sub></i>.
6437 *
6438 * @param type the other type used to compute the least upper bound
6439 * @return the least upper bound of this type and the given type
6440 */
6441 @override
6442 DartType getLeastUpperBound(DartType type);
6443
6444 /**
6445 * Return the element representing the method with the given name that is decl ared in this class,
6446 * or `null` if this class does not declare a method with the given name.
6447 *
6448 * @param methodName the name of the method to be returned
6449 * @return the method declared in this class with the given name
6450 */
6451 MethodElement getMethod(String methodName);
6452
6453 /**
6454 * Return an array containing all of the methods declared in this type.
6455 *
6456 * @return the methods declared in this type
6457 */
6458 List<MethodElement> get methods;
6459
6460 /**
6461 * Return an array containing all of the mixins that are applied to the class being extended in
6462 * order to derive the superclass of this class. Note that this is <b>not</b>, in general,
6463 * equivalent to getting the mixins from this type's element because the types returned by this
6464 * method will have had their type parameters replaced.
6465 *
6466 * @return the mixins that are applied to derive the superclass of this class
6467 */
6468 List<InterfaceType> get mixins;
6469
6470 /**
6471 * Return the element representing the setter with the given name that is decl ared in this class,
6472 * or `null` if this class does not declare a setter with the given name.
6473 *
6474 * @param setterName the name of the setter to be returned
6475 * @return the setter declared in this class with the given name
6476 */
6477 PropertyAccessorElement getSetter(String setterName);
6478
6479 /**
6480 * Return the type representing the superclass of this type, or null if this t ype represents the
6481 * class 'Object'. Note that this is <b>not</b>, in general, equivalent to get ting the superclass
6482 * from this type's element because the type returned by this method will have had it's type
6483 * parameters replaced.
6484 *
6485 * @return the superclass of this type
6486 */
6487 InterfaceType get superclass;
6488
6489 /**
6490 * Return `true` if this type is a direct supertype of the given type. The imp licit
6491 * interface of class <i>I</i> is a direct supertype of the implicit interface of class <i>J</i>
6492 * iff:
6493 * * <i>I</i> is Object, and <i>J</i> has no extends clause.
6494 * * <i>I</i> is listed in the extends clause of <i>J</i>.
6495 * * <i>I</i> is listed in the implements clause of <i>J</i>.
6496 * * <i>I</i> is listed in the with clause of <i>J</i>.
6497 * * <i>J</i> is a mixin application of the mixin of <i>I</i>.
6498 *
6499 * @param type the type being compared with this type
6500 * @return `true` if this type is a direct supertype of the given type
6501 */
6502 bool isDirectSupertypeOf(InterfaceType type);
6503
6504 /**
6505 * Return `true` if this type is more specific than the given type. An interfa ce type
6506 * <i>T</i> is more specific than an interface type <i>S</i>, written <i>T &la quo; S</i>, if one
6507 * of the following conditions is met:
6508 * * Reflexivity: <i>T</i> is <i>S</i>.
6509 * * <i>T</i> is bottom.
6510 * * <i>S</i> is dynamic.
6511 * * Direct supertype: <i>S</i> is a direct supertype of <i>T</i>.
6512 * * <i>T</i> is a type parameter and <i>S</i> is the upper bound of <i>T</i>.
6513 * * Covariance: <i>T</i> is of the form <i>I&lt;T<sub>1</sub>, &hellip;, T<su b>n</sub>&gt;</i>
6514 * and S</i> is of the form <i>I&lt;S<sub>1</sub>, &hellip;, S<sub>n</sub>&gt; </i> and
6515 * <i>T<sub>i</sub> &laquo; S<sub>i</sub></i>, <i>1 <= i <= n</i>.
6516 * * Transitivity: <i>T &laquo; U</i> and <i>U &laquo; S</i>.
6517 *
6518 * @param type the type being compared with this type
6519 * @return `true` if this type is more specific than the given type
6520 */
6521 @override
6522 bool isMoreSpecificThan(DartType type);
6523
6524 /**
6525 * Return `true` if this type is a subtype of the given type. An interface typ e <i>T</i> is
6526 * a subtype of an interface type <i>S</i>, written <i>T</i> <: <i>S</i>, iff
6527 * <i>[bottom/dynamic]T</i> &laquo; <i>S</i> (<i>T</i> is more specific than < i>S</i>). If an
6528 * interface type <i>I</i> includes a method named <i>call()</i>, and the type of <i>call()</i> is
6529 * the function type <i>F</i>, then <i>I</i> is considered to be a subtype of <i>F</i>.
6530 *
6531 * @param type the type being compared with this type
6532 * @return `true` if this type is a subtype of the given type
6533 */
6534 @override
6535 bool isSubtypeOf(DartType type);
6536
6537 /**
6538 * Return the element representing the constructor that results from looking u p the given
6539 * constructor in this class with respect to the given library, or `null` if t he look up
6540 * fails. The behavior of this method is defined by the Dart Language Specific ation in section
6541 * 12.11.1: <blockquote>If <i>e</i> is of the form <b>new</b> <i>T.id()</i> th en let <i>q<i> be
6542 * the constructor <i>T.id</i>, otherwise let <i>q<i> be the constructor <i>T< i>. Otherwise, if
6543 * <i>q</i> is not defined or not accessible, a NoSuchMethodException is throw n. </blockquote>
6544 *
6545 * @param constructorName the name of the constructor being looked up
6546 * @param library the library with respect to which the lookup is being perfor med
6547 * @return the result of looking up the given constructor in this class with r espect to the given
6548 * library
6549 */
6550 ConstructorElement lookUpConstructor(String constructorName, LibraryElement li brary);
6551
6552 /**
6553 * Return the element representing the getter that results from looking up the given getter in
6554 * this class with respect to the given library, or `null` if the look up fail s. The
6555 * behavior of this method is defined by the Dart Language Specification in se ction 12.15.1:
6556 * <blockquote>The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
6557 * with respect to library <i>L</i> is:
6558 * * If <i>C</i> declares an instance getter (respectively setter) named <i>m< /i> that is
6559 * accessible to <i>L</i>, then that getter (respectively setter) is the resul t of the lookup.
6560 * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lo okup is the result
6561 * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respec t to <i>L</i>.
6562 * Otherwise, we say that the lookup has failed.
6563 * </blockquote>
6564 *
6565 * @param getterName the name of the getter being looked up
6566 * @param library the library with respect to which the lookup is being perfor med
6567 * @return the result of looking up the given getter in this class with respec t to the given
6568 * library
6569 */
6570 PropertyAccessorElement lookUpGetter(String getterName, LibraryElement library );
6571
6572 /**
6573 * Return the element representing the getter that results from looking up the given getter in the
6574 * superclass of this class with respect to the given library, or `null` if th e look up
6575 * fails. The behavior of this method is defined by the Dart Language Specific ation in section
6576 * 12.15.1: <blockquote>The result of looking up getter (respectively setter) <i>m</i> in class
6577 * <i>C</i> with respect to library <i>L</i> is:
6578 * * If <i>C</i> declares an instance getter (respectively setter) named <i>m< /i> that is
6579 * accessible to <i>L</i>, then that getter (respectively setter) is the resul t of the lookup.
6580 * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lo okup is the result
6581 * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respec t to <i>L</i>.
6582 * Otherwise, we say that the lookup has failed.
6583 * </blockquote>
6584 *
6585 * @param getterName the name of the getter being looked up
6586 * @param library the library with respect to which the lookup is being perfor med
6587 * @return the result of looking up the given getter in this class with respec t to the given
6588 * library
6589 */
6590 PropertyAccessorElement lookUpGetterInSuperclass(String getterName, LibraryEle ment library);
6591
6592 /**
6593 * Return the element representing the method that results from looking up the given method in
6594 * this class with respect to the given library, or `null` if the look up fail s. The
6595 * behavior of this method is defined by the Dart Language Specification in se ction 12.15.1:
6596 * <blockquote> The result of looking up method <i>m</i> in class <i>C</i> wit h respect to library
6597 * <i>L</i> is:
6598 * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
6599 * that method is the result of the lookup. Otherwise, if <i>C</i> has a super class <i>S</i>, then
6600 * the result of the lookup is the result of looking up method <i>m</i> in <i> S</i> with respect
6601 * to <i>L</i>. Otherwise, we say that the lookup has failed.
6602 * </blockquote>
6603 *
6604 * @param methodName the name of the method being looked up
6605 * @param library the library with respect to which the lookup is being perfor med
6606 * @return the result of looking up the given method in this class with respec t to the given
6607 * library
6608 */
6609 MethodElement lookUpMethod(String methodName, LibraryElement library);
6610
6611 /**
6612 * Return the element representing the method that results from looking up the given method in the
6613 * superclass of this class with respect to the given library, or `null` if th e look up
6614 * fails. The behavior of this method is defined by the Dart Language Specific ation in section
6615 * 12.15.1: <blockquote> The result of looking up method <i>m</i> in class <i> C</i> with respect
6616 * to library <i>L</i> is:
6617 * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
6618 * that method is the result of the lookup. Otherwise, if <i>C</i> has a super class <i>S</i>, then
6619 * the result of the lookup is the result of looking up method <i>m</i> in <i> S</i> with respect
6620 * to <i>L</i>. Otherwise, we say that the lookup has failed.
6621 * </blockquote>
6622 *
6623 * @param methodName the name of the method being looked up
6624 * @param library the library with respect to which the lookup is being perfor med
6625 * @return the result of looking up the given method in this class with respec t to the given
6626 * library
6627 */
6628 MethodElement lookUpMethodInSuperclass(String methodName, LibraryElement libra ry);
6629
6630 /**
6631 * Return the element representing the setter that results from looking up the given setter in
6632 * this class with respect to the given library, or `null` if the look up fail s. The
6633 * behavior of this method is defined by the Dart Language Specification in se ction 12.16:
6634 * <blockquote> The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
6635 * with respect to library <i>L</i> is:
6636 * * If <i>C</i> declares an instance getter (respectively setter) named <i>m< /i> that is
6637 * accessible to <i>L</i>, then that getter (respectively setter) is the resul t of the lookup.
6638 * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lo okup is the result
6639 * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respec t to <i>L</i>.
6640 * Otherwise, we say that the lookup has failed.
6641 * </blockquote>
6642 *
6643 * @param setterName the name of the setter being looked up
6644 * @param library the library with respect to which the lookup is being perfor med
6645 * @return the result of looking up the given setter in this class with respec t to the given
6646 * library
6647 */
6648 PropertyAccessorElement lookUpSetter(String setterName, LibraryElement library );
6649
6650 /**
6651 * Return the element representing the setter that results from looking up the given setter in the
6652 * superclass of this class with respect to the given library, or `null` if th e look up
6653 * fails. The behavior of this method is defined by the Dart Language Specific ation in section
6654 * 12.16: <blockquote> The result of looking up getter (respectively setter) < i>m</i> in class
6655 * <i>C</i> with respect to library <i>L</i> is:
6656 * * If <i>C</i> declares an instance getter (respectively setter) named <i>m< /i> that is
6657 * accessible to <i>L</i>, then that getter (respectively setter) is the resul t of the lookup.
6658 * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lo okup is the result
6659 * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respec t to <i>L</i>.
6660 * Otherwise, we say that the lookup has failed.
6661 * </blockquote>
6662 *
6663 * @param setterName the name of the setter being looked up
6664 * @param library the library with respect to which the lookup is being perfor med
6665 * @return the result of looking up the given setter in this class with respec t to the given
6666 * library
6667 */
6668 PropertyAccessorElement lookUpSetterInSuperclass(String setterName, LibraryEle ment library);
6669
6670 /**
6671 * Return the type resulting from substituting the given arguments for this ty pe's parameters.
6672 * This is fully equivalent to `substitute(argumentTypes, getTypeArguments())` .
6673 *
6674 * @param argumentTypes the actual type arguments being substituted for the ty pe parameters
6675 * @return the result of performing the substitution
6676 */
6677 InterfaceType substitute4(List<DartType> argumentTypes);
6678
6679 @override
6680 InterfaceType substitute2(List<DartType> argumentTypes, List<DartType> paramet erTypes);
6681 }
6682
6683 /**
6684 * Instances of the class `InterfaceTypeImpl` defines the behavior common to obj ects
6685 * representing the type introduced by either a class or an interface, or a refe rence to such a
6686 * type.
6687 */
6688 class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
6689 /**
6690 * This method computes the longest inheritance path from some passed [Type] t o Object.
6691 *
6692 * @param type the [Type] to compute the longest inheritance path of from the passed
6693 * [Type] to Object
6694 * @return the computed longest inheritance path to Object
6695 * @see InterfaceType#getLeastUpperBound(Type)
6696 */
6697 static int computeLongestInheritancePathToObject(InterfaceType type) => _compu teLongestInheritancePathToObject(type, 0, new HashSet<ClassElement>());
6698
6699 /**
6700 * Returns the set of all superinterfaces of the passed [Type].
6701 *
6702 * @param type the [Type] to compute the set of superinterfaces of
6703 * @return the [Set] of superinterfaces of the passed [Type]
6704 * @see #getLeastUpperBound(Type)
6705 */
6706 static Set<InterfaceType> computeSuperinterfaceSet(InterfaceType type) => _com puteSuperinterfaceSet(type, new HashSet<InterfaceType>());
6707
6708 /**
6709 * This method computes the longest inheritance path from some passed [Type] t o Object. This
6710 * method calls itself recursively, callers should use the public method
6711 * [computeLongestInheritancePathToObject].
6712 *
6713 * @param type the [Type] to compute the longest inheritance path of from the passed
6714 * [Type] to Object
6715 * @param depth a field used recursively
6716 * @param visitedClasses the classes that have already been visited
6717 * @return the computed longest inheritance path to Object
6718 * @see #computeLongestInheritancePathToObject(Type)
6719 * @see #getLeastUpperBound(Type)
6720 */
6721 static int _computeLongestInheritancePathToObject(InterfaceType type, int dept h, HashSet<ClassElement> visitedClasses) {
6722 ClassElement classElement = type.element;
6723 // Object case
6724 if (classElement.supertype == null || visitedClasses.contains(classElement)) {
6725 return depth;
6726 }
6727 int longestPath = 1;
6728 try {
6729 visitedClasses.add(classElement);
6730 List<InterfaceType> superinterfaces = classElement.interfaces;
6731 int pathLength;
6732 if (superinterfaces.length > 0) {
6733 // loop through each of the superinterfaces recursively calling this met hod and keeping track
6734 // of the longest path to return
6735 for (InterfaceType superinterface in superinterfaces) {
6736 pathLength = _computeLongestInheritancePathToObject(superinterface, de pth + 1, visitedClasses);
6737 if (pathLength > longestPath) {
6738 longestPath = pathLength;
6739 }
6740 }
6741 }
6742 // finally, perform this same check on the super type
6743 // TODO(brianwilkerson) Does this also need to add in the number of mixin classes?
6744 InterfaceType supertype = classElement.supertype;
6745 pathLength = _computeLongestInheritancePathToObject(supertype, depth + 1, visitedClasses);
6746 if (pathLength > longestPath) {
6747 longestPath = pathLength;
6748 }
6749 } finally {
6750 visitedClasses.remove(classElement);
6751 }
6752 return longestPath;
6753 }
6754
6755 /**
6756 * Returns the set of all superinterfaces of the passed [Type]. This is a recu rsive method,
6757 * callers should call the public [computeSuperinterfaceSet].
6758 *
6759 * @param type the [Type] to compute the set of superinterfaces of
6760 * @param set a [HashSet] used recursively by this method
6761 * @return the [Set] of superinterfaces of the passed [Type]
6762 * @see #computeSuperinterfaceSet(Type)
6763 * @see #getLeastUpperBound(Type)
6764 */
6765 static Set<InterfaceType> _computeSuperinterfaceSet(InterfaceType type, HashSe t<InterfaceType> set) {
6766 Element element = type.element;
6767 if (element != null) {
6768 List<InterfaceType> superinterfaces = type.interfaces;
6769 for (InterfaceType superinterface in superinterfaces) {
6770 if (set.add(superinterface)) {
6771 _computeSuperinterfaceSet(superinterface, set);
6772 }
6773 }
6774 InterfaceType supertype = type.superclass;
6775 if (supertype != null) {
6776 if (set.add(supertype)) {
6777 _computeSuperinterfaceSet(supertype, set);
6778 }
6779 }
6780 }
6781 return set;
6782 }
6783
6784 /**
6785 * Return the intersection of the given sets of types, where intersection is b ased on the equality
6786 * of the types themselves.
6787 *
6788 * @param first the first set of types to be intersected
6789 * @param second the second set of types to be intersected
6790 * @return the intersection of the given sets of types
6791 */
6792 static List<InterfaceType> _intersection(Set<InterfaceType> first, Set<Interfa ceType> second) {
6793 Set<InterfaceType> result = new HashSet<InterfaceType>.from(first);
6794 result.retainAll(second);
6795 return new List.from(result);
6796 }
6797
6798 /**
6799 * Return the "least upper bound" of the given types under the assumption that the types have the
6800 * same element and differ only in terms of the type arguments. The resulting type is composed by
6801 * comparing the corresponding type arguments, keeping those that are the same , and using
6802 * 'dynamic' for those that are different.
6803 *
6804 * @param firstType the first type
6805 * @param secondType the second type
6806 * @return the "least upper bound" of the given types
6807 */
6808 static InterfaceType _leastUpperBound(InterfaceType firstType, InterfaceType s econdType) {
6809 if (firstType == secondType) {
6810 return firstType;
6811 }
6812 List<DartType> firstArguments = firstType.typeArguments;
6813 List<DartType> secondArguments = secondType.typeArguments;
6814 int argumentCount = firstArguments.length;
6815 if (argumentCount == 0) {
6816 return firstType;
6817 }
6818 List<DartType> lubArguments = new List<DartType>(argumentCount);
6819 for (int i = 0; i < argumentCount; i++) {
6820 //
6821 // Ideally we would take the least upper bound of the two argument types, but this can cause
6822 // an infinite recursion (such as when finding the least upper bound of St ring and num).
6823 //
6824 if (firstArguments[i] == secondArguments[i]) {
6825 lubArguments[i] = firstArguments[i];
6826 }
6827 if (lubArguments[i] == null) {
6828 lubArguments[i] = DynamicTypeImpl.instance;
6829 }
6830 }
6831 InterfaceTypeImpl lub = new InterfaceTypeImpl.con1(firstType.element);
6832 lub.typeArguments = lubArguments;
6833 return lub;
6834 }
6835
6836 /**
6837 * An array containing the actual types of the type arguments.
6838 */
6839 List<DartType> typeArguments = TypeImpl.EMPTY_ARRAY;
6840
6841 /**
6842 * Initialize a newly created type to be declared by the given element.
6843 *
6844 * @param element the element representing the declaration of the type
6845 */
6846 InterfaceTypeImpl.con1(ClassElement element) : super(element, element.displayN ame);
6847
6848 /**
6849 * Initialize a newly created type to have the given name. This constructor sh ould only be used in
6850 * cases where there is no declaration of the type.
6851 *
6852 * @param name the name of the type
6853 */
6854 InterfaceTypeImpl.con2(String name) : super(null, name);
6855
6856 @override
6857 bool operator ==(Object object) => internalEquals(object, new HashSet<ElementP air>());
6858
6859 @override
6860 List<PropertyAccessorElement> get accessors {
6861 List<PropertyAccessorElement> accessors = element.accessors;
6862 List<PropertyAccessorElement> members = new List<PropertyAccessorElement>(ac cessors.length);
6863 for (int i = 0; i < accessors.length; i++) {
6864 members[i] = PropertyAccessorMember.from(accessors[i], this);
6865 }
6866 return members;
6867 }
6868
6869 @override
6870 String get displayName {
6871 String name = this.name;
6872 List<DartType> typeArguments = this.typeArguments;
6873 bool allDynamic = true;
6874 for (DartType type in typeArguments) {
6875 if (type != null && !type.isDynamic) {
6876 allDynamic = false;
6877 break;
6878 }
6879 }
6880 // If there is at least one non-dynamic type, then list them out
6881 if (!allDynamic) {
6882 JavaStringBuilder builder = new JavaStringBuilder();
6883 builder.append(name);
6884 builder.append("<");
6885 for (int i = 0; i < typeArguments.length; i++) {
6886 if (i != 0) {
6887 builder.append(", ");
6888 }
6889 DartType typeArg = typeArguments[i];
6890 builder.append(typeArg.displayName);
6891 }
6892 builder.append(">");
6893 name = builder.toString();
6894 }
6895 return name;
6896 }
6897
6898 @override
6899 ClassElement get element => super.element as ClassElement;
6900
6901 @override
6902 PropertyAccessorElement getGetter(String getterName) => PropertyAccessorMember .from((element as ClassElementImpl).getGetter(getterName), this);
6903
6904 @override
6905 List<InterfaceType> get interfaces {
6906 ClassElement classElement = element;
6907 List<InterfaceType> interfaces = classElement.interfaces;
6908 List<TypeParameterElement> typeParameters = classElement.typeParameters;
6909 List<DartType> parameterTypes = classElement.type.typeArguments;
6910 if (typeParameters.length == 0) {
6911 return interfaces;
6912 }
6913 int count = interfaces.length;
6914 List<InterfaceType> typedInterfaces = new List<InterfaceType>(count);
6915 for (int i = 0; i < count; i++) {
6916 typedInterfaces[i] = interfaces[i].substitute2(typeArguments, parameterTyp es);
6917 }
6918 return typedInterfaces;
6919 }
6920
6921 @override
6922 DartType getLeastUpperBound(DartType type) {
6923 // quick check for self
6924 if (identical(type, this)) {
6925 return this;
6926 }
6927 // dynamic
6928 DartType dynamicType = DynamicTypeImpl.instance;
6929 if (identical(this, dynamicType) || identical(type, dynamicType)) {
6930 return dynamicType;
6931 }
6932 // TODO (jwren) opportunity here for a better, faster algorithm if this turn s out to be a bottle-neck
6933 if (type is! InterfaceType) {
6934 return null;
6935 }
6936 // new names to match up with the spec
6937 InterfaceType i = this;
6938 InterfaceType j = type as InterfaceType;
6939 // compute set of supertypes
6940 Set<InterfaceType> si = computeSuperinterfaceSet(i);
6941 Set<InterfaceType> sj = computeSuperinterfaceSet(j);
6942 // union si with i and sj with j
6943 si.add(i);
6944 sj.add(j);
6945 // compute intersection, reference as set 's'
6946 List<InterfaceType> s = _intersection(si, sj);
6947 // for each element in Set s, compute the largest inheritance path to Object
6948 List<int> depths = new List<int>.filled(s.length, 0);
6949 int maxDepth = 0;
6950 for (int n = 0; n < s.length; n++) {
6951 depths[n] = computeLongestInheritancePathToObject(s[n]);
6952 if (depths[n] > maxDepth) {
6953 maxDepth = depths[n];
6954 }
6955 }
6956 // ensure that the currently computed maxDepth is unique,
6957 // otherwise, decrement and test for uniqueness again
6958 for (; maxDepth >= 0; maxDepth--) {
6959 int indexOfLeastUpperBound = -1;
6960 int numberOfTypesAtMaxDepth = 0;
6961 for (int m = 0; m < depths.length; m++) {
6962 if (depths[m] == maxDepth) {
6963 numberOfTypesAtMaxDepth++;
6964 indexOfLeastUpperBound = m;
6965 }
6966 }
6967 if (numberOfTypesAtMaxDepth == 1) {
6968 return s[indexOfLeastUpperBound];
6969 }
6970 }
6971 // illegal state, log and return null- Object at maxDepth == 0 should always return itself as
6972 // the least upper bound.
6973 // TODO (jwren) log the error state
6974 return null;
6975 }
6976
6977 @override
6978 MethodElement getMethod(String methodName) => MethodMember.from((element as Cl assElementImpl).getMethod(methodName), this);
6979
6980 @override
6981 List<MethodElement> get methods {
6982 List<MethodElement> methods = element.methods;
6983 List<MethodElement> members = new List<MethodElement>(methods.length);
6984 for (int i = 0; i < methods.length; i++) {
6985 members[i] = MethodMember.from(methods[i], this);
6986 }
6987 return members;
6988 }
6989
6990 @override
6991 List<InterfaceType> get mixins {
6992 ClassElement classElement = element;
6993 List<InterfaceType> mixins = classElement.mixins;
6994 List<TypeParameterElement> typeParameters = classElement.typeParameters;
6995 List<DartType> parameterTypes = classElement.type.typeArguments;
6996 if (typeParameters.length == 0) {
6997 return mixins;
6998 }
6999 int count = mixins.length;
7000 List<InterfaceType> typedMixins = new List<InterfaceType>(count);
7001 for (int i = 0; i < count; i++) {
7002 typedMixins[i] = mixins[i].substitute2(typeArguments, parameterTypes);
7003 }
7004 return typedMixins;
7005 }
7006
7007 @override
7008 PropertyAccessorElement getSetter(String setterName) => PropertyAccessorMember .from((element as ClassElementImpl).getSetter(setterName), this);
7009
7010 @override
7011 InterfaceType get superclass {
7012 ClassElement classElement = element;
7013 InterfaceType supertype = classElement.supertype;
7014 if (supertype == null) {
7015 return null;
7016 }
7017 List<DartType> typeParameters = classElement.type.typeArguments;
7018 if (typeArguments.length == 0 || typeArguments.length != typeParameters.leng th) {
7019 return supertype;
7020 }
7021 return supertype.substitute2(typeArguments, typeParameters);
7022 }
7023
7024 @override
7025 List<TypeParameterElement> get typeParameters => element.typeParameters;
7026
7027 @override
7028 int get hashCode {
7029 ClassElement element = this.element;
7030 if (element == null) {
7031 return 0;
7032 }
7033 return element.hashCode;
7034 }
7035
7036 @override
7037 bool get isDartCoreFunction {
7038 ClassElement element = this.element;
7039 if (element == null) {
7040 return false;
7041 }
7042 return element.name == "Function" && element.library.isDartCore;
7043 }
7044
7045 @override
7046 bool isDirectSupertypeOf(InterfaceType type) {
7047 InterfaceType i = this;
7048 InterfaceType j = type;
7049 ClassElement jElement = j.element;
7050 InterfaceType supertype = jElement.supertype;
7051 //
7052 // If J has no direct supertype then it is Object, and Object has no direct supertypes.
7053 //
7054 if (supertype == null) {
7055 return false;
7056 }
7057 //
7058 // I is listed in the extends clause of J.
7059 //
7060 List<DartType> jArgs = j.typeArguments;
7061 List<DartType> jVars = jElement.type.typeArguments;
7062 supertype = supertype.substitute2(jArgs, jVars);
7063 if (supertype == i) {
7064 return true;
7065 }
7066 //
7067 // I is listed in the implements clause of J.
7068 //
7069 for (InterfaceType interfaceType in jElement.interfaces) {
7070 interfaceType = interfaceType.substitute2(jArgs, jVars);
7071 if (interfaceType == i) {
7072 return true;
7073 }
7074 }
7075 //
7076 // I is listed in the with clause of J.
7077 //
7078 for (InterfaceType mixinType in jElement.mixins) {
7079 mixinType = mixinType.substitute2(jArgs, jVars);
7080 if (mixinType == i) {
7081 return true;
7082 }
7083 }
7084 //
7085 // J is a mixin application of the mixin of I.
7086 //
7087 // TODO(brianwilkerson) Determine whether this needs to be implemented or wh ether it is covered
7088 // by the case above.
7089 return false;
7090 }
7091
7092 @override
7093 bool get isObject => element.supertype == null;
7094
7095 @override
7096 ConstructorElement lookUpConstructor(String constructorName, LibraryElement li brary) {
7097 // prepare base ConstructorElement
7098 ConstructorElement constructorElement;
7099 if (constructorName == null) {
7100 constructorElement = element.unnamedConstructor;
7101 } else {
7102 constructorElement = element.getNamedConstructor(constructorName);
7103 }
7104 // not found or not accessible
7105 if (constructorElement == null || !constructorElement.isAccessibleIn(library )) {
7106 return null;
7107 }
7108 // return member
7109 return ConstructorMember.from(constructorElement, this);
7110 }
7111
7112 @override
7113 PropertyAccessorElement lookUpGetter(String getterName, LibraryElement library ) {
7114 PropertyAccessorElement element = getGetter(getterName);
7115 if (element != null && element.isAccessibleIn(library)) {
7116 return element;
7117 }
7118 return lookUpGetterInSuperclass(getterName, library);
7119 }
7120
7121 @override
7122 PropertyAccessorElement lookUpGetterInSuperclass(String getterName, LibraryEle ment library) {
7123 for (InterfaceType mixin in mixins) {
7124 PropertyAccessorElement element = mixin.getGetter(getterName);
7125 if (element != null && element.isAccessibleIn(library)) {
7126 return element;
7127 }
7128 }
7129 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
7130 InterfaceType supertype = superclass;
7131 ClassElement supertypeElement = supertype == null ? null : supertype.element ;
7132 while (supertype != null && !visitedClasses.contains(supertypeElement)) {
7133 visitedClasses.add(supertypeElement);
7134 PropertyAccessorElement element = supertype.getGetter(getterName);
7135 if (element != null && element.isAccessibleIn(library)) {
7136 return element;
7137 }
7138 for (InterfaceType mixin in supertype.mixins) {
7139 element = mixin.getGetter(getterName);
7140 if (element != null && element.isAccessibleIn(library)) {
7141 return element;
7142 }
7143 }
7144 supertype = supertype.superclass;
7145 supertypeElement = supertype == null ? null : supertype.element;
7146 }
7147 return null;
7148 }
7149
7150 @override
7151 MethodElement lookUpMethod(String methodName, LibraryElement library) {
7152 MethodElement element = getMethod(methodName);
7153 if (element != null && element.isAccessibleIn(library)) {
7154 return element;
7155 }
7156 return lookUpMethodInSuperclass(methodName, library);
7157 }
7158
7159 @override
7160 MethodElement lookUpMethodInSuperclass(String methodName, LibraryElement libra ry) {
7161 for (InterfaceType mixin in mixins) {
7162 MethodElement element = mixin.getMethod(methodName);
7163 if (element != null && element.isAccessibleIn(library)) {
7164 return element;
7165 }
7166 }
7167 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
7168 InterfaceType supertype = superclass;
7169 ClassElement supertypeElement = supertype == null ? null : supertype.element ;
7170 while (supertype != null && !visitedClasses.contains(supertypeElement)) {
7171 visitedClasses.add(supertypeElement);
7172 MethodElement element = supertype.getMethod(methodName);
7173 if (element != null && element.isAccessibleIn(library)) {
7174 return element;
7175 }
7176 for (InterfaceType mixin in supertype.mixins) {
7177 element = mixin.getMethod(methodName);
7178 if (element != null && element.isAccessibleIn(library)) {
7179 return element;
7180 }
7181 }
7182 supertype = supertype.superclass;
7183 supertypeElement = supertype == null ? null : supertype.element;
7184 }
7185 return null;
7186 }
7187
7188 @override
7189 PropertyAccessorElement lookUpSetter(String setterName, LibraryElement library ) {
7190 PropertyAccessorElement element = getSetter(setterName);
7191 if (element != null && element.isAccessibleIn(library)) {
7192 return element;
7193 }
7194 return lookUpSetterInSuperclass(setterName, library);
7195 }
7196
7197 @override
7198 PropertyAccessorElement lookUpSetterInSuperclass(String setterName, LibraryEle ment library) {
7199 for (InterfaceType mixin in mixins) {
7200 PropertyAccessorElement element = mixin.getSetter(setterName);
7201 if (element != null && element.isAccessibleIn(library)) {
7202 return element;
7203 }
7204 }
7205 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
7206 InterfaceType supertype = superclass;
7207 ClassElement supertypeElement = supertype == null ? null : supertype.element ;
7208 while (supertype != null && !visitedClasses.contains(supertypeElement)) {
7209 visitedClasses.add(supertypeElement);
7210 PropertyAccessorElement element = supertype.getSetter(setterName);
7211 if (element != null && element.isAccessibleIn(library)) {
7212 return element;
7213 }
7214 for (InterfaceType mixin in supertype.mixins) {
7215 element = mixin.getSetter(setterName);
7216 if (element != null && element.isAccessibleIn(library)) {
7217 return element;
7218 }
7219 }
7220 supertype = supertype.superclass;
7221 supertypeElement = supertype == null ? null : supertype.element;
7222 }
7223 return null;
7224 }
7225
7226 @override
7227 InterfaceTypeImpl substitute4(List<DartType> argumentTypes) => substitute2(arg umentTypes, typeArguments);
7228
7229 @override
7230 InterfaceTypeImpl substitute2(List<DartType> argumentTypes, List<DartType> par ameterTypes) {
7231 if (argumentTypes.length != parameterTypes.length) {
7232 throw new IllegalArgumentException("argumentTypes.length (${argumentTypes. length}) != parameterTypes.length (${parameterTypes.length})");
7233 }
7234 if (argumentTypes.length == 0 || typeArguments.length == 0) {
7235 return this;
7236 }
7237 List<DartType> newTypeArguments = TypeImpl.substitute(typeArguments, argumen tTypes, parameterTypes);
7238 if (JavaArrays.equals(newTypeArguments, typeArguments)) {
7239 return this;
7240 }
7241 InterfaceTypeImpl newType = new InterfaceTypeImpl.con1(element);
7242 newType.typeArguments = newTypeArguments;
7243 return newType;
7244 }
7245
7246 @override
7247 void appendTo(JavaStringBuilder builder) {
7248 builder.append(name);
7249 int argumentCount = typeArguments.length;
7250 if (argumentCount > 0) {
7251 builder.append("<");
7252 for (int i = 0; i < argumentCount; i++) {
7253 if (i > 0) {
7254 builder.append(", ");
7255 }
7256 (typeArguments[i] as TypeImpl).appendTo(builder);
7257 }
7258 builder.append(">");
7259 }
7260 }
7261
7262 @override
7263 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) {
7264 if (object is! InterfaceTypeImpl) {
7265 return false;
7266 }
7267 InterfaceTypeImpl otherType = object as InterfaceTypeImpl;
7268 return (element == otherType.element) && TypeImpl.equalArrays(typeArguments, otherType.typeArguments, visitedElementPairs);
7269 }
7270
7271 @override
7272 bool internalIsMoreSpecificThan(DartType type, bool withDynamic, Set<TypeImpl_ TypePair> visitedTypePairs) {
7273 //
7274 // S is dynamic.
7275 // The test to determine whether S is dynamic is done here because dynamic i s not an instance of
7276 // InterfaceType.
7277 //
7278 if (identical(type, DynamicTypeImpl.instance)) {
7279 return true;
7280 } else if (type is UnionType) {
7281 return (type as UnionTypeImpl).internalUnionTypeIsMoreSpecificThan(this, w ithDynamic, visitedTypePairs);
7282 } else if (type is! InterfaceType) {
7283 return false;
7284 }
7285 return _isMoreSpecificThan(type as InterfaceType, new HashSet<ClassElement>( ), withDynamic, visitedTypePairs);
7286 }
7287
7288 @override
7289 bool internalIsSubtypeOf(DartType type, Set<TypeImpl_TypePair> visitedTypePair s) {
7290 //
7291 // T is a subtype of S, written T <: S, iff [bottom/dynamic]T << S
7292 //
7293 if (type.isDynamic) {
7294 return true;
7295 } else if (type is TypeParameterType) {
7296 return false;
7297 } else if (type is UnionType) {
7298 return (type as UnionTypeImpl).internalUnionTypeIsSuperTypeOf(this, visite dTypePairs);
7299 } else if (type is FunctionType) {
7300 // This implementation assumes transitivity
7301 // for function type subtyping on the RHS, but a literal reading
7302 // of the spec does not specify this. More precisely: if T <: F1 and F1 <: F2 and
7303 // F1 and F2 are function types, then we assume T <: F2.
7304 //
7305 // From the Function Types section of the spec:
7306 //
7307 // If a type I includes an instance method named call(), and the type of call()
7308 // is the function type F, then I is considered to be a subtype of F.
7309 //
7310 // However, the section on Interface Types says
7311 //
7312 // T is a subtype of S, written T <: S, iff [bottom/dynamic]T << S.
7313 //
7314 // after giving rules for << (pronounced "more specific than"). However, t he "only if"
7315 // direction of the "iff"
7316 // in the definition of <: seems to be contradicted by the special case <: rule
7317 // quoted from the Function Types section: I see no rule for << which tell s us that
7318 // I << F if I has call() at type F.
7319 //
7320 // After defining <: , the spec then
7321 // emphasizes that unlike the relation <<, the relation <: is not transiti ve in general:
7322 //
7323 // Note that <: is not a partial order on types, it is only binary relat ion on types.
7324 // This is because <: is not transitive. If it was, the subtype rule wou ld have a cycle.
7325 // For example: List <: List<String> and List<int> <: List, but List<int > is not a subtype
7326 // of List<String>. Although <: is not a partial order on types, it does contain a partial
7327 // order, namely <<. This means that, barring raw types, intuition about classical subtype
7328 // rules does apply.
7329 //
7330 // There is no other occurrence of the word "raw" in relation to types in the spec that I can
7331 // find, but presumably it's a reference to
7332 //
7333 // http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html
7334 //
7335 // so e.g. non-generic types are never raw. As pointed out by paulberry, i t's not clear
7336 // whether a type like T<int, dynamic> should be considered raw or not. On the one hand, it
7337 // doesn't correspond to a "raw"-in-the-Java-sense occurrence of T, which would instead
7338 // be T<dynamic, dynamic>; on the other hand, it's treated differently by <: and << when
7339 // occurring on the left hand side.
7340 ClassElement element = this.element;
7341 InheritanceManager manager = new InheritanceManager(element.library);
7342 FunctionType callType = manager.lookupMemberType(this, "call");
7343 if (callType != null) {
7344 // A more literal reading of the spec would give something like
7345 //
7346 // return callType.equals(type)
7347 //
7348 // here, but that causes 101 errors in the external tests
7349 // (tools/test.py --mode release --compiler dartanalyzer --runtime none) .
7350 return callType.isSubtypeOf(type);
7351 }
7352 return false;
7353 } else if (type is! InterfaceType) {
7354 return false;
7355 } else if (this == type) {
7356 return true;
7357 }
7358 return _isSubtypeOf(type as InterfaceType, new HashSet<ClassElement>(), visi tedTypePairs);
7359 }
7360
7361 bool _isMoreSpecificThan(InterfaceType s, HashSet<ClassElement> visitedClasses , bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
7362 //
7363 // A type T is more specific than a type S, written T << S, if one of the f ollowing conditions
7364 // is met:
7365 //
7366 // Reflexivity: T is S.
7367 //
7368 if (this == s) {
7369 return true;
7370 }
7371 //
7372 // T is bottom. (This case is handled by the class BottomTypeImpl.)
7373 //
7374 // Direct supertype: S is a direct supertype of T.
7375 //
7376 if (s.isDirectSupertypeOf(this)) {
7377 return true;
7378 }
7379 //
7380 // Covariance: T is of the form I<T1, ..., Tn> and S is of the form I<S1, .. ., Sn> and Ti << Si, 1 <= i <= n.
7381 //
7382 ClassElement tElement = this.element;
7383 ClassElement sElement = s.element;
7384 if (tElement == sElement) {
7385 List<DartType> tArguments = typeArguments;
7386 List<DartType> sArguments = s.typeArguments;
7387 if (tArguments.length != sArguments.length) {
7388 return false;
7389 }
7390 for (int i = 0; i < tArguments.length; i++) {
7391 if (!(tArguments[i] as TypeImpl).isMoreSpecificThan2(sArguments[i], with Dynamic, visitedTypePairs)) {
7392 return false;
7393 }
7394 }
7395 return true;
7396 }
7397 //
7398 // Transitivity: T << U and U << S.
7399 //
7400 // First check for infinite loops
7401 ClassElement element = this.element;
7402 if (element == null || visitedClasses.contains(element)) {
7403 return false;
7404 }
7405 visitedClasses.add(element);
7406 // Iterate over all of the types U that are more specific than T because the y are direct
7407 // supertypes of T and return true if any of them are more specific than S.
7408 InterfaceType supertype = superclass;
7409 if (supertype != null && (supertype as InterfaceTypeImpl)._isMoreSpecificTha n(s, visitedClasses, withDynamic, visitedTypePairs)) {
7410 return true;
7411 }
7412 for (InterfaceType interfaceType in interfaces) {
7413 if ((interfaceType as InterfaceTypeImpl)._isMoreSpecificThan(s, visitedCla sses, withDynamic, visitedTypePairs)) {
7414 return true;
7415 }
7416 }
7417 for (InterfaceType mixinType in mixins) {
7418 if ((mixinType as InterfaceTypeImpl)._isMoreSpecificThan(s, visitedClasses , withDynamic, visitedTypePairs)) {
7419 return true;
7420 }
7421 }
7422 return false;
7423 }
7424
7425 bool _isSubtypeOf(InterfaceType type, HashSet<ClassElement> visitedClasses, Se t<TypeImpl_TypePair> visitedTypePairs) {
7426 InterfaceType typeT = this;
7427 InterfaceType typeS = type;
7428 ClassElement elementT = element;
7429 if (elementT == null || visitedClasses.contains(elementT)) {
7430 return false;
7431 }
7432 visitedClasses.add(elementT);
7433 if (typeT == typeS) {
7434 return true;
7435 } else if (elementT == typeS.element) {
7436 // For each of the type arguments return true if all type args from T is a subtype of all
7437 // types from S.
7438 List<DartType> typeTArgs = typeT.typeArguments;
7439 List<DartType> typeSArgs = typeS.typeArguments;
7440 if (typeTArgs.length != typeSArgs.length) {
7441 // This case covers the case where two objects are being compared that h ave a different
7442 // number of parameterized types.
7443 return false;
7444 }
7445 for (int i = 0; i < typeTArgs.length; i++) {
7446 // Recursively call isSubtypeOf the type arguments and return false if t he T argument is not
7447 // a subtype of the S argument.
7448 if (!(typeTArgs[i] as TypeImpl).isSubtypeOf2(typeSArgs[i], visitedTypePa irs)) {
7449 return false;
7450 }
7451 }
7452 return true;
7453 } else if (typeS.isDartCoreFunction && elementT.getMethod("call") != null) {
7454 return true;
7455 }
7456 InterfaceType supertype = superclass;
7457 // The type is Object, return false.
7458 if (supertype != null && (supertype as InterfaceTypeImpl)._isSubtypeOf(typeS , visitedClasses, visitedTypePairs)) {
7459 return true;
7460 }
7461 List<InterfaceType> interfaceTypes = interfaces;
7462 for (InterfaceType interfaceType in interfaceTypes) {
7463 if ((interfaceType as InterfaceTypeImpl)._isSubtypeOf(typeS, visitedClasse s, visitedTypePairs)) {
7464 return true;
7465 }
7466 }
7467 List<InterfaceType> mixinTypes = mixins;
7468 for (InterfaceType mixinType in mixinTypes) {
7469 if ((mixinType as InterfaceTypeImpl)._isSubtypeOf(typeS, visitedClasses, v isitedTypePairs)) {
7470 return true;
7471 }
7472 }
7473 return false;
7474 }
7475 }
7476
7477 /**
7478 * Combination of [AngularTagSelectorElementImpl] and [HasAttributeSelectorEleme ntImpl].
7479 */
7480 class IsTagHasAttributeSelectorElementImpl extends AngularSelectorElementImpl {
7481 String _tagName;
7482
7483 String _attributeName;
7484
7485 IsTagHasAttributeSelectorElementImpl(String tagName, String attributeName) : s uper("${tagName}[${attributeName}]", -1) {
7486 this._tagName = tagName;
7487 this._attributeName = attributeName;
7488 }
7489
7490 @override
7491 bool apply(XmlTagNode node) => node.tag == _tagName && node.getAttribute(_attr ibuteName) != null;
7492
7493 String get attributeName => _attributeName;
7494
7495 String get tagName => _tagName;
7496 }
7497
7498 /**
7499 * The interface `LabelElement` defines the behavior of elements representing a label
7500 * associated with a statement.
7501 */
7502 abstract class LabelElement implements Element {
7503 /**
7504 * Return the executable element in which this label is defined.
7505 *
7506 * @return the executable element in which this label is defined
7507 */
7508 @override
7509 ExecutableElement get enclosingElement;
7510 }
7511
7512 /**
7513 * Instances of the class `LabelElementImpl` implement a `LabelElement`.
7514 */
7515 class LabelElementImpl extends ElementImpl implements LabelElement {
7516 /**
7517 * A flag indicating whether this label is associated with a `switch` statemen t.
7518 */
7519 final bool _onSwitchStatement;
7520
7521 /**
7522 * A flag indicating whether this label is associated with a `switch` member ( `case`
7523 * or `default`).
7524 */
7525 final bool _onSwitchMember;
7526
7527 /**
7528 * An empty array of label elements.
7529 */
7530 static List<LabelElement> EMPTY_ARRAY = new List<LabelElement>(0);
7531
7532 /**
7533 * Initialize a newly created label element to have the given name.
7534 *
7535 * @param name the name of this element
7536 * @param onSwitchStatement `true` if this label is associated with a `switch`
7537 * statement
7538 * @param onSwitchMember `true` if this label is associated with a `switch` me mber
7539 */
7540 LabelElementImpl(Identifier name, this._onSwitchStatement, this._onSwitchMembe r) : super.forNode(name);
7541
7542 @override
7543 accept(ElementVisitor visitor) => visitor.visitLabelElement(this);
7544
7545 @override
7546 ExecutableElement get enclosingElement => super.enclosingElement as Executable Element;
7547
7548 @override
7549 ElementKind get kind => ElementKind.LABEL;
7550
7551 /**
7552 * Return `true` if this label is associated with a `switch` member (`case` or
7553 * `default`).
7554 *
7555 * @return `true` if this label is associated with a `switch` member
7556 */
7557 bool get isOnSwitchMember => _onSwitchMember;
7558
7559 /**
7560 * Return `true` if this label is associated with a `switch` statement.
7561 *
7562 * @return `true` if this label is associated with a `switch` statement
7563 */
7564 bool get isOnSwitchStatement => _onSwitchStatement;
7565 }
7566
7567 /**
7568 * The interface `LibraryElement` defines the behavior of elements representing a library.
7569 */
7570 abstract class LibraryElement implements Element {
7571 /**
7572 * Return the compilation unit that defines this library.
7573 *
7574 * @return the compilation unit that defines this library
7575 */
7576 CompilationUnitElement get definingCompilationUnit;
7577
7578 /**
7579 * Return the entry point for this library, or `null` if this library does not have an entry
7580 * point. The entry point is defined to be a zero argument top-level function whose name is
7581 * `main`.
7582 *
7583 * @return the entry point for this library
7584 */
7585 FunctionElement get entryPoint;
7586
7587 /**
7588 * Return an array containing all of the libraries that are exported from this library.
7589 *
7590 * @return an array containing all of the libraries that are exported from thi s library
7591 */
7592 List<LibraryElement> get exportedLibraries;
7593
7594 /**
7595 * Return an array containing all of the exports defined in this library.
7596 *
7597 * @return the exports defined in this library
7598 */
7599 List<ExportElement> get exports;
7600
7601 /**
7602 * Return an array containing all of the libraries that are imported into this library. This
7603 * includes all of the libraries that are imported using a prefix (also availa ble through the
7604 * prefixes returned by [getPrefixes]) and those that are imported without a p refix.
7605 *
7606 * @return an array containing all of the libraries that are imported into thi s library
7607 */
7608 List<LibraryElement> get importedLibraries;
7609
7610 /**
7611 * Return an array containing all of the imports defined in this library.
7612 *
7613 * @return the imports defined in this library
7614 */
7615 List<ImportElement> get imports;
7616
7617 /**
7618 * Return an array containing all of the imports that share the given prefix, or an empty array if
7619 * there are no such imports.
7620 *
7621 * @param prefixElement the prefix element shared by the returned imports
7622 */
7623 List<ImportElement> getImportsWithPrefix(PrefixElement prefixElement);
7624
7625 /**
7626 * Return the element representing the synthetic function `loadLibrary` that i s implicitly
7627 * defined for this library if the library is imported using a deferred import .
7628 */
7629 FunctionElement get loadLibraryFunction;
7630
7631 /**
7632 * Return an array containing all of the compilation units that are included i n this library using
7633 * a `part` directive. This does not include the defining compilation unit tha t contains the
7634 * `part` directives.
7635 *
7636 * @return the compilation units that are included in this library
7637 */
7638 List<CompilationUnitElement> get parts;
7639
7640 /**
7641 * Return an array containing elements for each of the prefixes used to `impor t` libraries
7642 * into this library. Each prefix can be used in more than one `import` direct ive.
7643 *
7644 * @return the prefixes used to `import` libraries into this library
7645 */
7646 List<PrefixElement> get prefixes;
7647
7648 /**
7649 * Return the class defined in this library that has the given name, or `null` if this
7650 * library does not define a class with the given name.
7651 *
7652 * @param className the name of the class to be returned
7653 * @return the class with the given name that is defined in this library
7654 */
7655 ClassElement getType(String className);
7656
7657 /**
7658 * Return an array containing all of the compilation units this library consis ts of. This includes
7659 * the defining compilation unit and units included using the `part` directive .
7660 *
7661 * @return the compilation units this library consists of
7662 */
7663 List<CompilationUnitElement> get units;
7664
7665 /**
7666 * Return an array containing all directly and indirectly imported libraries.
7667 *
7668 * @return all directly and indirectly imported libraries
7669 */
7670 List<LibraryElement> get visibleLibraries;
7671
7672 /**
7673 * Return `true` if the defining compilation unit of this library contains at least one
7674 * import directive whose URI uses the "dart-ext" scheme.
7675 */
7676 bool get hasExtUri;
7677
7678 /**
7679 * Return `true` if this library defines a top-level function named `loadLibra ry`.
7680 *
7681 * @return `true` if this library defines a top-level function named `loadLibr ary`
7682 */
7683 bool get hasLoadLibraryFunction;
7684
7685 /**
7686 * Return `true` if this library is created for Angular analysis. If this libr ary has not
7687 * yet had toolkit references resolved, then `false` will be returned.
7688 *
7689 * @return `true` if this library is created for Angular analysis
7690 */
7691 bool get isAngularHtml;
7692
7693 /**
7694 * Return `true` if this library is an application that can be run in the brow ser.
7695 *
7696 * @return `true` if this library is an application that can be run in the bro wser
7697 */
7698 bool get isBrowserApplication;
7699
7700 /**
7701 * Return `true` if this library is the dart:core library.
7702 *
7703 * @return `true` if this library is the dart:core library
7704 */
7705 bool get isDartCore;
7706
7707 /**
7708 * Return `true` if this library is the dart:core library.
7709 *
7710 * @return `true` if this library is the dart:core library
7711 */
7712 bool get isInSdk;
7713
7714 /**
7715 * Return `true` if this library is up to date with respect to the given time stamp. If any
7716 * transitively referenced Source is newer than the time stamp, this method re turns false.
7717 *
7718 * @param timeStamp the time stamp to compare against
7719 * @return `true` if this library is up to date with respect to the given time stamp
7720 */
7721 bool isUpToDate(int timeStamp);
7722 }
7723
7724 /**
7725 * Instances of the class `LibraryElementImpl` implement a `LibraryElement`.
7726 */
7727 class LibraryElementImpl extends ElementImpl implements LibraryElement {
7728 /**
7729 * An empty array of library elements.
7730 */
7731 static List<LibraryElement> EMPTY_ARRAY = new List<LibraryElement>(0);
7732
7733 /**
7734 * Determine if the given library is up to date with respect to the given time stamp.
7735 *
7736 * @param library the library to process
7737 * @param timeStamp the time stamp to check against
7738 * @param visitedLibraries the set of visited libraries
7739 */
7740 static bool _safeIsUpToDate(LibraryElement library, int timeStamp, Set<Library Element> visitedLibraries) {
7741 if (!visitedLibraries.contains(library)) {
7742 visitedLibraries.add(library);
7743 AnalysisContext context = library.context;
7744 // Check the defining compilation unit.
7745 if (timeStamp < context.getModificationStamp(library.definingCompilationUn it.source)) {
7746 return false;
7747 }
7748 // Check the parted compilation units.
7749 for (CompilationUnitElement element in library.parts) {
7750 if (timeStamp < context.getModificationStamp(element.source)) {
7751 return false;
7752 }
7753 }
7754 // Check the imported libraries.
7755 for (LibraryElement importedLibrary in library.importedLibraries) {
7756 if (!_safeIsUpToDate(importedLibrary, timeStamp, visitedLibraries)) {
7757 return false;
7758 }
7759 }
7760 // Check the exported libraries.
7761 for (LibraryElement exportedLibrary in library.exportedLibraries) {
7762 if (!_safeIsUpToDate(exportedLibrary, timeStamp, visitedLibraries)) {
7763 return false;
7764 }
7765 }
7766 }
7767 return true;
7768 }
7769
7770 /**
7771 * The analysis context in which this library is defined.
7772 */
7773 final AnalysisContext context;
7774
7775 /**
7776 * The compilation unit that defines this library.
7777 */
7778 CompilationUnitElement _definingCompilationUnit;
7779
7780 /**
7781 * The entry point for this library, or `null` if this library does not have a n entry point.
7782 */
7783 FunctionElement entryPoint;
7784
7785 /**
7786 * An array containing specifications of all of the imports defined in this li brary.
7787 */
7788 List<ImportElement> _imports = ImportElement.EMPTY_ARRAY;
7789
7790 /**
7791 * An array containing specifications of all of the exports defined in this li brary.
7792 */
7793 List<ExportElement> _exports = ExportElement.EMPTY_ARRAY;
7794
7795 /**
7796 * An array containing all of the compilation units that are included in this library using a
7797 * `part` directive.
7798 */
7799 List<CompilationUnitElement> _parts = CompilationUnitElementImpl.EMPTY_ARRAY;
7800
7801 /**
7802 * Is `true` if this library is created for Angular analysis.
7803 */
7804 bool _isAngularHtml = false;
7805
7806 /**
7807 * The element representing the synthetic function `loadLibrary` that is defin ed for this
7808 * library, or `null` if the element has not yet been created.
7809 */
7810 FunctionElement _loadLibraryFunction;
7811
7812 /**
7813 * Initialize a newly created library element to have the given name.
7814 *
7815 * @param context the analysis context in which the library is defined
7816 * @param name the name of this element
7817 */
7818 LibraryElementImpl.forNode(this.context, LibraryIdentifier name) : super.forNo de(name);
7819
7820 /**
7821 * Initialize a newly created library element to have the given name.
7822 *
7823 * @param context the analysis context in which the library is defined
7824 * @param name the name of this element
7825 * @param nameOffset the offset of the name of this element in the file that c ontains the
7826 * declaration of this element
7827 */
7828 LibraryElementImpl(this.context, String name, int nameOffset) : super(name, na meOffset);
7829
7830 @override
7831 accept(ElementVisitor visitor) => visitor.visitLibraryElement(this);
7832
7833 @override
7834 bool operator ==(Object object) => object != null && runtimeType == object.run timeType && _definingCompilationUnit == (object as LibraryElementImpl).definingC ompilationUnit;
7835
7836 @override
7837 ElementImpl getChild(String identifier) {
7838 if ((_definingCompilationUnit as CompilationUnitElementImpl).identifier == i dentifier) {
7839 return _definingCompilationUnit as CompilationUnitElementImpl;
7840 }
7841 for (CompilationUnitElement part in _parts) {
7842 if ((part as CompilationUnitElementImpl).identifier == identifier) {
7843 return part as CompilationUnitElementImpl;
7844 }
7845 }
7846 for (ImportElement importElement in _imports) {
7847 if ((importElement as ImportElementImpl).identifier == identifier) {
7848 return importElement as ImportElementImpl;
7849 }
7850 }
7851 for (ExportElement exportElement in _exports) {
7852 if ((exportElement as ExportElementImpl).identifier == identifier) {
7853 return exportElement as ExportElementImpl;
7854 }
7855 }
7856 return null;
7857 }
7858
7859 @override
7860 CompilationUnitElement get definingCompilationUnit => _definingCompilationUnit ;
7861
7862 @override
7863 List<LibraryElement> get exportedLibraries {
7864 HashSet<LibraryElement> libraries = new HashSet<LibraryElement>();
7865 for (ExportElement element in _exports) {
7866 LibraryElement library = element.exportedLibrary;
7867 if (library != null) {
7868 libraries.add(library);
7869 }
7870 }
7871 return new List.from(libraries);
7872 }
7873
7874 @override
7875 List<ExportElement> get exports => _exports;
7876
7877 @override
7878 List<LibraryElement> get importedLibraries {
7879 HashSet<LibraryElement> libraries = new HashSet<LibraryElement>();
7880 for (ImportElement element in _imports) {
7881 LibraryElement library = element.importedLibrary;
7882 if (library != null) {
7883 libraries.add(library);
7884 }
7885 }
7886 return new List.from(libraries);
7887 }
7888
7889 @override
7890 List<ImportElement> get imports => _imports;
7891
7892 @override
7893 List<ImportElement> getImportsWithPrefix(PrefixElement prefixElement) {
7894 int count = _imports.length;
7895 List<ImportElement> importList = new List<ImportElement>();
7896 for (int i = 0; i < count; i++) {
7897 if (identical(_imports[i].prefix, prefixElement)) {
7898 importList.add(_imports[i]);
7899 }
7900 }
7901 return new List.from(importList);
7902 }
7903
7904 @override
7905 ElementKind get kind => ElementKind.LIBRARY;
7906
7907 @override
7908 LibraryElement get library => this;
7909
7910 @override
7911 FunctionElement get loadLibraryFunction {
7912 if (_loadLibraryFunction == null) {
7913 FunctionElementImpl function = new FunctionElementImpl(FunctionElement.LOA D_LIBRARY_NAME, -1);
7914 function.synthetic = true;
7915 function.enclosingElement = this;
7916 function.returnType = loadLibraryReturnType;
7917 function.type = new FunctionTypeImpl.con1(function);
7918 _loadLibraryFunction = function;
7919 }
7920 return _loadLibraryFunction;
7921 }
7922
7923 @override
7924 List<CompilationUnitElement> get parts => _parts;
7925
7926 @override
7927 List<PrefixElement> get prefixes {
7928 HashSet<PrefixElement> prefixes = new HashSet<PrefixElement>();
7929 for (ImportElement element in _imports) {
7930 PrefixElement prefix = element.prefix;
7931 if (prefix != null) {
7932 prefixes.add(prefix);
7933 }
7934 }
7935 return new List.from(prefixes);
7936 }
7937
7938 @override
7939 Source get source {
7940 if (_definingCompilationUnit == null) {
7941 return null;
7942 }
7943 return _definingCompilationUnit.source;
7944 }
7945
7946 @override
7947 ClassElement getType(String className) {
7948 ClassElement type = _definingCompilationUnit.getType(className);
7949 if (type != null) {
7950 return type;
7951 }
7952 for (CompilationUnitElement part in _parts) {
7953 type = part.getType(className);
7954 if (type != null) {
7955 return type;
7956 }
7957 }
7958 return null;
7959 }
7960
7961 @override
7962 List<CompilationUnitElement> get units {
7963 List<CompilationUnitElement> units = new List<CompilationUnitElement>(1 + _p arts.length);
7964 units[0] = _definingCompilationUnit;
7965 JavaSystem.arraycopy(_parts, 0, units, 1, _parts.length);
7966 return units;
7967 }
7968
7969 @override
7970 List<LibraryElement> get visibleLibraries {
7971 Set<LibraryElement> visibleLibraries = new Set();
7972 _addVisibleLibraries(visibleLibraries, false);
7973 return new List.from(visibleLibraries);
7974 }
7975
7976 @override
7977 bool get hasExtUri => hasModifier(Modifier.HAS_EXT_URI);
7978
7979 @override
7980 int get hashCode => _definingCompilationUnit.hashCode;
7981
7982 @override
7983 bool get hasLoadLibraryFunction {
7984 if (_definingCompilationUnit.hasLoadLibraryFunction) {
7985 return true;
7986 }
7987 for (int i = 0; i < _parts.length; i++) {
7988 if (_parts[i].hasLoadLibraryFunction) {
7989 return true;
7990 }
7991 }
7992 return false;
7993 }
7994
7995 @override
7996 bool get isAngularHtml => _isAngularHtml;
7997
7998 @override
7999 bool get isBrowserApplication => entryPoint != null && isOrImportsBrowserLibra ry;
8000
8001 @override
8002 bool get isDartCore => name == "dart.core";
8003
8004 @override
8005 bool get isInSdk => StringUtilities.startsWith5(name, 0, 0x64, 0x61, 0x72, 0x7 4, 0x2E);
8006
8007 @override
8008 bool isUpToDate(int timeStamp) {
8009 Set<LibraryElement> visitedLibraries = new Set();
8010 return _safeIsUpToDate(this, timeStamp, visitedLibraries);
8011 }
8012
8013 /**
8014 * Specifies if this library is created for Angular analysis.
8015 */
8016 void set angularHtml(bool isAngularHtml) {
8017 this._isAngularHtml = isAngularHtml;
8018 }
8019
8020 /**
8021 * Set the compilation unit that defines this library to the given compilation unit.
8022 *
8023 * @param definingCompilationUnit the compilation unit that defines this libra ry
8024 */
8025 void set definingCompilationUnit(CompilationUnitElement definingCompilationUni t) {
8026 (definingCompilationUnit as CompilationUnitElementImpl).enclosingElement = t his;
8027 this._definingCompilationUnit = definingCompilationUnit;
8028 }
8029
8030 /**
8031 * Set the specifications of all of the exports defined in this library to the given array.
8032 *
8033 * @param exports the specifications of all of the exports defined in this lib rary
8034 */
8035 void set exports(List<ExportElement> exports) {
8036 for (ExportElement exportElement in exports) {
8037 (exportElement as ExportElementImpl).enclosingElement = this;
8038 }
8039 this._exports = exports;
8040 }
8041
8042 /**
8043 * Set whether this library has an import of a "dart-ext" URI to the given val ue.
8044 *
8045 * @param hasExtUri `true` if this library has an import of a "dart-ext" URI
8046 */
8047 void set hasExtUri(bool hasExtUri) {
8048 setModifier(Modifier.HAS_EXT_URI, hasExtUri);
8049 }
8050
8051 /**
8052 * Set the specifications of all of the imports defined in this library to the given array.
8053 *
8054 * @param imports the specifications of all of the imports defined in this lib rary
8055 */
8056 void set imports(List<ImportElement> imports) {
8057 for (ImportElement importElement in imports) {
8058 (importElement as ImportElementImpl).enclosingElement = this;
8059 PrefixElementImpl prefix = importElement.prefix as PrefixElementImpl;
8060 if (prefix != null) {
8061 prefix.enclosingElement = this;
8062 }
8063 }
8064 this._imports = imports;
8065 }
8066
8067 /**
8068 * Set the compilation units that are included in this library using a `part` directive.
8069 *
8070 * @param parts the compilation units that are included in this library using a `part`
8071 * directive
8072 */
8073 void set parts(List<CompilationUnitElement> parts) {
8074 for (CompilationUnitElement compilationUnit in parts) {
8075 (compilationUnit as CompilationUnitElementImpl).enclosingElement = this;
8076 }
8077 this._parts = parts;
8078 }
8079
8080 @override
8081 void visitChildren(ElementVisitor visitor) {
8082 super.visitChildren(visitor);
8083 safelyVisitChild(_definingCompilationUnit, visitor);
8084 safelyVisitChildren(_exports, visitor);
8085 safelyVisitChildren(_imports, visitor);
8086 safelyVisitChildren(_parts, visitor);
8087 }
8088
8089 @override
8090 String get identifier => _definingCompilationUnit.source.encoding;
8091
8092 /**
8093 * Recursively fills set of visible libraries for [getVisibleElementsLibraries ].
8094 */
8095 void _addVisibleLibraries(Set<LibraryElement> visibleLibraries, bool includeEx ports) {
8096 // maybe already processed
8097 if (!visibleLibraries.add(this)) {
8098 return;
8099 }
8100 // add imported libraries
8101 for (ImportElement importElement in _imports) {
8102 LibraryElement importedLibrary = importElement.importedLibrary;
8103 if (importedLibrary != null) {
8104 (importedLibrary as LibraryElementImpl)._addVisibleLibraries(visibleLibr aries, true);
8105 }
8106 }
8107 // add exported libraries
8108 if (includeExports) {
8109 for (ExportElement exportElement in _exports) {
8110 LibraryElement exportedLibrary = exportElement.exportedLibrary;
8111 if (exportedLibrary != null) {
8112 (exportedLibrary as LibraryElementImpl)._addVisibleLibraries(visibleLi braries, true);
8113 }
8114 }
8115 }
8116 }
8117
8118 /**
8119 * Return the object representing the type "Future" from the dart:async librar y, or the type
8120 * "void" if the type "Future" cannot be accessed.
8121 *
8122 * @return the type "Future" from the dart:async library
8123 */
8124 DartType get loadLibraryReturnType {
8125 try {
8126 Source asyncSource = context.sourceFactory.forUri(DartSdk.DART_ASYNC);
8127 if (asyncSource == null) {
8128 AnalysisEngine.instance.logger.logError("Could not create a source for d art:async");
8129 return VoidTypeImpl.instance;
8130 }
8131 LibraryElement asyncElement = context.computeLibraryElement(asyncSource);
8132 if (asyncElement == null) {
8133 AnalysisEngine.instance.logger.logError("Could not build the element mod el for dart:async");
8134 return VoidTypeImpl.instance;
8135 }
8136 ClassElement futureElement = asyncElement.getType("Future");
8137 if (futureElement == null) {
8138 AnalysisEngine.instance.logger.logError("Could not find type Future in d art:async");
8139 return VoidTypeImpl.instance;
8140 }
8141 InterfaceType futureType = futureElement.type;
8142 return futureType.substitute4(<DartType> [DynamicTypeImpl.instance]);
8143 } on AnalysisException catch (exception, stackTrace) {
8144 AnalysisEngine.instance.logger.logError2("Could not build the element mode l for dart:async", new CaughtException(exception, stackTrace));
8145 return VoidTypeImpl.instance;
8146 }
8147 }
8148
8149 /**
8150 * Answer `true` if the receiver directly or indirectly imports the dart:html libraries.
8151 *
8152 * @return `true` if the receiver directly or indirectly imports the dart:html libraries
8153 */
8154 bool get isOrImportsBrowserLibrary {
8155 List<LibraryElement> visited = new List<LibraryElement>();
8156 Source htmlLibSource = context.sourceFactory.forUri(DartSdk.DART_HTML);
8157 visited.add(this);
8158 for (int index = 0; index < visited.length; index++) {
8159 LibraryElement library = visited[index];
8160 Source source = library.definingCompilationUnit.source;
8161 if (source == htmlLibSource) {
8162 return true;
8163 }
8164 for (LibraryElement importedLibrary in library.importedLibraries) {
8165 if (!visited.contains(importedLibrary)) {
8166 visited.add(importedLibrary);
8167 }
8168 }
8169 for (LibraryElement exportedLibrary in library.exportedLibraries) {
8170 if (!visited.contains(exportedLibrary)) {
8171 visited.add(exportedLibrary);
8172 }
8173 }
8174 }
8175 return false;
8176 }
8177 }
8178
8179 /**
8180 * The interface `LocalElement` defines the behavior of elements that can be (bu t are not
8181 * required to be) defined within a method or function (an [ExecutableElement]).
8182 */
8183 abstract class LocalElement implements Element {
8184 /**
8185 * Return a source range that covers the approximate portion of the source in which the name of
8186 * this element is visible, or `null` if there is no single range of character s within which
8187 * the element name is visible.
8188 * * For a local variable, this includes everything from the end of the variab le's initializer
8189 * to the end of the block that encloses the variable declaration.
8190 * * For a parameter, this includes the body of the method or function that de clares the
8191 * parameter.
8192 * * For a local function, this includes everything from the beginning of the function's body to
8193 * the end of the block that encloses the function declaration.
8194 * * For top-level functions, `null` will be returned because they are potenti ally visible
8195 * in multiple sources.
8196 *
8197 * @return the range of characters in which the name of this element is visibl e
8198 */
8199 SourceRange get visibleRange;
8200 }
8201
8202 /**
8203 * The interface `LocalVariableElement` defines the behavior common to elements that represent
8204 * a local variable.
8205 */
8206 abstract class LocalVariableElement implements LocalElement, VariableElement {
8207 /**
8208 * Return an array containing all of the toolkit specific objects attached to this variable.
8209 *
8210 * @return the toolkit objects attached to this variable
8211 */
8212 List<ToolkitObjectElement> get toolkitObjects;
8213 }
8214
8215 /**
8216 * Instances of the class `LocalVariableElementImpl` implement a `LocalVariableE lement`.
8217 */
8218 class LocalVariableElementImpl extends VariableElementImpl implements LocalVaria bleElement {
8219 /**
8220 * The offset to the beginning of the visible range for this element.
8221 */
8222 int _visibleRangeOffset = 0;
8223
8224 /**
8225 * The length of the visible range for this element, or `-1` if this element d oes not have a
8226 * visible range.
8227 */
8228 int _visibleRangeLength = -1;
8229
8230 /**
8231 * An empty array of field elements.
8232 */
8233 static List<LocalVariableElement> EMPTY_ARRAY = new List<LocalVariableElement> (0);
8234
8235 /**
8236 * Initialize a newly created local variable element to have the given name.
8237 *
8238 * @param name the name of this element
8239 */
8240 LocalVariableElementImpl.forNode(Identifier name) : super.forNode(name);
8241
8242 /**
8243 * Initialize a newly created method element to have the given name.
8244 *
8245 * @param name the name of this element
8246 * @param nameOffset the offset of the name of this element in the file that c ontains the
8247 * declaration of this element
8248 */
8249 LocalVariableElementImpl(String name, int nameOffset) : super(name, nameOffset );
8250
8251 @override
8252 accept(ElementVisitor visitor) => visitor.visitLocalVariableElement(this);
8253
8254 @override
8255 ElementKind get kind => ElementKind.LOCAL_VARIABLE;
8256
8257 @override
8258 List<ToolkitObjectElement> get toolkitObjects {
8259 CompilationUnitElementImpl unit = getAncestor((element) => element is Compil ationUnitElementImpl);
8260 if (unit == null) {
8261 return ToolkitObjectElement.EMPTY_ARRAY;
8262 }
8263 return unit._getToolkitObjects(this);
8264 }
8265
8266 @override
8267 SourceRange get visibleRange {
8268 if (_visibleRangeLength < 0) {
8269 return null;
8270 }
8271 return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
8272 }
8273
8274 @override
8275 bool get isPotentiallyMutatedInClosure => hasModifier(Modifier.POTENTIALLY_MUT ATED_IN_CONTEXT);
8276
8277 @override
8278 bool get isPotentiallyMutatedInScope => hasModifier(Modifier.POTENTIALLY_MUTAT ED_IN_SCOPE);
8279
8280 /**
8281 * Specifies that this variable is potentially mutated somewhere in closure.
8282 */
8283 void markPotentiallyMutatedInClosure() {
8284 setModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT, true);
8285 }
8286
8287 /**
8288 * Specifies that this variable is potentially mutated somewhere in its scope.
8289 */
8290 void markPotentiallyMutatedInScope() {
8291 setModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE, true);
8292 }
8293
8294 /**
8295 * Set the toolkit specific information objects attached to this variable.
8296 *
8297 * @param toolkitObjects the toolkit objects attached to this variable
8298 */
8299 void set toolkitObjects(List<ToolkitObjectElement> toolkitObjects) {
8300 CompilationUnitElementImpl unit = getAncestor((element) => element is Compil ationUnitElementImpl);
8301 if (unit == null) {
8302 return;
8303 }
8304 unit._setToolkitObjects(this, toolkitObjects);
8305 }
8306
8307 /**
8308 * Set the visible range for this element to the range starting at the given o ffset with the given
8309 * length.
8310 *
8311 * @param offset the offset to the beginning of the visible range for this ele ment
8312 * @param length the length of the visible range for this element, or `-1` if this element
8313 * does not have a visible range
8314 */
8315 void setVisibleRange(int offset, int length) {
8316 _visibleRangeOffset = offset;
8317 _visibleRangeLength = length;
8318 }
8319
8320 @override
8321 void appendTo(JavaStringBuilder builder) {
8322 builder.append(type);
8323 builder.append(" ");
8324 builder.append(displayName);
8325 }
8326
8327 @override
8328 String get identifier => "${super.identifier}@${nameOffset}";
8329 }
8330
8331 /**
8332 * The abstract class `Member` defines the behavior common to elements that repr esent members
8333 * of parameterized types.
8334 */
8335 abstract class Member implements Element {
8336 /**
8337 * The element on which the parameterized element was created.
8338 */
8339 final Element _baseElement;
8340
8341 /**
8342 * The type in which the element is defined.
8343 */
8344 final ParameterizedType _definingType;
8345
8346 /**
8347 * Initialize a newly created element to represent the member of the given par ameterized type.
8348 *
8349 * @param baseElement the element on which the parameterized element was creat ed
8350 * @param definingType the type in which the element is defined
8351 */
8352 Member(this._baseElement, this._definingType);
8353
8354 @override
8355 String computeDocumentationComment() => _baseElement.computeDocumentationComme nt();
8356
8357 @override
8358 Element getAncestor(Predicate<Element> predicate) => baseElement.getAncestor(p redicate);
8359
8360 /**
8361 * Return the element on which the parameterized element was created.
8362 *
8363 * @return the element on which the parameterized element was created
8364 */
8365 Element get baseElement => _baseElement;
8366
8367 @override
8368 AnalysisContext get context => _baseElement.context;
8369
8370 @override
8371 String get displayName => _baseElement.displayName;
8372
8373 @override
8374 String getExtendedDisplayName(String shortName) => _baseElement.getExtendedDis playName(shortName);
8375
8376 @override
8377 ElementKind get kind => _baseElement.kind;
8378
8379 @override
8380 LibraryElement get library => _baseElement.library;
8381
8382 @override
8383 ElementLocation get location => _baseElement.location;
8384
8385 @override
8386 List<ElementAnnotation> get metadata => _baseElement.metadata;
8387
8388 @override
8389 String get name => _baseElement.name;
8390
8391 @override
8392 int get nameOffset => _baseElement.nameOffset;
8393
8394 @override
8395 AstNode get node => _baseElement.node;
8396
8397 @override
8398 Source get source => _baseElement.source;
8399
8400 @override
8401 CompilationUnit get unit => _baseElement.unit;
8402
8403 @override
8404 bool isAccessibleIn(LibraryElement library) => _baseElement.isAccessibleIn(lib rary);
8405
8406 @override
8407 bool get isDeprecated => _baseElement.isDeprecated;
8408
8409 @override
8410 bool get isOverride => _baseElement.isOverride;
8411
8412 @override
8413 bool get isPrivate => _baseElement.isPrivate;
8414
8415 @override
8416 bool get isPublic => _baseElement.isPublic;
8417
8418 @override
8419 bool get isSynthetic => _baseElement.isSynthetic;
8420
8421 @override
8422 void visitChildren(ElementVisitor visitor) {
8423 }
8424
8425 /**
8426 * Return the type in which the element is defined.
8427 *
8428 * @return the type in which the element is defined
8429 */
8430 ParameterizedType get definingType => _definingType;
8431
8432 /**
8433 * If the given child is not `null`, use the given visitor to visit it.
8434 *
8435 * @param child the child to be visited
8436 * @param visitor the visitor to be used to visit the child
8437 */
8438 void safelyVisitChild(Element child, ElementVisitor visitor) {
8439 if (child != null) {
8440 child.accept(visitor);
8441 }
8442 }
8443
8444 /**
8445 * Use the given visitor to visit all of the children in the given array.
8446 *
8447 * @param children the children to be visited
8448 * @param visitor the visitor being used to visit the children
8449 */
8450 void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
8451 if (children != null) {
8452 for (Element child in children) {
8453 child.accept(visitor);
8454 }
8455 }
8456 }
8457
8458 /**
8459 * Return the type that results from replacing the type parameters in the give n type with the type
8460 * arguments.
8461 *
8462 * @param type the type to be transformed
8463 * @return the result of transforming the type
8464 */
8465 DartType substituteFor(DartType type) {
8466 if (type == null) {
8467 return null;
8468 }
8469 List<DartType> argumentTypes = _definingType.typeArguments;
8470 List<DartType> parameterTypes = TypeParameterTypeImpl.getTypes(_definingType .typeParameters);
8471 return type.substitute2(argumentTypes, parameterTypes);
8472 }
8473
8474 /**
8475 * Return the array of types that results from replacing the type parameters i n the given types
8476 * with the type arguments.
8477 *
8478 * @param types the types to be transformed
8479 * @return the result of transforming the types
8480 */
8481 List<InterfaceType> substituteFor2(List<InterfaceType> types) {
8482 int count = types.length;
8483 List<InterfaceType> substitutedTypes = new List<InterfaceType>(count);
8484 for (int i = 0; i < count; i++) {
8485 substitutedTypes[i] = substituteFor(types[i]);
8486 }
8487 return substitutedTypes;
8488 }
8489 }
8490
8491 /**
8492 * The interface `MethodElement` defines the behavior of elements that represent a method
8493 * defined within a type.
8494 */
8495 abstract class MethodElement implements ClassMemberElement, ExecutableElement {
8496 /**
8497 * Return the resolved [MethodDeclaration] node that declares this [MethodElem ent].
8498 *
8499 * This method is expensive, because resolved AST might be evicted from cache, so parsing and
8500 * resolving will be performed.
8501 *
8502 * @return the resolved [MethodDeclaration], not `null`.
8503 */
8504 @override
8505 MethodDeclaration get node;
8506
8507 /**
8508 * Return `true` if this method is abstract. Methods are abstract if they are not external
8509 * and have no body.
8510 *
8511 * @return `true` if this method is abstract
8512 */
8513 bool get isAbstract;
8514 }
8515
8516 /**
8517 * Instances of the class `MethodElementImpl` implement a `MethodElement`.
8518 */
8519 class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
8520 /**
8521 * An empty array of method elements.
8522 */
8523 static List<MethodElement> EMPTY_ARRAY = new List<MethodElement>(0);
8524
8525 /**
8526 * Initialize a newly created method element to have the given name.
8527 *
8528 * @param name the name of this element
8529 */
8530 MethodElementImpl.forNode(Identifier name) : super.forNode(name);
8531
8532 /**
8533 * Initialize a newly created method element to have the given name.
8534 *
8535 * @param name the name of this element
8536 * @param nameOffset the offset of the name of this element in the file that c ontains the
8537 * declaration of this element
8538 */
8539 MethodElementImpl(String name, int nameOffset) : super(name, nameOffset);
8540
8541 @override
8542 accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
8543
8544 @override
8545 String get displayName {
8546 String displayName = super.displayName;
8547 if ("unary-" == displayName) {
8548 return "-";
8549 }
8550 return displayName;
8551 }
8552
8553 @override
8554 ClassElement get enclosingElement => super.enclosingElement as ClassElement;
8555
8556 @override
8557 ElementKind get kind => ElementKind.METHOD;
8558
8559 @override
8560 String get name {
8561 String name = super.name;
8562 if (isOperator && name == "-") {
8563 if (parameters.length == 0) {
8564 return "unary-";
8565 }
8566 }
8567 return super.name;
8568 }
8569
8570 @override
8571 MethodDeclaration get node => getNodeMatching((node) => node is MethodDeclarat ion);
8572
8573 @override
8574 bool get isAbstract => hasModifier(Modifier.ABSTRACT);
8575
8576 @override
8577 bool get isOperator {
8578 String name = displayName;
8579 if (name.isEmpty) {
8580 return false;
8581 }
8582 int first = name.codeUnitAt(0);
8583 return !((0x61 <= first && first <= 0x7A) || (0x41 <= first && first <= 0x5A ) || first == 0x5F || first == 0x24);
8584 }
8585
8586 @override
8587 bool get isStatic => hasModifier(Modifier.STATIC);
8588
8589 /**
8590 * Set whether this method is abstract to correspond to the given value.
8591 *
8592 * @param isAbstract `true` if the method is abstract
8593 */
8594 void set abstract(bool isAbstract) {
8595 setModifier(Modifier.ABSTRACT, isAbstract);
8596 }
8597
8598 /**
8599 * Set whether this method is static to correspond to the given value.
8600 *
8601 * @param isStatic `true` if the method is static
8602 */
8603 void set static(bool isStatic) {
8604 setModifier(Modifier.STATIC, isStatic);
8605 }
8606
8607 @override
8608 void appendTo(JavaStringBuilder builder) {
8609 builder.append(enclosingElement.displayName);
8610 builder.append(".");
8611 builder.append(displayName);
8612 super.appendTo(builder);
8613 }
8614 }
8615
8616 /**
8617 * Instances of the class `MethodMember` represent a method element defined in a parameterized
8618 * type where the values of the type parameters are known.
8619 */
8620 class MethodMember extends ExecutableMember implements MethodElement {
8621 /**
8622 * If the given method's type is different when any type parameters from the d efining type's
8623 * declaration are replaced with the actual type arguments from the defining t ype, create a method
8624 * member representing the given method. Return the member that was created, o r the base method if
8625 * no member was created.
8626 *
8627 * @param baseMethod the base method for which a member might be created
8628 * @param definingType the type defining the parameters and arguments to be us ed in the
8629 * substitution
8630 * @return the method element that will return the correctly substituted types
8631 */
8632 static MethodElement from(MethodElement baseMethod, InterfaceType definingType ) {
8633 if (baseMethod == null || definingType.typeArguments.length == 0) {
8634 return baseMethod;
8635 }
8636 FunctionType baseType = baseMethod.type;
8637 List<DartType> argumentTypes = definingType.typeArguments;
8638 List<DartType> parameterTypes = definingType.element.type.typeArguments;
8639 FunctionType substitutedType = baseType.substitute2(argumentTypes, parameter Types);
8640 if (baseType == substitutedType) {
8641 return baseMethod;
8642 }
8643 // TODO(brianwilkerson) Consider caching the substituted type in the instanc e. It would use more
8644 // memory but speed up some operations. We need to see how often the type is being re-computed.
8645 return new MethodMember(baseMethod, definingType);
8646 }
8647
8648 /**
8649 * Initialize a newly created element to represent a method of the given param eterized type.
8650 *
8651 * @param baseElement the element on which the parameterized element was creat ed
8652 * @param definingType the type in which the element is defined
8653 */
8654 MethodMember(MethodElement baseElement, InterfaceType definingType) : super(ba seElement, definingType);
8655
8656 @override
8657 accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
8658
8659 @override
8660 MethodElement get baseElement => super.baseElement as MethodElement;
8661
8662 @override
8663 ClassElement get enclosingElement => baseElement.enclosingElement;
8664
8665 @override
8666 MethodDeclaration get node => baseElement.node;
8667
8668 @override
8669 bool get isAbstract => baseElement.isAbstract;
8670
8671 @override
8672 String toString() {
8673 MethodElement baseElement = this.baseElement;
8674 List<ParameterElement> parameters = this.parameters;
8675 FunctionType type = this.type;
8676 JavaStringBuilder builder = new JavaStringBuilder();
8677 builder.append(baseElement.enclosingElement.displayName);
8678 builder.append(".");
8679 builder.append(baseElement.displayName);
8680 builder.append("(");
8681 int parameterCount = parameters.length;
8682 for (int i = 0; i < parameterCount; i++) {
8683 if (i > 0) {
8684 builder.append(", ");
8685 }
8686 builder.append(parameters[i]).toString();
8687 }
8688 builder.append(")");
8689 if (type != null) {
8690 builder.append(Element.RIGHT_ARROW);
8691 builder.append(type.returnType);
8692 }
8693 return builder.toString();
8694 }
8695 }
8696
8697 /**
8698 * The enumeration `Modifier` defines constants for all of the modifiers defined by the Dart
8699 * language and for a few additional flags that are useful.
8700 */
8701 class Modifier extends Enum<Modifier> {
8702 /**
8703 * Indicates that the modifier 'abstract' was applied to the element.
8704 */
8705 static const Modifier ABSTRACT = const Modifier('ABSTRACT', 0);
8706
8707 /**
8708 * Indicates that an executable element has a body marked as being asynchronou s.
8709 */
8710 static const Modifier ASYNCHRONOUS = const Modifier('ASYNCHRONOUS', 1);
8711
8712 /**
8713 * Indicates that the modifier 'const' was applied to the element.
8714 */
8715 static const Modifier CONST = const Modifier('CONST', 2);
8716
8717 /**
8718 * Indicates that the import element represents a deferred library.
8719 */
8720 static const Modifier DEFERRED = const Modifier('DEFERRED', 3);
8721
8722 /**
8723 * Indicates that a class element was defined by an enum declaration.
8724 */
8725 static const Modifier ENUM = const Modifier('ENUM', 4);
8726
8727 /**
8728 * Indicates that the modifier 'factory' was applied to the element.
8729 */
8730 static const Modifier FACTORY = const Modifier('FACTORY', 5);
8731
8732 /**
8733 * Indicates that the modifier 'final' was applied to the element.
8734 */
8735 static const Modifier FINAL = const Modifier('FINAL', 6);
8736
8737 /**
8738 * Indicates that an executable element has a body marked as being a generator .
8739 */
8740 static const Modifier GENERATOR = const Modifier('GENERATOR', 7);
8741
8742 /**
8743 * Indicates that the pseudo-modifier 'get' was applied to the element.
8744 */
8745 static const Modifier GETTER = const Modifier('GETTER', 8);
8746
8747 /**
8748 * A flag used for libraries indicating that the defining compilation unit con tains at least one
8749 * import directive whose URI uses the "dart-ext" scheme.
8750 */
8751 static const Modifier HAS_EXT_URI = const Modifier('HAS_EXT_URI', 9);
8752
8753 /**
8754 * Indicates that a class can validly be used as a mixin.
8755 */
8756 static const Modifier MIXIN = const Modifier('MIXIN', 10);
8757
8758 /**
8759 * Indicates that the value of a parameter or local variable might be mutated within the context.
8760 */
8761 static const Modifier POTENTIALLY_MUTATED_IN_CONTEXT = const Modifier('POTENTI ALLY_MUTATED_IN_CONTEXT', 11);
8762
8763 /**
8764 * Indicates that the value of a parameter or local variable might be mutated within the scope.
8765 */
8766 static const Modifier POTENTIALLY_MUTATED_IN_SCOPE = const Modifier('POTENTIAL LY_MUTATED_IN_SCOPE', 12);
8767
8768 /**
8769 * Indicates that a class contains an explicit reference to 'super'.
8770 */
8771 static const Modifier REFERENCES_SUPER = const Modifier('REFERENCES_SUPER', 13 );
8772
8773 /**
8774 * Indicates that the pseudo-modifier 'set' was applied to the element.
8775 */
8776 static const Modifier SETTER = const Modifier('SETTER', 14);
8777
8778 /**
8779 * Indicates that the modifier 'static' was applied to the element.
8780 */
8781 static const Modifier STATIC = const Modifier('STATIC', 15);
8782
8783 /**
8784 * Indicates that the element does not appear in the source code but was impli citly created. For
8785 * example, if a class does not define any constructors, an implicit zero-argu ment constructor
8786 * will be created and it will be marked as being synthetic.
8787 */
8788 static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 16);
8789
8790 /**
8791 * Indicates that a class was defined using an alias. TODO(brianwilkerson) Thi s should be renamed
8792 * to 'ALIAS'.
8793 */
8794 static const Modifier TYPEDEF = const Modifier('TYPEDEF', 17);
8795
8796 static const List<Modifier> values = const [
8797 ABSTRACT,
8798 ASYNCHRONOUS,
8799 CONST,
8800 DEFERRED,
8801 ENUM,
8802 FACTORY,
8803 FINAL,
8804 GENERATOR,
8805 GETTER,
8806 HAS_EXT_URI,
8807 MIXIN,
8808 POTENTIALLY_MUTATED_IN_CONTEXT,
8809 POTENTIALLY_MUTATED_IN_SCOPE,
8810 REFERENCES_SUPER,
8811 SETTER,
8812 STATIC,
8813 SYNTHETIC,
8814 TYPEDEF];
8815
8816 const Modifier(String name, int ordinal) : super(name, ordinal);
8817 }
8818
8819 /**
8820 * The interface `MultiplyDefinedElement` defines the behavior of pseudo-element s that
8821 * represent multiple elements defined within a single scope that have the same name. This situation
8822 * is not allowed by the language, so objects implementing this interface always represent an error.
8823 * As a result, most of the normal operations on elements do not make sense and will return useless
8824 * results.
8825 */
8826 abstract class MultiplyDefinedElement implements Element {
8827 /**
8828 * Return an array containing all of the elements that were defined within the scope to have the
8829 * same name.
8830 *
8831 * @return the elements that were defined with the same name
8832 */
8833 List<Element> get conflictingElements;
8834
8835 /**
8836 * Return the type of this element as the dynamic type.
8837 *
8838 * @return the type of this element as the dynamic type
8839 */
8840 DartType get type;
8841 }
8842
8843 /**
8844 * Instances of the class `MultiplyDefinedElementImpl` represent a collection of elements that
8845 * have the same name within the same scope.
8846 */
8847 class MultiplyDefinedElementImpl implements MultiplyDefinedElement {
8848 /**
8849 * Return an element that represents the given conflicting elements.
8850 *
8851 * @param context the analysis context in which the multiply defined elements are defined
8852 * @param firstElement the first element that conflicts
8853 * @param secondElement the second element that conflicts
8854 */
8855 static Element fromElements(AnalysisContext context, Element firstElement, Ele ment secondElement) {
8856 List<Element> conflictingElements = _computeConflictingElements(firstElement , secondElement);
8857 int length = conflictingElements.length;
8858 if (length == 0) {
8859 return null;
8860 } else if (length == 1) {
8861 return conflictingElements[0];
8862 }
8863 return new MultiplyDefinedElementImpl(context, conflictingElements);
8864 }
8865
8866 /**
8867 * Add the given element to the list of elements. If the element is a multiply -defined element,
8868 * add all of the conflicting elements that it represents.
8869 *
8870 * @param elements the list to which the element(s) are to be added
8871 * @param element the element(s) to be added
8872 */
8873 static void _add(HashSet<Element> elements, Element element) {
8874 if (element is MultiplyDefinedElementImpl) {
8875 for (Element conflictingElement in element.conflictingElements) {
8876 elements.add(conflictingElement);
8877 }
8878 } else {
8879 elements.add(element);
8880 }
8881 }
8882
8883 /**
8884 * Use the given elements to construct an array of conflicting elements. If ei ther of the given
8885 * elements are multiply-defined elements then the conflicting elements they r epresent will be
8886 * included in the array. Otherwise, the element itself will be included.
8887 *
8888 * @param firstElement the first element to be included
8889 * @param secondElement the second element to be included
8890 * @return an array containing all of the conflicting elements
8891 */
8892 static List<Element> _computeConflictingElements(Element firstElement, Element secondElement) {
8893 HashSet<Element> elements = new HashSet<Element>();
8894 _add(elements, firstElement);
8895 _add(elements, secondElement);
8896 return new List.from(elements);
8897 }
8898
8899 /**
8900 * The analysis context in which the multiply defined elements are defined.
8901 */
8902 final AnalysisContext context;
8903
8904 /**
8905 * The name of the conflicting elements.
8906 */
8907 String _name;
8908
8909 /**
8910 * A list containing all of the elements that conflict.
8911 */
8912 final List<Element> conflictingElements;
8913
8914 /**
8915 * Initialize a newly created element to represent a list of conflicting eleme nts.
8916 *
8917 * @param context the analysis context in which the multiply defined elements are defined
8918 * @param conflictingElements the elements that conflict
8919 */
8920 MultiplyDefinedElementImpl(this.context, this.conflictingElements) {
8921 _name = conflictingElements[0].name;
8922 }
8923
8924 @override
8925 accept(ElementVisitor visitor) => visitor.visitMultiplyDefinedElement(this);
8926
8927 @override
8928 String computeDocumentationComment() => null;
8929
8930 @override
8931 Element getAncestor(Predicate<Element> predicate) => null;
8932
8933 @override
8934 String get displayName => _name;
8935
8936 @override
8937 Element get enclosingElement => null;
8938
8939 @override
8940 String getExtendedDisplayName(String shortName) {
8941 if (shortName != null) {
8942 return shortName;
8943 }
8944 return displayName;
8945 }
8946
8947 @override
8948 ElementKind get kind => ElementKind.ERROR;
8949
8950 @override
8951 LibraryElement get library => null;
8952
8953 @override
8954 ElementLocation get location => null;
8955
8956 @override
8957 List<ElementAnnotation> get metadata => ElementAnnotationImpl.EMPTY_ARRAY;
8958
8959 @override
8960 String get name => _name;
8961
8962 @override
8963 int get nameOffset => -1;
8964
8965 @override
8966 AstNode get node => null;
8967
8968 @override
8969 Source get source => null;
8970
8971 @override
8972 DartType get type => DynamicTypeImpl.instance;
8973
8974 @override
8975 CompilationUnit get unit => null;
8976
8977 @override
8978 bool isAccessibleIn(LibraryElement library) {
8979 for (Element element in conflictingElements) {
8980 if (element.isAccessibleIn(library)) {
8981 return true;
8982 }
8983 }
8984 return false;
8985 }
8986
8987 @override
8988 bool get isDeprecated => false;
8989
8990 @override
8991 bool get isOverride => false;
8992
8993 @override
8994 bool get isPrivate {
8995 String name = displayName;
8996 if (name == null) {
8997 return false;
8998 }
8999 return Identifier.isPrivateName(name);
9000 }
9001
9002 @override
9003 bool get isPublic => !isPrivate;
9004
9005 @override
9006 bool get isSynthetic => true;
9007
9008 @override
9009 String toString() {
9010 JavaStringBuilder builder = new JavaStringBuilder();
9011 builder.append("[");
9012 int count = conflictingElements.length;
9013 for (int i = 0; i < count; i++) {
9014 if (i > 0) {
9015 builder.append(", ");
9016 }
9017 (conflictingElements[i] as ElementImpl).appendTo(builder);
9018 }
9019 builder.append("]");
9020 return builder.toString();
9021 }
9022
9023 @override
9024 void visitChildren(ElementVisitor visitor) {
9025 }
9026 }
9027
9028 /**
9029 * The interface [MultiplyInheritedExecutableElement] defines all of the behavio r of an
9030 * [ExecutableElement], with the additional information of an array of
9031 * [ExecutableElement]s from which this element was composed.
9032 */
9033 abstract class MultiplyInheritedExecutableElement implements ExecutableElement {
9034 /**
9035 * Return an array containing all of the executable elements defined within th is executable
9036 * element.
9037 *
9038 * @return the elements defined within this executable element
9039 */
9040 List<ExecutableElement> get inheritedElements;
9041 }
9042
9043 /**
9044 * The interface [MultiplyInheritedMethodElementImpl] defines all of the behavio r of an
9045 * [MethodElementImpl], with the additional information of an array of
9046 * [ExecutableElement]s from which this element was composed.
9047 */
9048 class MultiplyInheritedMethodElementImpl extends MethodElementImpl implements Mu ltiplyInheritedExecutableElement {
9049 /**
9050 * An array the array of executable elements that were used to compose this el ement.
9051 */
9052 List<ExecutableElement> _elements = MethodElementImpl.EMPTY_ARRAY;
9053
9054 MultiplyInheritedMethodElementImpl(Identifier name) : super.forNode(name) {
9055 synthetic = true;
9056 }
9057
9058 @override
9059 List<ExecutableElement> get inheritedElements => _elements;
9060
9061 void set inheritedElements(List<ExecutableElement> elements) {
9062 this._elements = elements;
9063 }
9064 }
9065
9066 /**
9067 * The interface [MultiplyInheritedPropertyAccessorElementImpl] defines all of t he behavior of
9068 * an [PropertyAccessorElementImpl], with the additional information of an array of
9069 * [ExecutableElement]s from which this element was composed.
9070 */
9071 class MultiplyInheritedPropertyAccessorElementImpl extends PropertyAccessorEleme ntImpl implements MultiplyInheritedExecutableElement {
9072 /**
9073 * An array the array of executable elements that were used to compose this el ement.
9074 */
9075 List<ExecutableElement> _elements = PropertyAccessorElementImpl.EMPTY_ARRAY;
9076
9077 MultiplyInheritedPropertyAccessorElementImpl(Identifier name) : super.forNode( name) {
9078 synthetic = true;
9079 }
9080
9081 @override
9082 List<ExecutableElement> get inheritedElements => _elements;
9083
9084 void set inheritedElements(List<ExecutableElement> elements) {
9085 this._elements = elements;
9086 }
9087 }
9088
9089 /**
9090 * The interface `NamespaceCombinator` defines the behavior common to objects th at control how
9091 * namespaces are combined.
9092 */
9093 abstract class NamespaceCombinator {
9094 /**
9095 * An empty array of namespace combinators.
9096 */
9097 static final List<NamespaceCombinator> EMPTY_ARRAY = new List<NamespaceCombina tor>(0);
9098 }
9099
9100 /**
9101 * The interface `ParameterElement` defines the behavior of elements representin g a parameter
9102 * defined within an executable element.
9103 */
9104 abstract class ParameterElement implements LocalElement, VariableElement {
9105 /**
9106 * Return a source range that covers the portion of the source in which the de fault value for this
9107 * parameter is specified, or `null` if there is no default value.
9108 *
9109 * @return the range of characters in which the default value of this paramete r is specified
9110 */
9111 SourceRange get defaultValueRange;
9112
9113 /**
9114 * Return the kind of this parameter.
9115 *
9116 * @return the kind of this parameter
9117 */
9118 ParameterKind get parameterKind;
9119
9120 /**
9121 * Return an array containing all of the parameters defined by this parameter. A parameter will
9122 * only define other parameters if it is a function typed parameter.
9123 *
9124 * @return the parameters defined by this parameter element
9125 */
9126 List<ParameterElement> get parameters;
9127
9128 /**
9129 * Return `true` if this parameter is an initializing formal parameter.
9130 *
9131 * @return `true` if this parameter is an initializing formal parameter
9132 */
9133 bool get isInitializingFormal;
9134 }
9135
9136 /**
9137 * Instances of the class `ParameterElementImpl` implement a `ParameterElement`.
9138 */
9139 class ParameterElementImpl extends VariableElementImpl implements ParameterEleme nt {
9140 /**
9141 * An array containing all of the parameters defined by this parameter element . There will only be
9142 * parameters if this parameter is a function typed parameter.
9143 */
9144 List<ParameterElement> _parameters = ParameterElementImpl.EMPTY_ARRAY;
9145
9146 /**
9147 * The kind of this parameter.
9148 */
9149 ParameterKind parameterKind;
9150
9151 /**
9152 * The offset to the beginning of the default value range for this element.
9153 */
9154 int _defaultValueRangeOffset = 0;
9155
9156 /**
9157 * The length of the default value range for this element, or `-1` if this ele ment does not
9158 * have a default value.
9159 */
9160 int _defaultValueRangeLength = -1;
9161
9162 /**
9163 * The offset to the beginning of the visible range for this element.
9164 */
9165 int _visibleRangeOffset = 0;
9166
9167 /**
9168 * The length of the visible range for this element, or `-1` if this element d oes not have a
9169 * visible range.
9170 */
9171 int _visibleRangeLength = -1;
9172
9173 /**
9174 * An empty array of field elements.
9175 */
9176 static List<ParameterElement> EMPTY_ARRAY = new List<ParameterElement>(0);
9177
9178 /**
9179 * Initialize a newly created parameter element to have the given name.
9180 *
9181 * @param name the name of this element
9182 */
9183 ParameterElementImpl.forNode(Identifier name) : super.forNode(name);
9184
9185 /**
9186 * Initialize a newly created parameter element to have the given name.
9187 *
9188 * @param name the name of this element
9189 * @param nameOffset the offset of the name of this element in the file that c ontains the
9190 * declaration of this element
9191 */
9192 ParameterElementImpl(String name, int nameOffset) : super(name, nameOffset);
9193
9194 @override
9195 accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
9196
9197 @override
9198 ElementImpl getChild(String identifier) {
9199 for (ParameterElement parameter in _parameters) {
9200 if ((parameter as ParameterElementImpl).identifier == identifier) {
9201 return parameter as ParameterElementImpl;
9202 }
9203 }
9204 return null;
9205 }
9206
9207 @override
9208 SourceRange get defaultValueRange {
9209 if (_defaultValueRangeLength < 0) {
9210 return null;
9211 }
9212 return new SourceRange(_defaultValueRangeOffset, _defaultValueRangeLength);
9213 }
9214
9215 @override
9216 ElementKind get kind => ElementKind.PARAMETER;
9217
9218 @override
9219 List<ParameterElement> get parameters => _parameters;
9220
9221 @override
9222 SourceRange get visibleRange {
9223 if (_visibleRangeLength < 0) {
9224 return null;
9225 }
9226 return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
9227 }
9228
9229 @override
9230 bool get isInitializingFormal => false;
9231
9232 @override
9233 bool get isPotentiallyMutatedInClosure => hasModifier(Modifier.POTENTIALLY_MUT ATED_IN_CONTEXT);
9234
9235 @override
9236 bool get isPotentiallyMutatedInScope => hasModifier(Modifier.POTENTIALLY_MUTAT ED_IN_SCOPE);
9237
9238 /**
9239 * Specifies that this variable is potentially mutated somewhere in closure.
9240 */
9241 void markPotentiallyMutatedInClosure() {
9242 setModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT, true);
9243 }
9244
9245 /**
9246 * Specifies that this variable is potentially mutated somewhere in its scope.
9247 */
9248 void markPotentiallyMutatedInScope() {
9249 setModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE, true);
9250 }
9251
9252 /**
9253 * Set the range of the default value for this parameter to the range starting at the given offset
9254 * with the given length.
9255 *
9256 * @param offset the offset to the beginning of the default value range for th is element
9257 * @param length the length of the default value range for this element, or `- 1` if this
9258 * element does not have a default value
9259 */
9260 void setDefaultValueRange(int offset, int length) {
9261 _defaultValueRangeOffset = offset;
9262 _defaultValueRangeLength = length;
9263 }
9264
9265 /**
9266 * Set the parameters defined by this executable element to the given paramete rs.
9267 *
9268 * @param parameters the parameters defined by this executable element
9269 */
9270 void set parameters(List<ParameterElement> parameters) {
9271 for (ParameterElement parameter in parameters) {
9272 (parameter as ParameterElementImpl).enclosingElement = this;
9273 }
9274 this._parameters = parameters;
9275 }
9276
9277 /**
9278 * Set the visible range for this element to the range starting at the given o ffset with the given
9279 * length.
9280 *
9281 * @param offset the offset to the beginning of the visible range for this ele ment
9282 * @param length the length of the visible range for this element, or `-1` if this element
9283 * does not have a visible range
9284 */
9285 void setVisibleRange(int offset, int length) {
9286 _visibleRangeOffset = offset;
9287 _visibleRangeLength = length;
9288 }
9289
9290 @override
9291 void visitChildren(ElementVisitor visitor) {
9292 super.visitChildren(visitor);
9293 safelyVisitChildren(_parameters, visitor);
9294 }
9295
9296 @override
9297 void appendTo(JavaStringBuilder builder) {
9298 String left = "";
9299 String right = "";
9300 while (true) {
9301 if (parameterKind == ParameterKind.NAMED) {
9302 left = "{";
9303 right = "}";
9304 } else if (parameterKind == ParameterKind.POSITIONAL) {
9305 left = "[";
9306 right = "]";
9307 } else if (parameterKind == ParameterKind.REQUIRED) {
9308 }
9309 break;
9310 }
9311 builder.append(left);
9312 appendToWithoutDelimiters(builder);
9313 builder.append(right);
9314 }
9315
9316 /**
9317 * Append the type and name of this parameter to the given builder.
9318 *
9319 * @param builder the builder to which the type and name are to be appended
9320 */
9321 void appendToWithoutDelimiters(JavaStringBuilder builder) {
9322 builder.append(type);
9323 builder.append(" ");
9324 builder.append(displayName);
9325 }
9326 }
9327
9328 /**
9329 * Instances of the class `ParameterMember` represent a parameter element define d in a
9330 * parameterized type where the values of the type parameters are known.
9331 */
9332 class ParameterMember extends VariableMember implements ParameterElement {
9333 /**
9334 * If the given parameter's type is different when any type parameters from th e defining type's
9335 * declaration are replaced with the actual type arguments from the defining t ype, create a
9336 * parameter member representing the given parameter. Return the member that w as created, or the
9337 * base parameter if no member was created.
9338 *
9339 * @param baseParameter the base parameter for which a member might be created
9340 * @param definingType the type defining the parameters and arguments to be us ed in the
9341 * substitution
9342 * @return the parameter element that will return the correctly substituted ty pes
9343 */
9344 static ParameterElement from(ParameterElement baseParameter, ParameterizedType definingType) {
9345 if (baseParameter == null || definingType.typeArguments.length == 0) {
9346 return baseParameter;
9347 }
9348 // Check if parameter type depends on defining type type arguments.
9349 // It is possible that we did not resolve field formal parameter yet, so ski p this check for it.
9350 bool isFieldFormal = baseParameter is FieldFormalParameterElement;
9351 if (!isFieldFormal) {
9352 DartType baseType = baseParameter.type;
9353 List<DartType> argumentTypes = definingType.typeArguments;
9354 List<DartType> parameterTypes = TypeParameterTypeImpl.getTypes(definingTyp e.typeParameters);
9355 DartType substitutedType = baseType.substitute2(argumentTypes, parameterTy pes);
9356 if (baseType == substitutedType) {
9357 return baseParameter;
9358 }
9359 }
9360 // TODO(brianwilkerson) Consider caching the substituted type in the instanc e. It would use more
9361 // memory but speed up some operations. We need to see how often the type is being re-computed.
9362 if (isFieldFormal) {
9363 return new FieldFormalParameterMember(baseParameter as FieldFormalParamete rElement, definingType);
9364 }
9365 return new ParameterMember(baseParameter, definingType);
9366 }
9367
9368 /**
9369 * Initialize a newly created element to represent a parameter of the given pa rameterized type.
9370 *
9371 * @param baseElement the element on which the parameterized element was creat ed
9372 * @param definingType the type in which the element is defined
9373 */
9374 ParameterMember(ParameterElement baseElement, ParameterizedType definingType) : super(baseElement, definingType);
9375
9376 @override
9377 accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
9378
9379 @override
9380 Element getAncestor(Predicate<Element> predicate) {
9381 Element element = baseElement.getAncestor(predicate);
9382 ParameterizedType definingType = this.definingType;
9383 if (definingType is InterfaceType) {
9384 InterfaceType definingInterfaceType = definingType;
9385 if (element is ConstructorElement) {
9386 return ConstructorMember.from(element, definingInterfaceType);
9387 } else if (element is MethodElement) {
9388 return MethodMember.from(element, definingInterfaceType);
9389 } else if (element is PropertyAccessorElement) {
9390 return PropertyAccessorMember.from(element, definingInterfaceType);
9391 }
9392 }
9393 return element;
9394 }
9395
9396 @override
9397 ParameterElement get baseElement => super.baseElement as ParameterElement;
9398
9399 @override
9400 SourceRange get defaultValueRange => baseElement.defaultValueRange;
9401
9402 @override
9403 Element get enclosingElement => baseElement.enclosingElement;
9404
9405 @override
9406 ParameterKind get parameterKind => baseElement.parameterKind;
9407
9408 @override
9409 List<ParameterElement> get parameters {
9410 List<ParameterElement> baseParameters = baseElement.parameters;
9411 int parameterCount = baseParameters.length;
9412 if (parameterCount == 0) {
9413 return baseParameters;
9414 }
9415 List<ParameterElement> parameterizedParameters = new List<ParameterElement>( parameterCount);
9416 for (int i = 0; i < parameterCount; i++) {
9417 parameterizedParameters[i] = ParameterMember.from(baseParameters[i], defin ingType);
9418 }
9419 return parameterizedParameters;
9420 }
9421
9422 @override
9423 SourceRange get visibleRange => baseElement.visibleRange;
9424
9425 @override
9426 bool get isInitializingFormal => baseElement.isInitializingFormal;
9427
9428 @override
9429 String toString() {
9430 ParameterElement baseElement = this.baseElement;
9431 String left = "";
9432 String right = "";
9433 while (true) {
9434 if (baseElement.parameterKind == ParameterKind.NAMED) {
9435 left = "{";
9436 right = "}";
9437 } else if (baseElement.parameterKind == ParameterKind.POSITIONAL) {
9438 left = "[";
9439 right = "]";
9440 } else if (baseElement.parameterKind == ParameterKind.REQUIRED) {
9441 }
9442 break;
9443 }
9444 JavaStringBuilder builder = new JavaStringBuilder();
9445 builder.append(left);
9446 builder.append(type);
9447 builder.append(" ");
9448 builder.append(baseElement.displayName);
9449 builder.append(right);
9450 return builder.toString();
9451 }
9452
9453 @override
9454 void visitChildren(ElementVisitor visitor) {
9455 super.visitChildren(visitor);
9456 safelyVisitChildren(parameters, visitor);
9457 }
9458 }
9459
9460 /**
9461 * The interface `ParameterizedType` defines the behavior common to objects repr esenting a
9462 * type with type parameters, such as a class or function type alias.
9463 */
9464 abstract class ParameterizedType implements DartType {
9465 /**
9466 * Return an array containing the actual types of the type arguments. If this type's element does
9467 * not have type parameters, then the array should be empty (although it is po ssible for type
9468 * arguments to be erroneously declared). If the element has type parameters a nd the actual type
9469 * does not explicitly include argument values, then the type "dynamic" will b e automatically
9470 * provided.
9471 *
9472 * @return the actual types of the type arguments
9473 */
9474 List<DartType> get typeArguments;
9475
9476 /**
9477 * Return an array containing all of the type parameters declared for this typ e.
9478 *
9479 * @return the type parameters declared for this type
9480 */
9481 List<TypeParameterElement> get typeParameters;
9482 }
9483
9484 /**
9485 * The interface `PolymerAttributeElement` defines an attribute in
9486 * [PolymerTagHtmlElement].
9487 *
9488 * <pre>
9489 * <polymer-element name="my-example" attributes='attrA attrB'>
9490 * </polymer-element>
9491 * </pre>
9492 */
9493 abstract class PolymerAttributeElement implements PolymerElement {
9494 /**
9495 * An empty array of Polymer custom tag attributes.
9496 */
9497 static final List<PolymerAttributeElement> EMPTY_ARRAY = new List<PolymerAttri buteElement>(0);
9498
9499 /**
9500 * Return the [FieldElement] associated with this attribute. Maybe `null` if
9501 * [PolymerTagDartElement] does not have a field associated with it.
9502 */
9503 FieldElement get field;
9504 }
9505
9506 /**
9507 * Implementation of `PolymerAttributeElement`.
9508 */
9509 class PolymerAttributeElementImpl extends PolymerElementImpl implements PolymerA ttributeElement {
9510 /**
9511 * The [FieldElement] associated with this attribute.
9512 */
9513 FieldElement field;
9514
9515 /**
9516 * Initialize a newly created Polymer attribute to have the given name.
9517 *
9518 * @param name the name of this element
9519 * @param nameOffset the offset of the name of this element in the file that c ontains the
9520 * declaration of this element
9521 */
9522 PolymerAttributeElementImpl(String name, int nameOffset) : super(name, nameOff set);
9523
9524 @override
9525 accept(ElementVisitor visitor) => visitor.visitPolymerAttributeElement(this);
9526
9527 @override
9528 ElementKind get kind => ElementKind.POLYMER_ATTRIBUTE;
9529 }
9530
9531 /**
9532 * The interface `PolymerElement` defines the behavior of objects representing i nformation
9533 * about a Polymer specific element.
9534 */
9535 abstract class PolymerElement implements ToolkitObjectElement {
9536 /**
9537 * An empty array of Polymer elements.
9538 */
9539 static final List<PolymerElement> EMPTY_ARRAY = new List<PolymerElement>(0);
9540 }
9541
9542 /**
9543 * Implementation of `PolymerElement`.
9544 */
9545 abstract class PolymerElementImpl extends ToolkitObjectElementImpl implements Po lymerElement {
9546 /**
9547 * Initialize a newly created Polymer element to have the given name.
9548 *
9549 * @param name the name of this element
9550 * @param nameOffset the offset of the name of this element in the file that c ontains the
9551 * declaration of this element
9552 */
9553 PolymerElementImpl(String name, int nameOffset) : super(name, nameOffset);
9554 }
9555
9556 /**
9557 * The interface `PolymerTagDartElement` defines a Polymer custom tag in Dart.
9558 *
9559 * <pre>
9560 * @CustomTag('my-example')
9561 * </pre>
9562 */
9563 abstract class PolymerTagDartElement implements PolymerElement {
9564 /**
9565 * Return the [ClassElement] that is associated with this Polymer custom tag. Not
9566 * `null`, because [PolymerTagDartElement]s are created for [ClassElement]s
9567 * marked with the `@CustomTag` annotation.
9568 */
9569 ClassElement get classElement;
9570
9571 /**
9572 * Return the [PolymerTagHtmlElement] part of this Polymer custom tag. Maybe ` null` if
9573 * it has not been resolved yet or there are no corresponding Dart part define d.
9574 */
9575 PolymerTagHtmlElement get htmlElement;
9576 }
9577
9578 /**
9579 * Implementation of `PolymerTagDartElement`.
9580 */
9581 class PolymerTagDartElementImpl extends PolymerElementImpl implements PolymerTag DartElement {
9582 /**
9583 * The [ClassElement] that is associated with this Polymer custom tag.
9584 */
9585 final ClassElement classElement;
9586
9587 /**
9588 * The [PolymerTagHtmlElement] part of this Polymer custom tag. Maybe `null` i f it has
9589 * not been resolved yet or there are no corresponding Dart part defined.
9590 */
9591 PolymerTagHtmlElement htmlElement;
9592
9593 /**
9594 * Initialize a newly created Dart part of a Polymer tag to have the given nam e.
9595 *
9596 * @param name the name of this element
9597 * @param nameOffset the offset of the name of this element in the file that c ontains the
9598 * declaration of this element
9599 */
9600 PolymerTagDartElementImpl(String name, int nameOffset, this.classElement) : su per(name, nameOffset);
9601
9602 @override
9603 accept(ElementVisitor visitor) => visitor.visitPolymerTagDartElement(this);
9604
9605 @override
9606 ElementKind get kind => ElementKind.POLYMER_TAG_DART;
9607 }
9608
9609 /**
9610 * The interface `PolymerTagHtmlElement` defines a Polymer custom tag in HTML.
9611 *
9612 * <pre>
9613 * <polymer-element name="my-example" attributes='attrA attrB'>
9614 * </polymer-element>
9615 * </pre>
9616 */
9617 abstract class PolymerTagHtmlElement implements PolymerElement {
9618 /**
9619 * An empty array of [PolymerTagHtmlElement]s.
9620 */
9621 static final List<PolymerTagHtmlElement> EMPTY_ARRAY = new List<PolymerTagHtml Element>(0);
9622
9623 /**
9624 * Return an array containing all of the attributes declared by this tag.
9625 */
9626 List<PolymerAttributeElement> get attributes;
9627
9628 /**
9629 * Return the [PolymerTagDartElement] part on this Polymer custom tag. Maybe ` null` if
9630 * it has not been resolved yet or there are no corresponding Dart part define d.
9631 */
9632 PolymerTagDartElement get dartElement;
9633 }
9634
9635 /**
9636 * Implementation of `PolymerTagHtmlElement`.
9637 */
9638 class PolymerTagHtmlElementImpl extends PolymerElementImpl implements PolymerTag HtmlElement {
9639 /**
9640 * The [PolymerTagDartElement] part of this Polymer custom tag. Maybe `null` i f it has
9641 * not been resolved yet or there are no corresponding Dart part defined.
9642 */
9643 PolymerTagDartElement dartElement;
9644
9645 /**
9646 * The array containing all of the attributes declared by this tag.
9647 */
9648 List<PolymerAttributeElement> _attributes = PolymerAttributeElement.EMPTY_ARRA Y;
9649
9650 /**
9651 * Initialize a newly created HTML part of a Polymer tag to have the given nam e.
9652 *
9653 * @param name the name of this element
9654 * @param nameOffset the offset of the name of this element in the file that c ontains the
9655 * declaration of this element
9656 */
9657 PolymerTagHtmlElementImpl(String name, int nameOffset) : super(name, nameOffse t);
9658
9659 @override
9660 accept(ElementVisitor visitor) => visitor.visitPolymerTagHtmlElement(this);
9661
9662 @override
9663 List<PolymerAttributeElement> get attributes => _attributes;
9664
9665 @override
9666 ElementKind get kind => ElementKind.POLYMER_TAG_HTML;
9667
9668 /**
9669 * Set an array containing all of the attributes declared by this tag.
9670 *
9671 * @param attributes the properties to set
9672 */
9673 void set attributes(List<PolymerAttributeElement> attributes) {
9674 for (PolymerAttributeElement property in attributes) {
9675 encloseElement(property as PolymerAttributeElementImpl);
9676 }
9677 this._attributes = attributes;
9678 }
9679
9680 @override
9681 void visitChildren(ElementVisitor visitor) {
9682 safelyVisitChildren(_attributes, visitor);
9683 super.visitChildren(visitor);
9684 }
9685 }
9686
9687 /**
9688 * The interface `PrefixElement` defines the behavior common to elements that re present a
9689 * prefix used to import one or more libraries into another library.
9690 */
9691 abstract class PrefixElement implements Element {
9692 /**
9693 * Return the library into which other libraries are imported using this prefi x.
9694 *
9695 * @return the library into which other libraries are imported using this pref ix
9696 */
9697 @override
9698 LibraryElement get enclosingElement;
9699
9700 /**
9701 * Return an array containing all of the libraries that are imported using thi s prefix.
9702 *
9703 * @return the libraries that are imported using this prefix
9704 */
9705 List<LibraryElement> get importedLibraries;
9706 }
9707
9708 /**
9709 * Instances of the class `PrefixElementImpl` implement a `PrefixElement`.
9710 */
9711 class PrefixElementImpl extends ElementImpl implements PrefixElement {
9712 /**
9713 * An array containing all of the libraries that are imported using this prefi x.
9714 */
9715 List<LibraryElement> _importedLibraries = LibraryElementImpl.EMPTY_ARRAY;
9716
9717 /**
9718 * An empty array of prefix elements.
9719 */
9720 static List<PrefixElement> EMPTY_ARRAY = new List<PrefixElement>(0);
9721
9722 /**
9723 * Initialize a newly created prefix element to have the given name.
9724 *
9725 * @param name the name of this element
9726 */
9727 PrefixElementImpl.forNode(Identifier name) : super.forNode(name);
9728
9729 /**
9730 * Initialize a newly created method element to have the given name.
9731 *
9732 * @param name the name of this element
9733 * @param nameOffset the offset of the name of this element in the file that c ontains the
9734 * declaration of this element
9735 */
9736 PrefixElementImpl(String name, int nameOffset) : super(name, nameOffset);
9737
9738 @override
9739 accept(ElementVisitor visitor) => visitor.visitPrefixElement(this);
9740
9741 @override
9742 LibraryElement get enclosingElement => super.enclosingElement as LibraryElemen t;
9743
9744 @override
9745 List<LibraryElement> get importedLibraries => _importedLibraries;
9746
9747 @override
9748 ElementKind get kind => ElementKind.PREFIX;
9749
9750 /**
9751 * Set the libraries that are imported using this prefix to the given librarie s.
9752 *
9753 * @param importedLibraries the libraries that are imported using this prefix
9754 */
9755 void set importedLibraries(List<LibraryElement> importedLibraries) {
9756 for (LibraryElement library in importedLibraries) {
9757 (library as LibraryElementImpl).enclosingElement = this;
9758 }
9759 this._importedLibraries = importedLibraries;
9760 }
9761
9762 @override
9763 void appendTo(JavaStringBuilder builder) {
9764 builder.append("as ");
9765 super.appendTo(builder);
9766 }
9767
9768 @override
9769 String get identifier => "_${super.identifier}";
9770 }
9771
9772 /**
9773 * The interface `PropertyAccessorElement` defines the behavior of elements repr esenting a
9774 * getter or a setter. Note that explicitly defined property accessors implicitl y define a synthetic
9775 * field. Symmetrically, synthetic accessors are implicitly created for explicit ly defined fields.
9776 * The following rules apply:
9777 * * Every explicit field is represented by a non-synthetic [FieldElement].
9778 * * Every explicit field induces a getter and possibly a setter, both of which are represented by
9779 * synthetic [PropertyAccessorElement]s.
9780 * * Every explicit getter or setter is represented by a non-synthetic
9781 * [PropertyAccessorElement].
9782 * * Every explicit getter or setter (or pair thereof if they have the same name ) induces a field
9783 * that is represented by a synthetic [FieldElement].
9784 */
9785 abstract class PropertyAccessorElement implements ExecutableElement {
9786 /**
9787 * Return the accessor representing the getter that corresponds to (has the sa me name as) this
9788 * setter, or `null` if this accessor is not a setter or if there is no corres ponding
9789 * getter.
9790 *
9791 * @return the getter that corresponds to this setter
9792 */
9793 PropertyAccessorElement get correspondingGetter;
9794
9795 /**
9796 * Return the accessor representing the setter that corresponds to (has the sa me name as) this
9797 * getter, or `null` if this accessor is not a getter or if there is no corres ponding
9798 * setter.
9799 *
9800 * @return the setter that corresponds to this getter
9801 */
9802 PropertyAccessorElement get correspondingSetter;
9803
9804 /**
9805 * Return the field or top-level variable associated with this accessor. If th is accessor was
9806 * explicitly defined (is not synthetic) then the variable associated with it will be synthetic.
9807 *
9808 * @return the variable associated with this accessor
9809 */
9810 PropertyInducingElement get variable;
9811
9812 /**
9813 * Return `true` if this accessor is abstract. Accessors are abstract if they are not
9814 * external and have no body.
9815 *
9816 * @return `true` if this accessor is abstract
9817 */
9818 bool get isAbstract;
9819
9820 /**
9821 * Return `true` if this accessor represents a getter.
9822 *
9823 * @return `true` if this accessor represents a getter
9824 */
9825 bool get isGetter;
9826
9827 /**
9828 * Return `true` if this accessor represents a setter.
9829 *
9830 * @return `true` if this accessor represents a setter
9831 */
9832 bool get isSetter;
9833 }
9834
9835 /**
9836 * Instances of the class `PropertyAccessorElementImpl` implement a
9837 * `PropertyAccessorElement`.
9838 */
9839 class PropertyAccessorElementImpl extends ExecutableElementImpl implements Prope rtyAccessorElement {
9840 /**
9841 * The variable associated with this accessor.
9842 */
9843 PropertyInducingElement variable;
9844
9845 /**
9846 * An empty array of property accessor elements.
9847 */
9848 static List<PropertyAccessorElement> EMPTY_ARRAY = new List<PropertyAccessorEl ement>(0);
9849
9850 /**
9851 * Initialize a newly created property accessor element to have the given name .
9852 *
9853 * @param name the name of this element
9854 */
9855 PropertyAccessorElementImpl.forNode(Identifier name) : super.forNode(name);
9856
9857 /**
9858 * Initialize a newly created synthetic property accessor element to be associ ated with the given
9859 * variable.
9860 *
9861 * @param variable the variable with which this access is associated
9862 */
9863 PropertyAccessorElementImpl.forVariable(PropertyInducingElementImpl variable) : super(variable.name, variable.nameOffset) {
9864 this.variable = variable;
9865 static = variable.isStatic;
9866 synthetic = true;
9867 }
9868
9869 @override
9870 accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
9871
9872 @override
9873 bool operator ==(Object object) => super == object && isGetter == (object as P ropertyAccessorElement).isGetter;
9874
9875 @override
9876 PropertyAccessorElement get correspondingGetter {
9877 if (isGetter || variable == null) {
9878 return null;
9879 }
9880 return variable.getter;
9881 }
9882
9883 @override
9884 PropertyAccessorElement get correspondingSetter {
9885 if (isSetter || variable == null) {
9886 return null;
9887 }
9888 return variable.setter;
9889 }
9890
9891 @override
9892 ElementKind get kind {
9893 if (isGetter) {
9894 return ElementKind.GETTER;
9895 }
9896 return ElementKind.SETTER;
9897 }
9898
9899 @override
9900 String get name {
9901 if (isSetter) {
9902 return "${super.name}=";
9903 }
9904 return super.name;
9905 }
9906
9907 @override
9908 AstNode get node {
9909 if (isSynthetic) {
9910 return null;
9911 }
9912 if (enclosingElement is ClassElement) {
9913 return getNodeMatching((node) => node is MethodDeclaration);
9914 }
9915 if (enclosingElement is CompilationUnitElement) {
9916 return getNodeMatching((node) => node is FunctionDeclaration);
9917 }
9918 return null;
9919 }
9920
9921 @override
9922 int get hashCode => ObjectUtilities.combineHashCodes(super.hashCode, isGetter ? 1 : 2);
9923
9924 @override
9925 bool get isAbstract => hasModifier(Modifier.ABSTRACT);
9926
9927 @override
9928 bool get isGetter => hasModifier(Modifier.GETTER);
9929
9930 @override
9931 bool get isSetter => hasModifier(Modifier.SETTER);
9932
9933 @override
9934 bool get isStatic => hasModifier(Modifier.STATIC);
9935
9936 /**
9937 * Set whether this accessor is abstract to correspond to the given value.
9938 *
9939 * @param isAbstract `true` if the accessor is abstract
9940 */
9941 void set abstract(bool isAbstract) {
9942 setModifier(Modifier.ABSTRACT, isAbstract);
9943 }
9944
9945 /**
9946 * Set whether this accessor is a getter to correspond to the given value.
9947 *
9948 * @param isGetter `true` if the accessor is a getter
9949 */
9950 void set getter(bool isGetter) {
9951 setModifier(Modifier.GETTER, isGetter);
9952 }
9953
9954 /**
9955 * Set whether this accessor is a setter to correspond to the given value.
9956 *
9957 * @param isSetter `true` if the accessor is a setter
9958 */
9959 void set setter(bool isSetter) {
9960 setModifier(Modifier.SETTER, isSetter);
9961 }
9962
9963 /**
9964 * Set whether this accessor is static to correspond to the given value.
9965 *
9966 * @param isStatic `true` if the accessor is static
9967 */
9968 void set static(bool isStatic) {
9969 setModifier(Modifier.STATIC, isStatic);
9970 }
9971
9972 @override
9973 void appendTo(JavaStringBuilder builder) {
9974 builder.append(isGetter ? "get " : "set ");
9975 builder.append(variable.displayName);
9976 super.appendTo(builder);
9977 }
9978
9979 @override
9980 String get identifier {
9981 String name = displayName;
9982 String suffix = isGetter ? "?" : "=";
9983 return "${name}${suffix}";
9984 }
9985 }
9986
9987 /**
9988 * Instances of the class `PropertyAccessorMember` represent a property accessor element
9989 * defined in a parameterized type where the values of the type parameters are k nown.
9990 */
9991 class PropertyAccessorMember extends ExecutableMember implements PropertyAccesso rElement {
9992 /**
9993 * If the given property accessor's type is different when any type parameters from the defining
9994 * type's declaration are replaced with the actual type arguments from the def ining type, create a
9995 * property accessor member representing the given property accessor. Return t he member that was
9996 * created, or the base accessor if no member was created.
9997 *
9998 * @param baseAccessor the base property accessor for which a member might be created
9999 * @param definingType the type defining the parameters and arguments to be us ed in the
10000 * substitution
10001 * @return the property accessor element that will return the correctly substi tuted types
10002 */
10003 static PropertyAccessorElement from(PropertyAccessorElement baseAccessor, Inte rfaceType definingType) {
10004 if (!_isChangedByTypeSubstitution(baseAccessor, definingType)) {
10005 return baseAccessor;
10006 }
10007 // TODO(brianwilkerson) Consider caching the substituted type in the instanc e. It would use more
10008 // memory but speed up some operations. We need to see how often the type is being re-computed.
10009 return new PropertyAccessorMember(baseAccessor, definingType);
10010 }
10011
10012 /**
10013 * Determine whether the given property accessor's type is changed when type p arameters from the
10014 * defining type's declaration are replaced with the actual type arguments fro m the defining type.
10015 *
10016 * @param baseAccessor the base property accessor
10017 * @param definingType the type defining the parameters and arguments to be us ed in the
10018 * substitution
10019 * @return true if the type is changed by type substitution.
10020 */
10021 static bool _isChangedByTypeSubstitution(PropertyAccessorElement baseAccessor, InterfaceType definingType) {
10022 List<DartType> argumentTypes = definingType.typeArguments;
10023 if (baseAccessor != null && argumentTypes.length != 0) {
10024 FunctionType baseType = baseAccessor.type;
10025 List<DartType> parameterTypes = definingType.element.type.typeArguments;
10026 FunctionType substitutedType = baseType.substitute2(argumentTypes, paramet erTypes);
10027 if (baseType != substitutedType) {
10028 return true;
10029 }
10030 // If this property accessor is based on a field, that field might have a propagated type.
10031 // In which case we need to check whether the propagated type of the field needs substitution.
10032 PropertyInducingElement field = baseAccessor.variable;
10033 if (!field.isSynthetic) {
10034 DartType baseFieldType = field.propagatedType;
10035 if (baseFieldType != null) {
10036 DartType substitutedFieldType = baseFieldType.substitute2(argumentType s, parameterTypes);
10037 if (baseFieldType != substitutedFieldType) {
10038 return true;
10039 }
10040 }
10041 }
10042 }
10043 return false;
10044 }
10045
10046 /**
10047 * Initialize a newly created element to represent a property accessor of the given parameterized
10048 * type.
10049 *
10050 * @param baseElement the element on which the parameterized element was creat ed
10051 * @param definingType the type in which the element is defined
10052 */
10053 PropertyAccessorMember(PropertyAccessorElement baseElement, InterfaceType defi ningType) : super(baseElement, definingType);
10054
10055 @override
10056 accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
10057
10058 @override
10059 PropertyAccessorElement get baseElement => super.baseElement as PropertyAccess orElement;
10060
10061 @override
10062 PropertyAccessorElement get correspondingGetter => from(baseElement.correspond ingGetter, definingType);
10063
10064 @override
10065 PropertyAccessorElement get correspondingSetter => from(baseElement.correspond ingSetter, definingType);
10066
10067 @override
10068 Element get enclosingElement => baseElement.enclosingElement;
10069
10070 @override
10071 PropertyInducingElement get variable {
10072 PropertyInducingElement variable = baseElement.variable;
10073 if (variable is FieldElement) {
10074 return FieldMember.from(variable, definingType);
10075 }
10076 return variable;
10077 }
10078
10079 @override
10080 bool get isAbstract => baseElement.isAbstract;
10081
10082 @override
10083 bool get isGetter => baseElement.isGetter;
10084
10085 @override
10086 bool get isSetter => baseElement.isSetter;
10087
10088 @override
10089 String toString() {
10090 PropertyAccessorElement baseElement = this.baseElement;
10091 List<ParameterElement> parameters = this.parameters;
10092 FunctionType type = this.type;
10093 JavaStringBuilder builder = new JavaStringBuilder();
10094 if (isGetter) {
10095 builder.append("get ");
10096 } else {
10097 builder.append("set ");
10098 }
10099 builder.append(baseElement.enclosingElement.displayName);
10100 builder.append(".");
10101 builder.append(baseElement.displayName);
10102 builder.append("(");
10103 int parameterCount = parameters.length;
10104 for (int i = 0; i < parameterCount; i++) {
10105 if (i > 0) {
10106 builder.append(", ");
10107 }
10108 builder.append(parameters[i]).toString();
10109 }
10110 builder.append(")");
10111 if (type != null) {
10112 builder.append(Element.RIGHT_ARROW);
10113 builder.append(type.returnType);
10114 }
10115 return builder.toString();
10116 }
10117
10118 @override
10119 InterfaceType get definingType => super.definingType as InterfaceType;
10120 }
10121
10122 /**
10123 * The interface `PropertyInducingElement` defines the behavior of elements repr esenting a
10124 * variable that has an associated getter and possibly a setter. Note that expli citly defined
10125 * variables implicitly define a synthetic getter and that non-`final` explicitl y defined
10126 * variables implicitly define a synthetic setter. Symmetrically, synthetic fiel ds are implicitly
10127 * created for explicitly defined getters and setters. The following rules apply :
10128 * * Every explicit variable is represented by a non-synthetic [PropertyInducing Element].
10129 * * Every explicit variable induces a getter and possibly a setter, both of whi ch are represented
10130 * by synthetic [PropertyAccessorElement]s.
10131 * * Every explicit getter or setter is represented by a non-synthetic
10132 * [PropertyAccessorElement].
10133 * * Every explicit getter or setter (or pair thereof if they have the same name ) induces a
10134 * variable that is represented by a synthetic [PropertyInducingElement].
10135 */
10136 abstract class PropertyInducingElement implements VariableElement {
10137 /**
10138 * Return the getter associated with this variable. If this variable was expli citly defined (is
10139 * not synthetic) then the getter associated with it will be synthetic.
10140 *
10141 * @return the getter associated with this variable
10142 */
10143 PropertyAccessorElement get getter;
10144
10145 /**
10146 * Return the propagated type of this variable, or `null` if type propagation has not been
10147 * performed, for example because the variable is not final.
10148 *
10149 * @return the propagated type of this variable
10150 */
10151 DartType get propagatedType;
10152
10153 /**
10154 * Return the setter associated with this variable, or `null` if the variable is effectively
10155 * `final` and therefore does not have a setter associated with it. (This can happen either
10156 * because the variable is explicitly defined as being `final` or because the variable is
10157 * induced by an explicit getter that does not have a corresponding setter.) I f this variable was
10158 * explicitly defined (is not synthetic) then the setter associated with it wi ll be synthetic.
10159 *
10160 * @return the setter associated with this variable
10161 */
10162 PropertyAccessorElement get setter;
10163
10164 /**
10165 * Return `true` if this element is a static element. A static element is an e lement that is
10166 * not associated with a particular instance, but rather with an entire librar y or class.
10167 *
10168 * @return `true` if this executable element is a static element
10169 */
10170 bool get isStatic;
10171 }
10172
10173 /**
10174 * Instances of the class `PropertyInducingElementImpl` implement a
10175 * `PropertyInducingElement`.
10176 */
10177 abstract class PropertyInducingElementImpl extends VariableElementImpl implement s PropertyInducingElement {
10178 /**
10179 * The getter associated with this element.
10180 */
10181 PropertyAccessorElement getter;
10182
10183 /**
10184 * The setter associated with this element, or `null` if the element is effect ively
10185 * `final` and therefore does not have a setter associated with it.
10186 */
10187 PropertyAccessorElement setter;
10188
10189 /**
10190 * The propagated type of this variable, or `null` if type propagation has not been
10191 * performed.
10192 */
10193 DartType propagatedType;
10194
10195 /**
10196 * An empty array of elements.
10197 */
10198 static List<PropertyInducingElement> EMPTY_ARRAY = new List<PropertyInducingEl ement>(0);
10199
10200 /**
10201 * Initialize a newly created element to have the given name.
10202 *
10203 * @param name the name of this element
10204 */
10205 PropertyInducingElementImpl.forNode(Identifier name) : super.forNode(name);
10206
10207 /**
10208 * Initialize a newly created synthetic element to have the given name.
10209 *
10210 * @param name the name of this element
10211 * @param nameOffset the offset of the name of this element in the file that c ontains the
10212 * declaration of this element
10213 */
10214 PropertyInducingElementImpl(String name, int nameOffset) : super(name, nameOff set);
10215 }
10216
10217 /**
10218 * Instances of the class `RecursiveElementVisitor` implement an element visitor that will
10219 * recursively visit all of the element in an element model. For example, using an instance of this
10220 * class to visit a [CompilationUnitElement] will also cause all of the types in the
10221 * compilation unit to be visited.
10222 *
10223 * Subclasses that override a visit method must either invoke the overridden vis it method or must
10224 * explicitly ask the visited element to visit its children. Failure to do so wi ll cause the
10225 * children of the visited element to not be visited.
10226 */
10227 class RecursiveElementVisitor<R> implements ElementVisitor<R> {
10228 @override
10229 R visitAngularComponentElement(AngularComponentElement element) {
10230 element.visitChildren(this);
10231 return null;
10232 }
10233
10234 @override
10235 R visitAngularControllerElement(AngularControllerElement element) {
10236 element.visitChildren(this);
10237 return null;
10238 }
10239
10240 @override
10241 R visitAngularDirectiveElement(AngularDecoratorElement element) {
10242 element.visitChildren(this);
10243 return null;
10244 }
10245
10246 @override
10247 R visitAngularFormatterElement(AngularFormatterElement element) {
10248 element.visitChildren(this);
10249 return null;
10250 }
10251
10252 @override
10253 R visitAngularPropertyElement(AngularPropertyElement element) {
10254 element.visitChildren(this);
10255 return null;
10256 }
10257
10258 @override
10259 R visitAngularScopePropertyElement(AngularScopePropertyElement element) {
10260 element.visitChildren(this);
10261 return null;
10262 }
10263
10264 @override
10265 R visitAngularSelectorElement(AngularSelectorElement element) {
10266 element.visitChildren(this);
10267 return null;
10268 }
10269
10270 @override
10271 R visitAngularViewElement(AngularViewElement element) {
10272 element.visitChildren(this);
10273 return null;
10274 }
10275
10276 @override
10277 R visitClassElement(ClassElement element) {
10278 element.visitChildren(this);
10279 return null;
10280 }
10281
10282 @override
10283 R visitCompilationUnitElement(CompilationUnitElement element) {
10284 element.visitChildren(this);
10285 return null;
10286 }
10287
10288 @override
10289 R visitConstructorElement(ConstructorElement element) {
10290 element.visitChildren(this);
10291 return null;
10292 }
10293
10294 @override
10295 R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) {
10296 element.visitChildren(this);
10297 return null;
10298 }
10299
10300 @override
10301 R visitExportElement(ExportElement element) {
10302 element.visitChildren(this);
10303 return null;
10304 }
10305
10306 @override
10307 R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) {
10308 element.visitChildren(this);
10309 return null;
10310 }
10311
10312 @override
10313 R visitFieldElement(FieldElement element) {
10314 element.visitChildren(this);
10315 return null;
10316 }
10317
10318 @override
10319 R visitFieldFormalParameterElement(FieldFormalParameterElement element) {
10320 element.visitChildren(this);
10321 return null;
10322 }
10323
10324 @override
10325 R visitFunctionElement(FunctionElement element) {
10326 element.visitChildren(this);
10327 return null;
10328 }
10329
10330 @override
10331 R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
10332 element.visitChildren(this);
10333 return null;
10334 }
10335
10336 @override
10337 R visitHtmlElement(HtmlElement element) {
10338 element.visitChildren(this);
10339 return null;
10340 }
10341
10342 @override
10343 R visitImportElement(ImportElement element) {
10344 element.visitChildren(this);
10345 return null;
10346 }
10347
10348 @override
10349 R visitLabelElement(LabelElement element) {
10350 element.visitChildren(this);
10351 return null;
10352 }
10353
10354 @override
10355 R visitLibraryElement(LibraryElement element) {
10356 element.visitChildren(this);
10357 return null;
10358 }
10359
10360 @override
10361 R visitLocalVariableElement(LocalVariableElement element) {
10362 element.visitChildren(this);
10363 return null;
10364 }
10365
10366 @override
10367 R visitMethodElement(MethodElement element) {
10368 element.visitChildren(this);
10369 return null;
10370 }
10371
10372 @override
10373 R visitMultiplyDefinedElement(MultiplyDefinedElement element) {
10374 element.visitChildren(this);
10375 return null;
10376 }
10377
10378 @override
10379 R visitParameterElement(ParameterElement element) {
10380 element.visitChildren(this);
10381 return null;
10382 }
10383
10384 @override
10385 R visitPolymerAttributeElement(PolymerAttributeElement element) {
10386 element.visitChildren(this);
10387 return null;
10388 }
10389
10390 @override
10391 R visitPolymerTagDartElement(PolymerTagDartElement element) {
10392 element.visitChildren(this);
10393 return null;
10394 }
10395
10396 @override
10397 R visitPolymerTagHtmlElement(PolymerTagHtmlElement element) {
10398 element.visitChildren(this);
10399 return null;
10400 }
10401
10402 @override
10403 R visitPrefixElement(PrefixElement element) {
10404 element.visitChildren(this);
10405 return null;
10406 }
10407
10408 @override
10409 R visitPropertyAccessorElement(PropertyAccessorElement element) {
10410 element.visitChildren(this);
10411 return null;
10412 }
10413
10414 @override
10415 R visitTopLevelVariableElement(TopLevelVariableElement element) {
10416 element.visitChildren(this);
10417 return null;
10418 }
10419
10420 @override
10421 R visitTypeParameterElement(TypeParameterElement element) {
10422 element.visitChildren(this);
10423 return null;
10424 }
10425 }
10426
10427 /**
10428 * The interface `ShowElementCombinator` defines the behavior of combinators tha t cause some
10429 * of the names in a namespace to be visible (and the rest hidden) when being im ported.
10430 */
10431 abstract class ShowElementCombinator implements NamespaceCombinator {
10432 /**
10433 * Return the offset of the character immediately following the last character of this node.
10434 *
10435 * @return the offset of the character just past this node
10436 */
10437 int get end;
10438
10439 /**
10440 * Return the offset of the 'show' keyword of this element.
10441 *
10442 * @return the offset of the 'show' keyword of this element
10443 */
10444 int get offset;
10445
10446 /**
10447 * Return an array containing the names that are to be made visible in the imp orting library if
10448 * they are defined in the imported library.
10449 *
10450 * @return the names from the imported library that are visible in the importi ng library
10451 */
10452 List<String> get shownNames;
10453 }
10454
10455 /**
10456 * Instances of the class `ShowElementCombinatorImpl` implement a
10457 * [ShowElementCombinator].
10458 */
10459 class ShowElementCombinatorImpl implements ShowElementCombinator {
10460 /**
10461 * The names that are to be made visible in the importing library if they are defined in the
10462 * imported library.
10463 */
10464 List<String> shownNames = StringUtilities.EMPTY_ARRAY;
10465
10466 /**
10467 * The offset of the character immediately following the last character of thi s node.
10468 */
10469 int end = -1;
10470
10471 /**
10472 * The offset of the 'show' keyword of this element.
10473 */
10474 int offset = 0;
10475
10476 @override
10477 String toString() {
10478 JavaStringBuilder builder = new JavaStringBuilder();
10479 builder.append("show ");
10480 int count = shownNames.length;
10481 for (int i = 0; i < count; i++) {
10482 if (i > 0) {
10483 builder.append(", ");
10484 }
10485 builder.append(shownNames[i]);
10486 }
10487 return builder.toString();
10488 }
10489 }
10490
10491 /**
10492 * Instances of the class `SimpleElementVisitor` implement an element visitor th at will do
10493 * nothing when visiting an element. It is intended to be a superclass for class es that use the
10494 * visitor pattern primarily as a dispatch mechanism (and hence don't need to re cursively visit a
10495 * whole structure) and that only need to visit a small number of element types.
10496 */
10497 class SimpleElementVisitor<R> implements ElementVisitor<R> {
10498 @override
10499 R visitAngularComponentElement(AngularComponentElement element) => null;
10500
10501 @override
10502 R visitAngularControllerElement(AngularControllerElement element) => null;
10503
10504 @override
10505 R visitAngularDirectiveElement(AngularDecoratorElement element) => null;
10506
10507 @override
10508 R visitAngularFormatterElement(AngularFormatterElement element) => null;
10509
10510 @override
10511 R visitAngularPropertyElement(AngularPropertyElement element) => null;
10512
10513 @override
10514 R visitAngularScopePropertyElement(AngularScopePropertyElement element) => nul l;
10515
10516 @override
10517 R visitAngularSelectorElement(AngularSelectorElement element) => null;
10518
10519 @override
10520 R visitAngularViewElement(AngularViewElement element) => null;
10521
10522 @override
10523 R visitClassElement(ClassElement element) => null;
10524
10525 @override
10526 R visitCompilationUnitElement(CompilationUnitElement element) => null;
10527
10528 @override
10529 R visitConstructorElement(ConstructorElement element) => null;
10530
10531 @override
10532 R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) => null;
10533
10534 @override
10535 R visitExportElement(ExportElement element) => null;
10536
10537 @override
10538 R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) => null;
10539
10540 @override
10541 R visitFieldElement(FieldElement element) => null;
10542
10543 @override
10544 R visitFieldFormalParameterElement(FieldFormalParameterElement element) => nul l;
10545
10546 @override
10547 R visitFunctionElement(FunctionElement element) => null;
10548
10549 @override
10550 R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) => null;
10551
10552 @override
10553 R visitHtmlElement(HtmlElement element) => null;
10554
10555 @override
10556 R visitImportElement(ImportElement element) => null;
10557
10558 @override
10559 R visitLabelElement(LabelElement element) => null;
10560
10561 @override
10562 R visitLibraryElement(LibraryElement element) => null;
10563
10564 @override
10565 R visitLocalVariableElement(LocalVariableElement element) => null;
10566
10567 @override
10568 R visitMethodElement(MethodElement element) => null;
10569
10570 @override
10571 R visitMultiplyDefinedElement(MultiplyDefinedElement element) => null;
10572
10573 @override
10574 R visitParameterElement(ParameterElement element) => null;
10575
10576 @override
10577 R visitPolymerAttributeElement(PolymerAttributeElement element) => null;
10578
10579 @override
10580 R visitPolymerTagDartElement(PolymerTagDartElement element) => null;
10581
10582 @override
10583 R visitPolymerTagHtmlElement(PolymerTagHtmlElement element) => null;
10584
10585 @override
10586 R visitPrefixElement(PrefixElement element) => null;
10587
10588 @override
10589 R visitPropertyAccessorElement(PropertyAccessorElement element) => null;
10590
10591 @override
10592 R visitTopLevelVariableElement(TopLevelVariableElement element) => null;
10593
10594 @override
10595 R visitTypeParameterElement(TypeParameterElement element) => null;
10596 }
10597
10598 /**
10599 * The interface `ToolkitObjectElement` defines the behavior of elements that re present a
10600 * toolkit specific object, such as Angular controller or component. These eleme nts are not based on
10601 * the Dart syntax, but on some semantic agreement, such as a special annotation .
10602 */
10603 abstract class ToolkitObjectElement implements Element {
10604 /**
10605 * An empty array of toolkit object elements.
10606 */
10607 static final List<ToolkitObjectElement> EMPTY_ARRAY = new List<ToolkitObjectEl ement>(0);
10608 }
10609
10610 /**
10611 * Instances of the class `ToolkitObjectElementImpl` implement a `ToolkitObjectE lement`.
10612 */
10613 abstract class ToolkitObjectElementImpl extends ElementImpl implements ToolkitOb jectElement {
10614 /**
10615 * Initialize a newly created toolkit object element to have the given name.
10616 *
10617 * @param name the name of this element
10618 * @param nameOffset the offset of the name of this element in the file that c ontains the
10619 * declaration of this element
10620 */
10621 ToolkitObjectElementImpl(String name, int nameOffset) : super(name, nameOffset );
10622 }
10623
10624 /**
10625 * The interface `TopLevelVariableElement` defines the behavior of elements repr esenting a
10626 * top-level variable.
10627 */
10628 abstract class TopLevelVariableElement implements PropertyInducingElement {
10629 }
10630
10631 /**
10632 * Instances of the class `TopLevelVariableElementImpl` implement a
10633 * `TopLevelVariableElement`.
10634 */
10635 class TopLevelVariableElementImpl extends PropertyInducingElementImpl implements TopLevelVariableElement {
10636 /**
10637 * An empty array of top-level variable elements.
10638 */
10639 static List<TopLevelVariableElement> EMPTY_ARRAY = new List<TopLevelVariableEl ement>(0);
10640
10641 /**
10642 * Initialize a newly created top-level variable element to have the given nam e.
10643 *
10644 * @param name the name of this element
10645 */
10646 TopLevelVariableElementImpl.forNode(Identifier name) : super.forNode(name);
10647
10648 /**
10649 * Initialize a newly created synthetic top-level variable element to have the given name.
10650 *
10651 * @param name the name of this element
10652 * @param nameOffset the offset of the name of this element in the file that c ontains the
10653 * declaration of this element
10654 */
10655 TopLevelVariableElementImpl(String name, int nameOffset) : super(name, nameOff set);
10656
10657 @override
10658 accept(ElementVisitor visitor) => visitor.visitTopLevelVariableElement(this);
10659
10660 @override
10661 ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
10662
10663 @override
10664 bool get isStatic => true;
10665 }
10666
10667 /**
10668 * The abstract class `TypeImpl` implements the behavior common to objects repre senting the
10669 * declared type of elements in the element model.
10670 */
10671 abstract class TypeImpl implements DartType {
10672 static bool equalArrays(List<DartType> typeArgs1, List<DartType> typeArgs2, Se t<ElementPair> visitedElementPairs) {
10673 if (typeArgs1.length != typeArgs2.length) {
10674 return false;
10675 }
10676 for (int i = 0; i < typeArgs1.length; i++) {
10677 if (!(typeArgs1[i] as TypeImpl).internalEquals(typeArgs2[i], visitedElemen tPairs)) {
10678 return false;
10679 }
10680 }
10681 return true;
10682 }
10683
10684 /**
10685 * Return an array containing the results of using the given argument types an d parameter types to
10686 * perform a substitution on all of the given types.
10687 *
10688 * @param types the types on which a substitution is to be performed
10689 * @param argumentTypes the argument types for the substitution
10690 * @param parameterTypes the parameter types for the substitution
10691 * @return the result of performing the substitution on each of the types
10692 */
10693 static List<DartType> substitute(List<DartType> types, List<DartType> argument Types, List<DartType> parameterTypes) {
10694 int length = types.length;
10695 if (length == 0) {
10696 return types;
10697 }
10698 List<DartType> newTypes = new List<DartType>(length);
10699 for (int i = 0; i < length; i++) {
10700 newTypes[i] = types[i].substitute2(argumentTypes, parameterTypes);
10701 }
10702 return newTypes;
10703 }
10704
10705 /**
10706 * The element representing the declaration of this type, or `null` if the typ e has not, or
10707 * cannot, be associated with an element.
10708 */
10709 final Element _element;
10710
10711 /**
10712 * The name of this type, or `null` if the type does not have a name.
10713 */
10714 final String name;
10715
10716 /**
10717 * An empty array of types.
10718 */
10719 static List<DartType> EMPTY_ARRAY = new List<DartType>(0);
10720
10721 /**
10722 * Initialize a newly created type to be declared by the given element and to have the given name.
10723 *
10724 * @param element the element representing the declaration of the type
10725 * @param name the name of the type
10726 */
10727 TypeImpl(this._element, this.name);
10728
10729 @override
10730 String get displayName => name;
10731
10732 @override
10733 Element get element => _element;
10734
10735 @override
10736 DartType getLeastUpperBound(DartType type) => null;
10737
10738 @override
10739 bool isAssignableTo(DartType type) => isAssignableTo2(type, new HashSet<TypeIm pl_TypePair>());
10740
10741 /**
10742 * Return `true` if this type is assignable to the given type. A type <i>T</i> may be
10743 * assigned to a type <i>S</i>, written <i>T</i> &hArr; <i>S</i>, iff either < i>T</i> <: <i>S</i>
10744 * or <i>S</i> <: <i>T</i> (Interface Types section of spec).
10745 *
10746 * The given set of pairs of types (T1, T2), where each pair indicates that we invoked this method
10747 * because we are in the process of answering the question of whether T1 is a subtype of T2, is
10748 * used to prevent infinite loops.
10749 *
10750 * @param type the type being compared with this type
10751 * @param visitedTypePairs the set of pairs of types used to prevent infinite loops
10752 * @return `true` if this type is assignable to the given type
10753 */
10754 bool isAssignableTo2(DartType type, Set<TypeImpl_TypePair> visitedTypePairs) = > isSubtypeOf2(type, visitedTypePairs) || (type as TypeImpl).isSubtypeOf2(this, visitedTypePairs);
10755
10756 @override
10757 bool get isBottom => false;
10758
10759 @override
10760 bool get isDartCoreFunction => false;
10761
10762 @override
10763 bool get isDynamic => false;
10764
10765 @override
10766 bool isMoreSpecificThan(DartType type) => isMoreSpecificThan2(type, false, new HashSet<TypeImpl_TypePair>());
10767
10768 /**
10769 * Return `true` if this type is more specific than the given type.
10770 *
10771 * The given set of pairs of types (T1, T2), where each pair indicates that we invoked this method
10772 * because we are in the process of answering the question of whether T1 is a subtype of T2, is
10773 * used to prevent infinite loops.
10774 *
10775 * @param type the type being compared with this type
10776 * @param withDynamic `true` if "dynamic" should be considered as a subtype of any type
10777 * @param visitedTypePairs the set of pairs of types used to prevent infinite loops
10778 * @return `true` if this type is more specific than the given type
10779 */
10780 bool isMoreSpecificThan2(DartType type, bool withDynamic, Set<TypeImpl_TypePai r> visitedTypePairs) {
10781 // If the visitedTypePairs already has the pair (this, type), return false
10782 TypeImpl_TypePair typePair = new TypeImpl_TypePair(this, type);
10783 if (!visitedTypePairs.add(typePair)) {
10784 return false;
10785 }
10786 bool result = internalIsMoreSpecificThan(type, withDynamic, visitedTypePairs );
10787 visitedTypePairs.remove(typePair);
10788 return result;
10789 }
10790
10791 @override
10792 bool get isObject => false;
10793
10794 @override
10795 bool isSubtypeOf(DartType type) => isSubtypeOf2(type, new HashSet<TypeImpl_Typ ePair>());
10796
10797 /**
10798 * Return `true` if this type is a subtype of the given type.
10799 *
10800 * The given set of pairs of types (T1, T2), where each pair indicates that we invoked this method
10801 * because we are in the process of answering the question of whether T1 is a subtype of T2, is
10802 * used to prevent infinite loops.
10803 *
10804 * @param type the type being compared with this type
10805 * @param visitedTypePairs the set of pairs of types used to prevent infinite loops
10806 * @return `true` if this type is a subtype of the given type
10807 */
10808 bool isSubtypeOf2(DartType type, Set<TypeImpl_TypePair> visitedTypePairs) {
10809 // If the visitedTypePairs already has the pair (this, type), return false
10810 TypeImpl_TypePair typePair = new TypeImpl_TypePair(this, type);
10811 if (!visitedTypePairs.add(typePair)) {
10812 return false;
10813 }
10814 bool result = internalIsSubtypeOf(type, visitedTypePairs);
10815 visitedTypePairs.remove(typePair);
10816 return result;
10817 }
10818
10819 @override
10820 bool isSupertypeOf(DartType type) => type.isSubtypeOf(this);
10821
10822 @override
10823 bool get isVoid => false;
10824
10825 @override
10826 String toString() {
10827 JavaStringBuilder builder = new JavaStringBuilder();
10828 appendTo(builder);
10829 return builder.toString();
10830 }
10831
10832 /**
10833 * Append a textual representation of this type to the given builder.
10834 *
10835 * @param builder the builder to which the text is to be appended
10836 */
10837 void appendTo(JavaStringBuilder builder) {
10838 if (name == null) {
10839 builder.append("<unnamed type>");
10840 } else {
10841 builder.append(name);
10842 }
10843 }
10844
10845 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs);
10846
10847 bool internalIsMoreSpecificThan(DartType type, bool withDynamic, Set<TypeImpl_ TypePair> visitedTypePairs);
10848
10849 bool internalIsSubtypeOf(DartType type, Set<TypeImpl_TypePair> visitedTypePair s);
10850 }
10851
10852 class TypeImpl_TypePair {
10853 final DartType _firstType;
10854
10855 final DartType _secondType;
10856
10857 int _cachedHashCode = 0;
10858
10859 TypeImpl_TypePair(this._firstType, this._secondType);
10860
10861 @override
10862 bool operator ==(Object object) {
10863 if (identical(object, this)) {
10864 return true;
10865 }
10866 if (object is TypeImpl_TypePair) {
10867 TypeImpl_TypePair typePair = object;
10868 return _firstType == typePair._firstType && _secondType != null && _second Type == typePair._secondType;
10869 }
10870 return false;
10871 }
10872
10873 @override
10874 int get hashCode {
10875 if (_cachedHashCode == 0) {
10876 int firstHashCode = 0;
10877 if (_firstType != null) {
10878 Element firstElement = _firstType.element;
10879 firstHashCode = firstElement == null ? 0 : firstElement.hashCode;
10880 }
10881 int secondHashCode = 0;
10882 if (_secondType != null) {
10883 Element secondElement = _secondType.element;
10884 secondHashCode = secondElement == null ? 0 : secondElement.hashCode;
10885 }
10886 _cachedHashCode = firstHashCode + secondHashCode;
10887 }
10888 return _cachedHashCode;
10889 }
10890 }
10891
10892 /**
10893 * The interface `TypeParameterElement` defines the behavior of elements represe nting a type
10894 * parameter.
10895 */
10896 abstract class TypeParameterElement implements Element {
10897 /**
10898 * Return the type representing the bound associated with this parameter, or ` null` if this
10899 * parameter does not have an explicit bound.
10900 *
10901 * @return the type representing the bound associated with this parameter
10902 */
10903 DartType get bound;
10904
10905 /**
10906 * Return the type defined by this type parameter.
10907 *
10908 * @return the type defined by this type parameter
10909 */
10910 TypeParameterType get type;
10911 }
10912
10913 /**
10914 * Instances of the class `TypeParameterElementImpl` implement a [TypeParameterE lement].
10915 */
10916 class TypeParameterElementImpl extends ElementImpl implements TypeParameterEleme nt {
10917 /**
10918 * The type defined by this type parameter.
10919 */
10920 TypeParameterType type;
10921
10922 /**
10923 * The type representing the bound associated with this parameter, or `null` i f this
10924 * parameter does not have an explicit bound.
10925 */
10926 DartType bound;
10927
10928 /**
10929 * An empty array of type parameter elements.
10930 */
10931 static List<TypeParameterElement> EMPTY_ARRAY = new List<TypeParameterElement> (0);
10932
10933 /**
10934 * Initialize a newly created type parameter element to have the given name.
10935 *
10936 * @param name the name of this element
10937 */
10938 TypeParameterElementImpl.forNode(Identifier name) : super.forNode(name);
10939
10940 /**
10941 * Initialize a newly created method element to have the given name.
10942 *
10943 * @param name the name of this element
10944 * @param nameOffset the offset of the name of this element in the file that c ontains the
10945 * declaration of this element
10946 */
10947 TypeParameterElementImpl(String name, int nameOffset) : super(name, nameOffset );
10948
10949 @override
10950 accept(ElementVisitor visitor) => visitor.visitTypeParameterElement(this);
10951
10952 @override
10953 ElementKind get kind => ElementKind.TYPE_PARAMETER;
10954
10955 @override
10956 void appendTo(JavaStringBuilder builder) {
10957 builder.append(displayName);
10958 if (bound != null) {
10959 builder.append(" extends ");
10960 builder.append(bound);
10961 }
10962 }
10963 }
10964
10965 /**
10966 * The interface `TypeParameterType` defines the behavior of objects representin g the type
10967 * introduced by a type parameter.
10968 */
10969 abstract class TypeParameterType implements DartType {
10970 @override
10971 TypeParameterElement get element;
10972 }
10973
10974 /**
10975 * Instances of the class `TypeParameterTypeImpl` defines the behavior of object s representing
10976 * the type introduced by a type parameter.
10977 */
10978 class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
10979 /**
10980 * An empty array of type parameter types.
10981 */
10982 static List<TypeParameterType> EMPTY_ARRAY = new List<TypeParameterType>(0);
10983
10984 /**
10985 * Return an array containing the type parameter types defined by the given ar ray of type
10986 * parameter elements.
10987 *
10988 * @param typeParameters the type parameter elements defining the type paramet er types to be
10989 * returned
10990 * @return the type parameter types defined by the type parameter elements
10991 */
10992 static List<TypeParameterType> getTypes(List<TypeParameterElement> typeParamet ers) {
10993 int count = typeParameters.length;
10994 if (count == 0) {
10995 return EMPTY_ARRAY;
10996 }
10997 List<TypeParameterType> types = new List<TypeParameterType>(count);
10998 for (int i = 0; i < count; i++) {
10999 types[i] = typeParameters[i].type;
11000 }
11001 return types;
11002 }
11003
11004 /**
11005 * Initialize a newly created type parameter type to be declared by the given element and to have
11006 * the given name.
11007 *
11008 * @param element the element representing the declaration of the type paramet er
11009 */
11010 TypeParameterTypeImpl(TypeParameterElement element) : super(element, element.n ame);
11011
11012 @override
11013 bool operator ==(Object object) => object is TypeParameterTypeImpl && (element == object.element);
11014
11015 @override
11016 TypeParameterElement get element => super.element as TypeParameterElement;
11017
11018 @override
11019 int get hashCode => element.hashCode;
11020
11021 @override
11022 DartType substitute2(List<DartType> argumentTypes, List<DartType> parameterTyp es) {
11023 int length = parameterTypes.length;
11024 for (int i = 0; i < length; i++) {
11025 if (parameterTypes[i] == this) {
11026 return argumentTypes[i];
11027 }
11028 }
11029 return this;
11030 }
11031
11032 @override
11033 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => th is == object;
11034
11035 @override
11036 bool internalIsMoreSpecificThan(DartType s, bool withDynamic, Set<TypeImpl_Typ ePair> visitedTypePairs) {
11037 //
11038 // A type T is more specific than a type S, written T << S, if one of the f ollowing conditions
11039 // is met:
11040 //
11041 // Reflexivity: T is S.
11042 //
11043 if (this == s) {
11044 return true;
11045 }
11046 // S is dynamic.
11047 //
11048 if (s.isDynamic) {
11049 return true;
11050 }
11051 return _isMoreSpecificThan(s, new HashSet<DartType>(), withDynamic, visitedT ypePairs);
11052 }
11053
11054 @override
11055 bool internalIsSubtypeOf(DartType type, Set<TypeImpl_TypePair> visitedTypePair s) => isMoreSpecificThan2(type, true, new HashSet<TypeImpl_TypePair>());
11056
11057 bool _isMoreSpecificThan(DartType s, Set<DartType> visitedTypes, bool withDyna mic, Set<TypeImpl_TypePair> visitedTypePairs) {
11058 //
11059 // T is a type parameter and S is the upper bound of T.
11060 //
11061 DartType bound = element.bound;
11062 if (s == bound) {
11063 return true;
11064 }
11065 //
11066 // T is a type parameter and S is Object.
11067 //
11068 if (s.isObject) {
11069 return true;
11070 }
11071 // We need upper bound to continue.
11072 if (bound == null) {
11073 return false;
11074 }
11075 //
11076 // Transitivity: T << U and U << S.
11077 //
11078 if (bound is TypeParameterTypeImpl) {
11079 TypeParameterTypeImpl boundTypeParameter = bound;
11080 // First check for infinite loops
11081 if (visitedTypes.contains(bound)) {
11082 return false;
11083 }
11084 visitedTypes.add(bound);
11085 // Then check upper bound.
11086 return boundTypeParameter._isMoreSpecificThan(s, visitedTypes, withDynamic , visitedTypePairs);
11087 }
11088 // Check interface type.
11089 return (bound as TypeImpl).isMoreSpecificThan2(s, withDynamic, visitedTypePa irs);
11090 }
11091 }
11092
11093 /**
11094 * The interface `UndefinedElement` defines the behavior of pseudo-elements that represent
11095 * names that are undefined. This situation is not allowed by the language, so o bjects implementing
11096 * this interface always represent an error. As a result, most of the normal ope rations on elements
11097 * do not make sense and will return useless results.
11098 */
11099 abstract class UndefinedElement implements Element {
11100 }
11101
11102 /**
11103 * A flat immutable union of `Type`s. Here "flat" means a union type never conta ins another
11104 * union type.
11105 */
11106 abstract class UnionType implements DartType {
11107 /**
11108 * @return an immutable view of the types in this union type.
11109 */
11110 Set<DartType> get elements;
11111 }
11112
11113 /**
11114 * In addition to the methods of the `UnionType` interface we add a factory meth od
11115 * `union` for building unions.
11116 */
11117 class UnionTypeImpl extends TypeImpl implements UnionType {
11118 /**
11119 * Any unions in the `types` will be flattened in the returned union. If there is only one
11120 * type after flattening then it will be returned directly, instead of a singl eton union.
11121 *
11122 * @param types the `Type`s to union
11123 * @return a `Type` comprising the `Type`s in `types`
11124 */
11125 static DartType union(List<DartType> types) {
11126 Set<DartType> set = new HashSet<DartType>();
11127 for (DartType t in types) {
11128 if (t is UnionType) {
11129 set.addAll(t.elements);
11130 } else {
11131 set.add(t);
11132 }
11133 }
11134 if (set.length == 0) {
11135 throw new IllegalArgumentException("No known use case for empty unions.");
11136 } else if (set.length == 1) {
11137 return new JavaIterator(set).next();
11138 } else {
11139 return new UnionTypeImpl(set);
11140 }
11141 }
11142
11143 /**
11144 * The types in this union.
11145 */
11146 final Set<DartType> _types;
11147
11148 /**
11149 * This constructor should only be called by the `union` factory: it does not check that its
11150 * argument `types` contains no union types.
11151 *
11152 * @param types
11153 */
11154 UnionTypeImpl(this._types) : super(null, null);
11155
11156 @override
11157 bool operator ==(Object other) {
11158 if (other == null || other is! UnionType) {
11159 return false;
11160 } else if (identical(this, other)) {
11161 return true;
11162 } else {
11163 return javaSetEquals(_types, (other as UnionType).elements);
11164 }
11165 }
11166
11167 @override
11168 String get displayName {
11169 JavaStringBuilder builder = new JavaStringBuilder();
11170 String prefix = "{";
11171 for (DartType t in _types) {
11172 builder.append(prefix);
11173 builder.append(t.displayName);
11174 prefix = ",";
11175 }
11176 builder.append("}");
11177 return builder.toString();
11178 }
11179
11180 @override
11181 Set<DartType> get elements => _types;
11182
11183 @override
11184 int get hashCode => _types.hashCode;
11185
11186 @override
11187 DartType substitute2(List<DartType> argumentTypes, List<DartType> parameterTyp es) {
11188 List<DartType> out = new List<DartType>();
11189 for (DartType t in _types) {
11190 out.add(t.substitute2(argumentTypes, parameterTypes));
11191 }
11192 return union(new List.from(out));
11193 }
11194
11195 @override
11196 void appendTo(JavaStringBuilder builder) {
11197 String prefix = "{";
11198 for (DartType t in _types) {
11199 builder.append(prefix);
11200 (t as TypeImpl).appendTo(builder);
11201 prefix = ",";
11202 }
11203 builder.append("}");
11204 }
11205
11206 @override
11207 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => th is == object;
11208
11209 @override
11210 bool internalIsMoreSpecificThan(DartType type, bool withDynamic, Set<TypeImpl_ TypePair> visitedTypePairs) {
11211 // TODO(collinsn): what version of subtyping do we want?
11212 //
11213 // The more unsound version: any.
11214 /*
11215 for (Type t : types) {
11216 if (((TypeImpl) t).internalIsMoreSpecificThan(type, withDynamic, visitedTy pePairs)) {
11217 return true;
11218 }
11219 }
11220 return false;
11221 */
11222 // The less unsound version: all.
11223 for (DartType t in _types) {
11224 if (!(t as TypeImpl).internalIsMoreSpecificThan(type, withDynamic, visited TypePairs)) {
11225 return false;
11226 }
11227 }
11228 return true;
11229 }
11230
11231 @override
11232 bool internalIsSubtypeOf(DartType type, Set<TypeImpl_TypePair> visitedTypePair s) {
11233 // TODO(collinsn): what version of subtyping do we want?
11234 //
11235 // The more unsound version: any.
11236 /*
11237 for (Type t : types) {
11238 if (((TypeImpl) t).internalIsSubtypeOf(type, visitedTypePairs)) {
11239 return true;
11240 }
11241 }
11242 return false;
11243 */
11244 // The less unsound version: all.
11245 for (DartType t in _types) {
11246 if (!(t as TypeImpl).internalIsSubtypeOf(type, visitedTypePairs)) {
11247 return false;
11248 }
11249 }
11250 return true;
11251 }
11252
11253 /**
11254 * The more-specific-than test for union types on the RHS is uniform in non-un ion LHSs. So, other
11255 * `TypeImpl`s can call this method to implement `internalIsMoreSpecificThan` for
11256 * union types.
11257 *
11258 * @param type
11259 * @param visitedTypePairs
11260 * @return true if `type` is more specific than this union type
11261 */
11262 bool internalUnionTypeIsMoreSpecificThan(DartType type, bool withDynamic, Set< TypeImpl_TypePair> visitedTypePairs) {
11263 // This implementation does not make sense when [type] is a union type, at l east
11264 // for the "less unsound" version of [internalIsMoreSpecificThan] above.
11265 if (type is UnionType) {
11266 throw new IllegalArgumentException("Only non-union types are supported.");
11267 }
11268 for (DartType t in _types) {
11269 if ((type as TypeImpl).internalIsMoreSpecificThan(t, withDynamic, visitedT ypePairs)) {
11270 return true;
11271 }
11272 }
11273 return false;
11274 }
11275
11276 /**
11277 * The supertype test for union types is uniform in non-union subtypes. So, ot her `TypeImpl`
11278 * s can call this method to implement `internalIsSubtypeOf` for union types.
11279 *
11280 * @param type
11281 * @param visitedTypePairs
11282 * @return true if this union type is a super type of `type`
11283 */
11284 bool internalUnionTypeIsSuperTypeOf(DartType type, Set<TypeImpl_TypePair> visi tedTypePairs) {
11285 // This implementation does not make sense when [type] is a union type, at l east
11286 // for the "less unsound" version of [internalIsSubtypeOf] above.
11287 if (type is UnionType) {
11288 throw new IllegalArgumentException("Only non-union types are supported.");
11289 }
11290 for (DartType t in _types) {
11291 if ((type as TypeImpl).internalIsSubtypeOf(t, visitedTypePairs)) {
11292 return true;
11293 }
11294 }
11295 return false;
11296 }
11297 }
11298
11299 /**
11300 * The interface `UriReferencedElement` defines the behavior of objects included into a
11301 * library using some URI.
11302 */
11303 abstract class UriReferencedElement implements Element {
11304 /**
11305 * Return the offset of the character immediately following the last character of this node's URI,
11306 * or `-1` for synthetic import.
11307 *
11308 * @return the offset of the character just past the node's URI
11309 */
11310 int get uriEnd;
11311
11312 /**
11313 * Return the offset of the URI in the file, or `-1` if this element is synthe tic.
11314 *
11315 * @return the offset of the URI
11316 */
11317 int get uriOffset;
11318
11319 /**
11320 * Return the URI that is used to include this element into the enclosing libr ary, or `null`
11321 * if this is the defining compilation unit of a library.
11322 *
11323 * @return the URI that is used to include this element into the enclosing lib rary
11324 */
11325 String get uri;
11326 }
11327
11328 /**
11329 * Instances of the class `UriReferencedElementImpl` implement an [UriReferenced Element]
11330 * .
11331 */
11332 abstract class UriReferencedElementImpl extends ElementImpl implements UriRefere ncedElement {
11333 /**
11334 * The offset of the URI in the file, may be `-1` if synthetic.
11335 */
11336 int uriOffset = -1;
11337
11338 /**
11339 * The offset of the character immediately following the last character of thi s node's URI, may be
11340 * `-1` if synthetic.
11341 */
11342 int uriEnd = -1;
11343
11344 /**
11345 * The URI that is specified by this directive.
11346 */
11347 String uri;
11348
11349 /**
11350 * Initialize a newly created import element.
11351 *
11352 * @param name the name of this element
11353 * @param offset the directive offset, may be `-1` if synthetic.
11354 */
11355 UriReferencedElementImpl(String name, int offset) : super(name, offset);
11356 }
11357
11358 /**
11359 * The interface `VariableElement` defines the behavior common to elements that represent a
11360 * variable.
11361 */
11362 abstract class VariableElement implements Element {
11363 /**
11364 * Return a synthetic function representing this variable's initializer, or `n ull` if this
11365 * variable does not have an initializer. The function will have no parameters . The return type of
11366 * the function will be the compile-time type of the initialization expression .
11367 *
11368 * @return a synthetic function representing this variable's initializer
11369 */
11370 FunctionElement get initializer;
11371
11372 /**
11373 * Return the resolved [VariableDeclaration] node that declares this [Variable Element]
11374 * .
11375 *
11376 * This method is expensive, because resolved AST might be evicted from cache, so parsing and
11377 * resolving will be performed.
11378 *
11379 * @return the resolved [VariableDeclaration], not `null`.
11380 */
11381 @override
11382 VariableDeclaration get node;
11383
11384 /**
11385 * Return the declared type of this variable, or `null` if the variable did no t have a
11386 * declared type (such as if it was declared using the keyword 'var').
11387 *
11388 * @return the declared type of this variable
11389 */
11390 DartType get type;
11391
11392 /**
11393 * Return `true` if this variable was declared with the 'const' modifier.
11394 *
11395 * @return `true` if this variable was declared with the 'const' modifier
11396 */
11397 bool get isConst;
11398
11399 /**
11400 * Return `true` if this variable was declared with the 'final' modifier. Vari ables that are
11401 * declared with the 'const' modifier will return `false` even though they are implicitly
11402 * final.
11403 *
11404 * @return `true` if this variable was declared with the 'final' modifier
11405 */
11406 bool get isFinal;
11407 }
11408
11409 /**
11410 * Instances of the class `VariableElementImpl` implement a `VariableElement`.
11411 */
11412 abstract class VariableElementImpl extends ElementImpl implements VariableElemen t {
11413 /**
11414 * The declared type of this variable.
11415 */
11416 DartType type;
11417
11418 /**
11419 * A synthetic function representing this variable's initializer, or `null` if this variable
11420 * does not have an initializer.
11421 */
11422 FunctionElement _initializer;
11423
11424 /**
11425 * An empty array of variable elements.
11426 */
11427 static List<VariableElement> EMPTY_ARRAY = new List<VariableElement>(0);
11428
11429 /**
11430 * Initialize a newly created variable element to have the given name.
11431 *
11432 * @param name the name of this element
11433 */
11434 VariableElementImpl.forNode(Identifier name) : super.forNode(name);
11435
11436 /**
11437 * Initialize a newly created variable element to have the given name.
11438 *
11439 * @param name the name of this element
11440 * @param nameOffset the offset of the name of this element in the file that c ontains the
11441 * declaration of this element
11442 */
11443 VariableElementImpl(String name, int nameOffset) : super(name, nameOffset);
11444
11445 /**
11446 * Return the result of evaluating this variable's initializer as a compile-ti me constant
11447 * expression, or `null` if this variable is not a 'const' variable, if it doe s not have an
11448 * initializer, or if the compilation unit containing the variable has not bee n resolved.
11449 *
11450 * @return the result of evaluating this variable's initializer
11451 */
11452 EvaluationResultImpl get evaluationResult => null;
11453
11454 @override
11455 FunctionElement get initializer => _initializer;
11456
11457 @override
11458 VariableDeclaration get node => getNodeMatching((node) => node is VariableDecl aration);
11459
11460 @override
11461 bool get isConst => hasModifier(Modifier.CONST);
11462
11463 @override
11464 bool get isFinal => hasModifier(Modifier.FINAL);
11465
11466 /**
11467 * Return `true` if this variable is potentially mutated somewhere in a closur e. This
11468 * information is only available for local variables (including parameters) an d only after the
11469 * compilation unit containing the variable has been resolved.
11470 *
11471 * @return `true` if this variable is potentially mutated somewhere in closure
11472 */
11473 bool get isPotentiallyMutatedInClosure => false;
11474
11475 /**
11476 * Return `true` if this variable is potentially mutated somewhere in its scop e. This
11477 * information is only available for local variables (including parameters) an d only after the
11478 * compilation unit containing the variable has been resolved.
11479 *
11480 * @return `true` if this variable is potentially mutated somewhere in its sco pe
11481 */
11482 bool get isPotentiallyMutatedInScope => false;
11483
11484 /**
11485 * Set whether this variable is const to correspond to the given value.
11486 *
11487 * @param isConst `true` if the variable is const
11488 */
11489 void set const3(bool isConst) {
11490 setModifier(Modifier.CONST, isConst);
11491 }
11492
11493 /**
11494 * Set the result of evaluating this variable's initializer as a compile-time constant expression
11495 * to the given result.
11496 *
11497 * @param result the result of evaluating this variable's initializer
11498 */
11499 void set evaluationResult(EvaluationResultImpl result) {
11500 throw new IllegalStateException("Invalid attempt to set a compile-time const ant result");
11501 }
11502
11503 /**
11504 * Set whether this variable is final to correspond to the given value.
11505 *
11506 * @param isFinal `true` if the variable is final
11507 */
11508 void set final2(bool isFinal) {
11509 setModifier(Modifier.FINAL, isFinal);
11510 }
11511
11512 /**
11513 * Set the function representing this variable's initializer to the given func tion.
11514 *
11515 * @param initializer the function representing this variable's initializer
11516 */
11517 void set initializer(FunctionElement initializer) {
11518 if (initializer != null) {
11519 (initializer as FunctionElementImpl).enclosingElement = this;
11520 }
11521 this._initializer = initializer;
11522 }
11523
11524 @override
11525 void visitChildren(ElementVisitor visitor) {
11526 super.visitChildren(visitor);
11527 safelyVisitChild(_initializer, visitor);
11528 }
11529
11530 @override
11531 void appendTo(JavaStringBuilder builder) {
11532 builder.append(type);
11533 builder.append(" ");
11534 builder.append(displayName);
11535 }
11536 }
11537
11538 /**
11539 * The abstract class `VariableMember` defines the behavior common to members th at represent a
11540 * variable element defined in a parameterized type where the values of the type parameters are
11541 * known.
11542 */
11543 abstract class VariableMember extends Member implements VariableElement {
11544 /**
11545 * Initialize a newly created element to represent an executable element of th e given
11546 * parameterized type.
11547 *
11548 * @param baseElement the element on which the parameterized element was creat ed
11549 * @param definingType the type in which the element is defined
11550 */
11551 VariableMember(VariableElement baseElement, ParameterizedType definingType) : super(baseElement, definingType);
11552
11553 @override
11554 VariableElement get baseElement => super.baseElement as VariableElement;
11555
11556 @override
11557 FunctionElement get initializer {
11558 //
11559 // Elements within this element should have type parameters substituted, jus t like this element.
11560 //
11561 throw new UnsupportedOperationException();
11562 }
11563
11564 @override
11565 VariableDeclaration get node => baseElement.node;
11566
11567 @override
11568 DartType get type => substituteFor(baseElement.type);
11569
11570 @override
11571 bool get isConst => baseElement.isConst;
11572
11573 @override
11574 bool get isFinal => baseElement.isFinal;
11575
11576 @override
11577 void visitChildren(ElementVisitor visitor) {
11578 // TODO(brianwilkerson) We need to finish implementing the accessors used be low so that we can
11579 // safely invoke them.
11580 super.visitChildren(visitor);
11581 safelyVisitChild(baseElement.initializer, visitor);
11582 }
11583 }
11584
11585 /**
11586 * The interface `VoidType` defines the behavior of the unique object representi ng the type
11587 * `void`.
11588 */
11589 abstract class VoidType implements DartType {
11590 @override
11591 VoidType substitute2(List<DartType> argumentTypes, List<DartType> parameterTyp es);
11592 }
11593
11594 /**
11595 * The unique instance of the class `VoidTypeImpl` implements the type `void`.
11596 */
11597 class VoidTypeImpl extends TypeImpl implements VoidType {
11598 /**
11599 * The unique instance of this class.
11600 */
11601 static VoidTypeImpl _INSTANCE = new VoidTypeImpl();
11602
11603 /**
11604 * Return the unique instance of this class.
11605 *
11606 * @return the unique instance of this class
11607 */
11608 static VoidTypeImpl get instance => _INSTANCE;
11609
11610 /**
11611 * Prevent the creation of instances of this class.
11612 */
11613 VoidTypeImpl() : super(null, Keyword.VOID.syntax);
11614
11615 @override
11616 bool operator ==(Object object) => identical(object, this);
11617
11618 @override
11619 int get hashCode => 2;
11620
11621 @override
11622 bool get isVoid => true;
11623
11624 @override
11625 VoidTypeImpl substitute2(List<DartType> argumentTypes, List<DartType> paramete rTypes) => this;
11626
11627 @override
11628 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => id entical(object, this);
11629
11630 @override
11631 bool internalIsMoreSpecificThan(DartType type, bool withDynamic, Set<TypeImpl_ TypePair> visitedTypePairs) => isSubtypeOf(type);
11632
11633 @override
11634 bool internalIsSubtypeOf(DartType type, Set<TypeImpl_TypePair> visitedTypePair s) {
11635 if (type is UnionType) {
11636 return (type as UnionTypeImpl).internalUnionTypeIsSuperTypeOf(this, visite dTypePairs);
11637 }
11638 // The only subtype relations that pertain to void are therefore:
11639 // void <: void (by reflexivity)
11640 // bottom <: void (as bottom is a subtype of all types).
11641 // void <: dynamic (as dynamic is a supertype of all types)
11642 return identical(type, this) || identical(type, DynamicTypeImpl.instance);
11643 }
11644 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698