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

Side by Side Diff: packages/analyzer/lib/src/dart/element/element.dart

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 4 months 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
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 library analyzer.src.dart.element.element;
6
7 import 'dart:collection';
8 import 'dart:math' show min;
9
10 import 'package:analyzer/dart/ast/ast.dart';
11 import 'package:analyzer/dart/ast/token.dart';
12 import 'package:analyzer/dart/constant/value.dart';
13 import 'package:analyzer/dart/element/element.dart';
14 import 'package:analyzer/dart/element/type.dart';
15 import 'package:analyzer/dart/element/visitor.dart';
16 import 'package:analyzer/src/dart/ast/utilities.dart';
17 import 'package:analyzer/src/dart/constant/value.dart';
18 import 'package:analyzer/src/dart/element/handle.dart';
19 import 'package:analyzer/src/dart/element/type.dart';
20 import 'package:analyzer/src/error/codes.dart' show CompileTimeErrorCode;
21 import 'package:analyzer/src/generated/constant.dart' show EvaluationResultImpl;
22 import 'package:analyzer/src/generated/engine.dart'
23 show AnalysisContext, AnalysisEngine;
24 import 'package:analyzer/src/generated/java_engine.dart';
25 import 'package:analyzer/src/generated/resolver.dart';
26 import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
27 import 'package:analyzer/src/generated/source.dart';
28 import 'package:analyzer/src/generated/testing/ast_factory.dart';
29 import 'package:analyzer/src/generated/utilities_collection.dart';
30 import 'package:analyzer/src/generated/utilities_dart.dart';
31 import 'package:analyzer/src/generated/utilities_general.dart';
32 import 'package:analyzer/src/summary/idl.dart';
33 import 'package:analyzer/src/task/dart.dart';
34
35 /**
36 * A concrete implementation of a [ClassElement].
37 */
38 abstract class AbstractClassElementImpl extends ElementImpl
39 implements ClassElement {
40 /**
41 * A list containing all of the accessors (getters and setters) contained in
42 * this class.
43 */
44 List<PropertyAccessorElement> _accessors;
45
46 /**
47 * A list containing all of the fields contained in this class.
48 */
49 List<FieldElement> _fields;
50
51 /**
52 * Initialize a newly created class element to have the given [name] at the
53 * given [offset] in the file that contains the declaration of this element.
54 */
55 AbstractClassElementImpl(String name, int offset) : super(name, offset);
56
57 /**
58 * Initialize a newly created class element to have the given [name].
59 */
60 AbstractClassElementImpl.forNode(Identifier name) : super.forNode(name);
61
62 /**
63 * Initialize using the given serialized information.
64 */
65 AbstractClassElementImpl.forSerialized(
66 CompilationUnitElementImpl enclosingUnit)
67 : super.forSerialized(enclosingUnit);
68
69 @override
70 List<PropertyAccessorElement> get accessors {
71 return _accessors ?? const <PropertyAccessorElement>[];
72 }
73
74 /**
75 * Set the accessors contained in this class to the given [accessors].
76 */
77 void set accessors(List<PropertyAccessorElement> accessors) {
78 for (PropertyAccessorElement accessor in accessors) {
79 (accessor as PropertyAccessorElementImpl).enclosingElement = this;
80 }
81 this._accessors = accessors;
82 }
83
84 @override
85 String get displayName => name;
86
87 @override
88 List<FieldElement> get fields => _fields ?? const <FieldElement>[];
89
90 /**
91 * Set the fields contained in this class to the given [fields].
92 */
93 void set fields(List<FieldElement> fields) {
94 for (FieldElement field in fields) {
95 (field as FieldElementImpl).enclosingElement = this;
96 }
97 this._fields = fields;
98 }
99
100 @override
101 bool get isEnum;
102
103 @override
104 ElementKind get kind => ElementKind.CLASS;
105
106 @override
107 accept(ElementVisitor visitor) => visitor.visitClassElement(this);
108
109 @override
110 NamedCompilationUnitMember computeNode() {
111 if (isEnum) {
112 return getNodeMatching((node) => node is EnumDeclaration);
113 } else {
114 return getNodeMatching(
115 (node) => node is ClassDeclaration || node is ClassTypeAlias);
116 }
117 }
118
119 @override
120 ElementImpl getChild(String identifier) {
121 //
122 // The casts in this method are safe because the set methods would have
123 // thrown a CCE if any of the elements in the arrays were not of the
124 // expected types.
125 //
126 for (PropertyAccessorElement accessor in accessors) {
127 PropertyAccessorElementImpl accessorImpl = accessor;
128 if (accessorImpl.identifier == identifier) {
129 return accessorImpl;
130 }
131 }
132 for (FieldElement field in fields) {
133 FieldElementImpl fieldImpl = field;
134 if (fieldImpl.identifier == identifier) {
135 return fieldImpl;
136 }
137 }
138 return null;
139 }
140
141 @override
142 FieldElement getField(String name) {
143 for (FieldElement fieldElement in fields) {
144 if (name == fieldElement.name) {
145 return fieldElement;
146 }
147 }
148 return null;
149 }
150
151 @override
152 PropertyAccessorElement getGetter(String getterName) {
153 int length = accessors.length;
154 for (int i = 0; i < length; i++) {
155 PropertyAccessorElement accessor = accessors[i];
156 if (accessor.isGetter && accessor.name == getterName) {
157 return accessor;
158 }
159 }
160 return null;
161 }
162
163 @override
164 PropertyAccessorElement getSetter(String setterName) {
165 // TODO (jwren) revisit- should we append '=' here or require clients to
166 // include it?
167 // Do we need the check for isSetter below?
168 if (!StringUtilities.endsWithChar(setterName, 0x3D)) {
169 setterName += '=';
170 }
171 for (PropertyAccessorElement accessor in accessors) {
172 if (accessor.isSetter && accessor.name == setterName) {
173 return accessor;
174 }
175 }
176 return null;
177 }
178
179 @override
180 MethodElement lookUpConcreteMethod(
181 String methodName, LibraryElement library) =>
182 _internalLookUpConcreteMethod(
183 methodName, library, true, new HashSet<ClassElement>());
184
185 @override
186 PropertyAccessorElement lookUpGetter(
187 String getterName, LibraryElement library) =>
188 _internalLookUpGetter(getterName, library, true);
189
190 @override
191 PropertyAccessorElement lookUpInheritedConcreteGetter(
192 String getterName, LibraryElement library) =>
193 _internalLookUpConcreteGetter(getterName, library, false);
194
195 @override
196 MethodElement lookUpInheritedConcreteMethod(
197 String methodName, LibraryElement library) =>
198 _internalLookUpConcreteMethod(
199 methodName, library, false, new HashSet<ClassElement>());
200
201 @override
202 PropertyAccessorElement lookUpInheritedConcreteSetter(
203 String setterName, LibraryElement library) =>
204 _internalLookUpConcreteSetter(setterName, library, false);
205
206 @override
207 MethodElement lookUpInheritedMethod(
208 String methodName, LibraryElement library) =>
209 _internalLookUpMethod(
210 methodName, library, false, new HashSet<ClassElement>());
211
212 @override
213 MethodElement lookUpMethod(String methodName, LibraryElement library) =>
214 _internalLookUpMethod(
215 methodName, library, true, new HashSet<ClassElement>());
216
217 @override
218 PropertyAccessorElement lookUpSetter(
219 String setterName, LibraryElement library) =>
220 _internalLookUpSetter(setterName, library, true);
221
222 @override
223 void visitChildren(ElementVisitor visitor) {
224 super.visitChildren(visitor);
225 safelyVisitChildren(accessors, visitor);
226 safelyVisitChildren(fields, visitor);
227 }
228
229 PropertyAccessorElement _internalLookUpConcreteGetter(
230 String getterName, LibraryElement library, bool includeThisClass) {
231 PropertyAccessorElement getter =
232 _internalLookUpGetter(getterName, library, includeThisClass);
233 while (getter != null && getter.isAbstract) {
234 Element definingClass = getter.enclosingElement;
235 if (definingClass is! ClassElement) {
236 return null;
237 }
238 getter = getImpl(definingClass)
239 ._internalLookUpGetter(getterName, library, false);
240 }
241 return getter;
242 }
243
244 MethodElement _internalLookUpConcreteMethod(
245 String methodName,
246 LibraryElement library,
247 bool includeThisClass,
248 HashSet<ClassElement> visitedClasses) {
249 MethodElement method = _internalLookUpMethod(
250 methodName, library, includeThisClass, visitedClasses);
251 while (method != null && method.isAbstract) {
252 ClassElement definingClass = method.enclosingElement;
253 if (definingClass == null) {
254 return null;
255 }
256 method = getImpl(definingClass)
257 ._internalLookUpMethod(methodName, library, false, visitedClasses);
258 }
259 return method;
260 }
261
262 PropertyAccessorElement _internalLookUpConcreteSetter(
263 String setterName, LibraryElement library, bool includeThisClass) {
264 PropertyAccessorElement setter =
265 _internalLookUpSetter(setterName, library, includeThisClass);
266 while (setter != null && setter.isAbstract) {
267 Element definingClass = setter.enclosingElement;
268 if (definingClass is ClassElementImpl) {
269 setter =
270 definingClass._internalLookUpSetter(setterName, library, false);
271 } else {
272 return null;
273 }
274 }
275 return setter;
276 }
277
278 PropertyAccessorElement _internalLookUpGetter(
279 String getterName, LibraryElement library, bool includeThisClass) {
280 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
281 ClassElement currentElement = this;
282 if (includeThisClass) {
283 PropertyAccessorElement element = currentElement.getGetter(getterName);
284 if (element != null && element.isAccessibleIn(library)) {
285 return element;
286 }
287 }
288 while (currentElement != null && visitedClasses.add(currentElement)) {
289 for (InterfaceType mixin in currentElement.mixins.reversed) {
290 ClassElement mixinElement = mixin.element;
291 if (mixinElement != null) {
292 PropertyAccessorElement element = mixinElement.getGetter(getterName);
293 if (element != null && element.isAccessibleIn(library)) {
294 return element;
295 }
296 }
297 }
298 InterfaceType supertype = currentElement.supertype;
299 if (supertype == null) {
300 return null;
301 }
302 currentElement = supertype.element;
303 PropertyAccessorElement element = currentElement.getGetter(getterName);
304 if (element != null && element.isAccessibleIn(library)) {
305 return element;
306 }
307 }
308 return null;
309 }
310
311 MethodElement _internalLookUpMethod(String methodName, LibraryElement library,
312 bool includeThisClass, HashSet<ClassElement> visitedClasses) {
313 ClassElement currentElement = this;
314 if (includeThisClass) {
315 MethodElement element = currentElement.getMethod(methodName);
316 if (element != null && element.isAccessibleIn(library)) {
317 return element;
318 }
319 }
320 while (currentElement != null && visitedClasses.add(currentElement)) {
321 for (InterfaceType mixin in currentElement.mixins.reversed) {
322 ClassElement mixinElement = mixin.element;
323 if (mixinElement != null) {
324 MethodElement element = mixinElement.getMethod(methodName);
325 if (element != null && element.isAccessibleIn(library)) {
326 return element;
327 }
328 }
329 }
330 InterfaceType supertype = currentElement.supertype;
331 if (supertype == null) {
332 return null;
333 }
334 currentElement = supertype.element;
335 MethodElement element = currentElement.getMethod(methodName);
336 if (element != null && element.isAccessibleIn(library)) {
337 return element;
338 }
339 }
340 return null;
341 }
342
343 PropertyAccessorElement _internalLookUpSetter(
344 String setterName, LibraryElement library, bool includeThisClass) {
345 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
346 ClassElement currentElement = this;
347 if (includeThisClass) {
348 PropertyAccessorElement element = currentElement.getSetter(setterName);
349 if (element != null && element.isAccessibleIn(library)) {
350 return element;
351 }
352 }
353 while (currentElement != null && visitedClasses.add(currentElement)) {
354 for (InterfaceType mixin in currentElement.mixins.reversed) {
355 ClassElement mixinElement = mixin.element;
356 if (mixinElement != null) {
357 PropertyAccessorElement element = mixinElement.getSetter(setterName);
358 if (element != null && element.isAccessibleIn(library)) {
359 return element;
360 }
361 }
362 }
363 InterfaceType supertype = currentElement.supertype;
364 if (supertype == null) {
365 return null;
366 }
367 currentElement = supertype.element;
368 PropertyAccessorElement element = currentElement.getSetter(setterName);
369 if (element != null && element.isAccessibleIn(library)) {
370 return element;
371 }
372 }
373 return null;
374 }
375
376 /**
377 * Return the [AbstractClassElementImpl] of the given [classElement]. May
378 * throw an exception if the [AbstractClassElementImpl] cannot be provided
379 * (should not happen though).
380 */
381 static AbstractClassElementImpl getImpl(ClassElement classElement) {
382 if (classElement is ClassElementHandle) {
383 return getImpl(classElement.actualElement);
384 }
385 return classElement as AbstractClassElementImpl;
386 }
387 }
388
389 /**
390 * For AST nodes that could be in both the getter and setter contexts
391 * ([IndexExpression]s and [SimpleIdentifier]s), the additional resolved
392 * elements are stored in the AST node, in an [AuxiliaryElements]. Because
393 * resolved elements are either statically resolved or resolved using propagated
394 * type information, this class is a wrapper for a pair of [ExecutableElement]s,
395 * not just a single [ExecutableElement].
396 */
397 class AuxiliaryElements {
398 /**
399 * The element based on propagated type information, or `null` if the AST
400 * structure has not been resolved or if the node could not be resolved.
401 */
402 final ExecutableElement propagatedElement;
403
404 /**
405 * The element based on static type information, or `null` if the AST
406 * structure has not been resolved or if the node could not be resolved.
407 */
408 final ExecutableElement staticElement;
409
410 /**
411 * Initialize a newly created pair to have both the [staticElement] and the
412 * [propagatedElement].
413 */
414 AuxiliaryElements(this.staticElement, this.propagatedElement);
415 }
416
417 /**
418 * An [AbstractClassElementImpl] which is a class.
419 */
420 class ClassElementImpl extends AbstractClassElementImpl
421 with TypeParameterizedElementMixin {
422 /**
423 * The unlinked representation of the class in the summary.
424 */
425 final UnlinkedClass _unlinkedClass;
426
427 /**
428 * A list containing all of the type parameters defined for this class.
429 */
430 List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
431
432 /**
433 * The superclass of the class, or `null` for [Object].
434 */
435 InterfaceType _supertype;
436
437 /**
438 * The type defined by the class.
439 */
440 InterfaceType _type;
441
442 /**
443 * A list containing all of the mixins that are applied to the class being
444 * extended in order to derive the superclass of this class.
445 */
446 List<InterfaceType> _mixins;
447
448 /**
449 * A list containing all of the interfaces that are implemented by this class.
450 */
451 List<InterfaceType> _interfaces;
452
453 /**
454 * For classes which are not mixin applications, a list containing all of the
455 * constructors contained in this class, or `null` if the list of
456 * constructors has not yet been built.
457 *
458 * For classes which are mixin applications, the list of constructors is
459 * computed on the fly by the [constructors] getter, and this field is
460 * `null`.
461 */
462 List<ConstructorElement> _constructors;
463
464 /**
465 * A list containing all of the methods contained in this class.
466 */
467 List<MethodElement> _methods;
468
469 /**
470 * A flag indicating whether the types associated with the instance members of
471 * this class have been inferred.
472 */
473 bool _hasBeenInferred = false;
474
475 /**
476 * The version of this element. The version is changed when the element is
477 * incrementally updated, so that its lists of constructors, accessors and
478 * methods might be different.
479 */
480 int version = 0;
481
482 /**
483 * Initialize a newly created class element to have the given [name] at the
484 * given [offset] in the file that contains the declaration of this element.
485 */
486 ClassElementImpl(String name, int offset)
487 : _unlinkedClass = null,
488 super(name, offset);
489
490 /**
491 * Initialize a newly created class element to have the given [name].
492 */
493 ClassElementImpl.forNode(Identifier name)
494 : _unlinkedClass = null,
495 super.forNode(name);
496
497 /**
498 * Initialize using the given serialized information.
499 */
500 ClassElementImpl.forSerialized(
501 this._unlinkedClass, CompilationUnitElementImpl enclosingUnit)
502 : super.forSerialized(enclosingUnit);
503
504 /**
505 * Set whether this class is abstract.
506 */
507 void set abstract(bool isAbstract) {
508 assert(_unlinkedClass == null);
509 setModifier(Modifier.ABSTRACT, isAbstract);
510 }
511
512 @override
513 List<PropertyAccessorElement> get accessors {
514 if (_unlinkedClass != null && _accessors == null) {
515 _resynthesizeFieldsAndPropertyAccessors();
516 }
517 return _accessors ?? const <PropertyAccessorElement>[];
518 }
519
520 @override
521 void set accessors(List<PropertyAccessorElement> accessors) {
522 assert(_unlinkedClass == null);
523 super.accessors = accessors;
524 }
525
526 @override
527 List<InterfaceType> get allSupertypes {
528 List<InterfaceType> list = new List<InterfaceType>();
529 _collectAllSupertypes(list);
530 return list;
531 }
532
533 @override
534 int get codeLength {
535 if (_unlinkedClass != null) {
536 return _unlinkedClass.codeRange?.length;
537 }
538 return super.codeLength;
539 }
540
541 @override
542 int get codeOffset {
543 if (_unlinkedClass != null) {
544 return _unlinkedClass.codeRange?.offset;
545 }
546 return super.codeOffset;
547 }
548
549 @override
550 List<ConstructorElement> get constructors {
551 if (isMixinApplication) {
552 return _computeMixinAppConstructors();
553 }
554 if (_unlinkedClass != null && _constructors == null) {
555 _constructors = _unlinkedClass.executables
556 .where((e) => e.kind == UnlinkedExecutableKind.constructor)
557 .map((e) => new ConstructorElementImpl.forSerialized(e, this))
558 .toList(growable: false);
559 // Ensure at least implicit default constructor.
560 if (_constructors.isEmpty) {
561 ConstructorElementImpl constructor = new ConstructorElementImpl('', -1);
562 constructor.synthetic = true;
563 constructor.enclosingElement = this;
564 _constructors = <ConstructorElement>[constructor];
565 }
566 }
567 assert(_constructors != null);
568 return _constructors ?? const <ConstructorElement>[];
569 }
570
571 /**
572 * Set the constructors contained in this class to the given [constructors].
573 *
574 * Should only be used for class elements that are not mixin applications.
575 */
576 void set constructors(List<ConstructorElement> constructors) {
577 assert(_unlinkedClass == null);
578 assert(!isMixinApplication);
579 for (ConstructorElement constructor in constructors) {
580 (constructor as ConstructorElementImpl).enclosingElement = this;
581 }
582 this._constructors = constructors;
583 }
584
585 @override
586 String get documentationComment {
587 if (_unlinkedClass != null) {
588 return _unlinkedClass?.documentationComment?.text;
589 }
590 return super.documentationComment;
591 }
592
593 /**
594 * Return `true` if [CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS] should
595 * be reported for this class.
596 */
597 bool get doesMixinLackConstructors {
598 if (!isMixinApplication && mixins.isEmpty) {
599 // This class is not a mixin application and it doesn't have a "with"
600 // clause, so CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS is
601 // inapplicable.
602 return false;
603 }
604 if (supertype == null) {
605 // Should never happen, since Object is the only class that has no
606 // supertype, and it should have been caught by the test above.
607 assert(false);
608 return false;
609 }
610 // Find the nearest class in the supertype chain that is not a mixin
611 // application.
612 ClassElement nearestNonMixinClass = supertype.element;
613 if (nearestNonMixinClass.isMixinApplication) {
614 // Use a list to keep track of the classes we've seen, so that we won't
615 // go into an infinite loop in the event of a non-trivial loop in the
616 // class hierarchy.
617 List<ClassElement> classesSeen = <ClassElement>[this];
618 while (nearestNonMixinClass.isMixinApplication) {
619 if (classesSeen.contains(nearestNonMixinClass)) {
620 // Loop in the class hierarchy (which is reported elsewhere). Don't
621 // confuse the user with further errors.
622 return false;
623 }
624 classesSeen.add(nearestNonMixinClass);
625 if (nearestNonMixinClass.supertype == null) {
626 // Should never happen, since Object is the only class that has no
627 // supertype, and it is not a mixin application.
628 assert(false);
629 return false;
630 }
631 nearestNonMixinClass = nearestNonMixinClass.supertype.element;
632 }
633 }
634 return !nearestNonMixinClass.constructors.any(isSuperConstructorAccessible);
635 }
636
637 @override
638 TypeParameterizedElementMixin get enclosingTypeParameterContext => null;
639
640 @override
641 List<FieldElement> get fields {
642 if (_unlinkedClass != null && _fields == null) {
643 _resynthesizeFieldsAndPropertyAccessors();
644 }
645 return _fields ?? const <FieldElement>[];
646 }
647
648 @override
649 void set fields(List<FieldElement> fields) {
650 assert(_unlinkedClass == null);
651 super.fields = fields;
652 }
653
654 bool get hasBeenInferred {
655 if (_unlinkedClass != null) {
656 return context.analysisOptions.strongMode;
657 }
658 return _hasBeenInferred;
659 }
660
661 void set hasBeenInferred(bool hasBeenInferred) {
662 assert(_unlinkedClass == null);
663 _hasBeenInferred = hasBeenInferred;
664 }
665
666 @override
667 bool get hasNonFinalField {
668 List<ClassElement> classesToVisit = new List<ClassElement>();
669 HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
670 classesToVisit.add(this);
671 while (!classesToVisit.isEmpty) {
672 ClassElement currentElement = classesToVisit.removeAt(0);
673 if (visitedClasses.add(currentElement)) {
674 // check fields
675 for (FieldElement field in currentElement.fields) {
676 if (!field.isFinal &&
677 !field.isConst &&
678 !field.isStatic &&
679 !field.isSynthetic) {
680 return true;
681 }
682 }
683 // check mixins
684 for (InterfaceType mixinType in currentElement.mixins) {
685 ClassElement mixinElement = mixinType.element;
686 classesToVisit.add(mixinElement);
687 }
688 // check super
689 InterfaceType supertype = currentElement.supertype;
690 if (supertype != null) {
691 ClassElement superElement = supertype.element;
692 if (superElement != null) {
693 classesToVisit.add(superElement);
694 }
695 }
696 }
697 }
698 // not found
699 return false;
700 }
701
702 /**
703 * Return `true` if the class has a `noSuchMethod()` method distinct from the
704 * one declared in class `Object`, as per the Dart Language Specification
705 * (section 10.4).
706 */
707 bool get hasNoSuchMethod {
708 MethodElement method =
709 lookUpMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME, library);
710 ClassElement definingClass = method?.enclosingElement;
711 return definingClass != null && !definingClass.type.isObject;
712 }
713
714 @override
715 bool get hasReferenceToSuper => hasModifier(Modifier.REFERENCES_SUPER);
716
717 /**
718 * Set whether this class references 'super'.
719 */
720 void set hasReferenceToSuper(bool isReferencedSuper) {
721 setModifier(Modifier.REFERENCES_SUPER, isReferencedSuper);
722 }
723
724 @override
725 bool get hasStaticMember {
726 for (MethodElement method in methods) {
727 if (method.isStatic) {
728 return true;
729 }
730 }
731 for (PropertyAccessorElement accessor in accessors) {
732 if (accessor.isStatic) {
733 return true;
734 }
735 }
736 return false;
737 }
738
739 @override
740 List<InterfaceType> get interfaces {
741 if (_unlinkedClass != null && _interfaces == null) {
742 ResynthesizerContext context = enclosingUnit.resynthesizerContext;
743 _interfaces = _unlinkedClass.interfaces
744 .map((EntityRef t) => context.resolveTypeRef(t, this))
745 .where((DartType type) => type is InterfaceType)
746 .toList(growable: false);
747 }
748 return _interfaces ?? const <InterfaceType>[];
749 }
750
751 void set interfaces(List<InterfaceType> interfaces) {
752 assert(_unlinkedClass == null);
753 _interfaces = interfaces;
754 }
755
756 @override
757 bool get isAbstract {
758 if (_unlinkedClass != null) {
759 return _unlinkedClass.isAbstract;
760 }
761 return hasModifier(Modifier.ABSTRACT);
762 }
763
764 @override
765 bool get isEnum => false;
766
767 @override
768 bool get isMixinApplication {
769 if (_unlinkedClass != null) {
770 return _unlinkedClass.isMixinApplication;
771 }
772 return hasModifier(Modifier.MIXIN_APPLICATION);
773 }
774
775 @override
776 bool get isOrInheritsProxy =>
777 _safeIsOrInheritsProxy(this, new HashSet<ClassElement>());
778
779 @override
780 bool get isProxy {
781 for (ElementAnnotation annotation in metadata) {
782 if (annotation.isProxy) {
783 return true;
784 }
785 }
786 return false;
787 }
788
789 @override
790 bool get isValidMixin {
791 if (!context.analysisOptions.enableSuperMixins) {
792 if (hasReferenceToSuper) {
793 return false;
794 }
795 if (!supertype.isObject) {
796 return false;
797 }
798 }
799 for (ConstructorElement constructor in constructors) {
800 if (!constructor.isSynthetic && !constructor.isFactory) {
801 return false;
802 }
803 }
804 return true;
805 }
806
807 @override
808 List<ElementAnnotation> get metadata {
809 if (_unlinkedClass != null) {
810 return _metadata ??=
811 _buildAnnotations(enclosingUnit, _unlinkedClass.annotations);
812 }
813 return super.metadata;
814 }
815
816 @override
817 List<MethodElement> get methods {
818 if (_unlinkedClass != null) {
819 _methods ??= _unlinkedClass.executables
820 .where((e) => e.kind == UnlinkedExecutableKind.functionOrMethod)
821 .map((e) => new MethodElementImpl.forSerialized(e, this))
822 .toList(growable: false);
823 }
824 return _methods ?? const <MethodElement>[];
825 }
826
827 /**
828 * Set the methods contained in this class to the given [methods].
829 */
830 void set methods(List<MethodElement> methods) {
831 assert(_unlinkedClass == null);
832 for (MethodElement method in methods) {
833 (method as MethodElementImpl).enclosingElement = this;
834 }
835 _methods = methods;
836 }
837
838 /**
839 * Set whether this class is a mixin application.
840 */
841 void set mixinApplication(bool isMixinApplication) {
842 assert(_unlinkedClass == null);
843 setModifier(Modifier.MIXIN_APPLICATION, isMixinApplication);
844 }
845
846 @override
847 List<InterfaceType> get mixins {
848 if (_unlinkedClass != null && _mixins == null) {
849 ResynthesizerContext context = enclosingUnit.resynthesizerContext;
850 _mixins = _unlinkedClass.mixins
851 .map((EntityRef t) => context.resolveTypeRef(t, this))
852 .where((DartType type) => type is InterfaceType)
853 .toList(growable: false);
854 }
855 return _mixins ?? const <InterfaceType>[];
856 }
857
858 void set mixins(List<InterfaceType> mixins) {
859 assert(_unlinkedClass == null);
860 _mixins = mixins;
861 }
862
863 @override
864 String get name {
865 if (_unlinkedClass != null) {
866 return _unlinkedClass.name;
867 }
868 return super.name;
869 }
870
871 @override
872 int get nameOffset {
873 if (_unlinkedClass != null) {
874 return _unlinkedClass.nameOffset;
875 }
876 return super.nameOffset;
877 }
878
879 @override
880 InterfaceType get supertype {
881 if (_unlinkedClass != null && _supertype == null) {
882 if (_unlinkedClass.supertype != null) {
883 DartType type = enclosingUnit.resynthesizerContext
884 .resolveTypeRef(_unlinkedClass.supertype, this);
885 if (type is InterfaceType) {
886 _supertype = type;
887 } else {
888 _supertype = context.typeProvider.objectType;
889 }
890 } else if (_unlinkedClass.hasNoSupertype) {
891 return null;
892 } else {
893 _supertype = context.typeProvider.objectType;
894 }
895 }
896 return _supertype;
897 }
898
899 void set supertype(InterfaceType supertype) {
900 assert(_unlinkedClass == null);
901 _supertype = supertype;
902 }
903
904 @override
905 InterfaceType get type {
906 if (_type == null) {
907 InterfaceTypeImpl type = new InterfaceTypeImpl(this);
908 type.typeArguments = typeParameterTypes;
909 _type = type;
910 }
911 return _type;
912 }
913
914 @override
915 TypeParameterizedElementMixin get typeParameterContext => this;
916
917 @override
918 List<TypeParameterElement> get typeParameters {
919 if (_unlinkedClass != null) {
920 return super.typeParameters;
921 }
922 return _typeParameters;
923 }
924
925 /**
926 * Set the type parameters defined for this class to the given
927 * [typeParameters].
928 */
929 void set typeParameters(List<TypeParameterElement> typeParameters) {
930 assert(_unlinkedClass == null);
931 for (TypeParameterElement typeParameter in typeParameters) {
932 (typeParameter as TypeParameterElementImpl).enclosingElement = this;
933 }
934 this._typeParameters = typeParameters;
935 }
936
937 @override
938 List<UnlinkedTypeParam> get unlinkedTypeParams =>
939 _unlinkedClass.typeParameters;
940
941 @override
942 ConstructorElement get unnamedConstructor {
943 for (ConstructorElement element in constructors) {
944 String name = element.displayName;
945 if (name == null || name.isEmpty) {
946 return element;
947 }
948 }
949 return null;
950 }
951
952 @override
953 void appendTo(StringBuffer buffer) {
954 if (isAbstract) {
955 buffer.write('abstract ');
956 }
957 buffer.write('class ');
958 String name = displayName;
959 if (name == null) {
960 buffer.write("{unnamed class}");
961 } else {
962 buffer.write(name);
963 }
964 int variableCount = typeParameters.length;
965 if (variableCount > 0) {
966 buffer.write("<");
967 for (int i = 0; i < variableCount; i++) {
968 if (i > 0) {
969 buffer.write(", ");
970 }
971 (typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
972 }
973 buffer.write(">");
974 }
975 if (supertype != null && !supertype.isObject) {
976 buffer.write(' extends ');
977 buffer.write(supertype.displayName);
978 }
979 if (mixins.isNotEmpty) {
980 buffer.write(' with ');
981 buffer.write(mixins.map((t) => t.displayName).join(', '));
982 }
983 if (interfaces.isNotEmpty) {
984 buffer.write(' implements ');
985 buffer.write(interfaces.map((t) => t.displayName).join(', '));
986 }
987 }
988
989 @override
990 ElementImpl getChild(String identifier) {
991 ElementImpl child = super.getChild(identifier);
992 if (child != null) {
993 return child;
994 }
995 //
996 // The casts in this method are safe because the set methods would have
997 // thrown a CCE if any of the elements in the arrays were not of the
998 // expected types.
999 //
1000 for (ConstructorElement constructor in _constructors) {
1001 ConstructorElementImpl constructorImpl = constructor;
1002 if (constructorImpl.identifier == identifier) {
1003 return constructorImpl;
1004 }
1005 }
1006 for (MethodElement method in methods) {
1007 MethodElementImpl methodImpl = method;
1008 if (methodImpl.identifier == identifier) {
1009 return methodImpl;
1010 }
1011 }
1012 for (TypeParameterElement typeParameter in typeParameters) {
1013 TypeParameterElementImpl typeParameterImpl = typeParameter;
1014 if (typeParameterImpl.identifier == identifier) {
1015 return typeParameterImpl;
1016 }
1017 }
1018 return null;
1019 }
1020
1021 @override
1022 MethodElement getMethod(String methodName) {
1023 int length = methods.length;
1024 for (int i = 0; i < length; i++) {
1025 MethodElement method = methods[i];
1026 if (method.name == methodName) {
1027 return method;
1028 }
1029 }
1030 return null;
1031 }
1032
1033 @override
1034 ConstructorElement getNamedConstructor(String name) {
1035 for (ConstructorElement element in constructors) {
1036 String elementName = element.name;
1037 if (elementName != null && elementName == name) {
1038 return element;
1039 }
1040 }
1041 return null;
1042 }
1043
1044 @override
1045 bool isSuperConstructorAccessible(ConstructorElement constructor) {
1046 // If this class has no mixins, then all superclass constructors are
1047 // accessible.
1048 if (mixins.isEmpty) {
1049 return true;
1050 }
1051 // Otherwise only constructors that lack optional parameters are
1052 // accessible (see dartbug.com/19576).
1053 for (ParameterElement parameter in constructor.parameters) {
1054 if (parameter.parameterKind != ParameterKind.REQUIRED) {
1055 return false;
1056 }
1057 }
1058 return true;
1059 }
1060
1061 @override
1062 void visitChildren(ElementVisitor visitor) {
1063 super.visitChildren(visitor);
1064 safelyVisitChildren(_constructors, visitor);
1065 safelyVisitChildren(methods, visitor);
1066 safelyVisitChildren(_typeParameters, visitor);
1067 }
1068
1069 void _collectAllSupertypes(List<InterfaceType> supertypes) {
1070 List<InterfaceType> typesToVisit = new List<InterfaceType>();
1071 List<ClassElement> visitedClasses = new List<ClassElement>();
1072 typesToVisit.add(this.type);
1073 while (!typesToVisit.isEmpty) {
1074 InterfaceType currentType = typesToVisit.removeAt(0);
1075 ClassElement currentElement = currentType.element;
1076 if (!visitedClasses.contains(currentElement)) {
1077 visitedClasses.add(currentElement);
1078 if (!identical(currentType, this.type)) {
1079 supertypes.add(currentType);
1080 }
1081 InterfaceType supertype = currentType.superclass;
1082 if (supertype != null) {
1083 typesToVisit.add(supertype);
1084 }
1085 for (InterfaceType type in currentElement.interfaces) {
1086 typesToVisit.add(type);
1087 }
1088 for (InterfaceType type in currentElement.mixins) {
1089 ClassElement element = type.element;
1090 if (!visitedClasses.contains(element)) {
1091 supertypes.add(type);
1092 }
1093 }
1094 }
1095 }
1096 }
1097
1098 /**
1099 * Compute a list of constructors for this class, which is a mixin
1100 * application. If specified, [visitedClasses] is a list of the other mixin
1101 * application classes which have been visited on the way to reaching this
1102 * one (this is used to detect circularities).
1103 */
1104 List<ConstructorElement> _computeMixinAppConstructors(
1105 [List<ClassElementImpl> visitedClasses = null]) {
1106 // First get the list of constructors of the superclass which need to be
1107 // forwarded to this class.
1108 Iterable<ConstructorElement> constructorsToForward;
1109 if (supertype == null) {
1110 // Shouldn't ever happen, since the only class with no supertype is
1111 // Object, and it isn't a mixin application. But for safety's sake just
1112 // assume an empty list.
1113 assert(false);
1114 constructorsToForward = <ConstructorElement>[];
1115 } else if (!supertype.element.isMixinApplication) {
1116 List<ConstructorElement> superclassConstructors =
1117 supertype.element.constructors;
1118 // Filter out any constructors with optional parameters (see
1119 // dartbug.com/15101).
1120 constructorsToForward =
1121 superclassConstructors.where(isSuperConstructorAccessible);
1122 } else {
1123 if (visitedClasses == null) {
1124 visitedClasses = <ClassElementImpl>[this];
1125 } else {
1126 if (visitedClasses.contains(this)) {
1127 // Loop in the class hierarchy. Don't try to forward any
1128 // constructors.
1129 return <ConstructorElement>[];
1130 }
1131 visitedClasses.add(this);
1132 }
1133 try {
1134 ClassElementImpl superElement = AbstractClassElementImpl
1135 .getImpl(supertype.element) as ClassElementImpl;
1136 constructorsToForward =
1137 superElement._computeMixinAppConstructors(visitedClasses);
1138 } finally {
1139 visitedClasses.removeLast();
1140 }
1141 }
1142
1143 // Figure out the type parameter substitution we need to perform in order
1144 // to produce constructors for this class. We want to be robust in the
1145 // face of errors, so drop any extra type arguments and fill in any missing
1146 // ones with `dynamic`.
1147 List<DartType> parameterTypes =
1148 TypeParameterTypeImpl.getTypes(supertype.typeParameters);
1149 List<DartType> argumentTypes = new List<DartType>.filled(
1150 parameterTypes.length, DynamicTypeImpl.instance);
1151 for (int i = 0; i < supertype.typeArguments.length; i++) {
1152 if (i >= argumentTypes.length) {
1153 break;
1154 }
1155 argumentTypes[i] = supertype.typeArguments[i];
1156 }
1157
1158 // Now create an implicit constructor for every constructor found above,
1159 // substituting type parameters as appropriate.
1160 return constructorsToForward
1161 .map((ConstructorElement superclassConstructor) {
1162 ConstructorElementImpl implicitConstructor =
1163 new ConstructorElementImpl(superclassConstructor.name, -1);
1164 implicitConstructor.synthetic = true;
1165 implicitConstructor.redirectedConstructor = superclassConstructor;
1166 List<ParameterElement> superParameters = superclassConstructor.parameters;
1167 int count = superParameters.length;
1168 if (count > 0) {
1169 List<ParameterElement> implicitParameters =
1170 new List<ParameterElement>(count);
1171 for (int i = 0; i < count; i++) {
1172 ParameterElement superParameter = superParameters[i];
1173 ParameterElementImpl implicitParameter =
1174 new ParameterElementImpl(superParameter.name, -1);
1175 implicitParameter.const3 = superParameter.isConst;
1176 implicitParameter.final2 = superParameter.isFinal;
1177 implicitParameter.parameterKind = superParameter.parameterKind;
1178 implicitParameter.synthetic = true;
1179 implicitParameter.type =
1180 superParameter.type.substitute2(argumentTypes, parameterTypes);
1181 implicitParameters[i] = implicitParameter;
1182 }
1183 implicitConstructor.parameters = implicitParameters;
1184 }
1185 implicitConstructor.enclosingElement = this;
1186 return implicitConstructor;
1187 }).toList(growable: false);
1188 }
1189
1190 /**
1191 * Resynthesize explicit fields and property accessors and fill [_fields] and
1192 * [_accessors] with explicit and implicit elements.
1193 */
1194 void _resynthesizeFieldsAndPropertyAccessors() {
1195 assert(_fields == null);
1196 assert(_accessors == null);
1197 // Build explicit fields and implicit property accessors.
1198 var explicitFields = <FieldElement>[];
1199 var implicitAccessors = <PropertyAccessorElement>[];
1200 for (UnlinkedVariable v in _unlinkedClass.fields) {
1201 FieldElementImpl field =
1202 new FieldElementImpl.forSerializedFactory(v, this);
1203 explicitFields.add(field);
1204 implicitAccessors.add(
1205 new PropertyAccessorElementImpl_ImplicitGetter(field)
1206 ..enclosingElement = this);
1207 if (!field.isConst && !field.isFinal) {
1208 implicitAccessors.add(
1209 new PropertyAccessorElementImpl_ImplicitSetter(field)
1210 ..enclosingElement = this);
1211 }
1212 }
1213 // Build explicit property accessors and implicit fields.
1214 var explicitAccessors = <PropertyAccessorElement>[];
1215 var implicitFields = <String, FieldElementImpl>{};
1216 for (UnlinkedExecutable e in _unlinkedClass.executables) {
1217 if (e.kind == UnlinkedExecutableKind.getter ||
1218 e.kind == UnlinkedExecutableKind.setter) {
1219 PropertyAccessorElementImpl accessor =
1220 new PropertyAccessorElementImpl.forSerialized(e, this);
1221 explicitAccessors.add(accessor);
1222 // Prepare the field type.
1223 DartType fieldType;
1224 if (e.kind == UnlinkedExecutableKind.getter) {
1225 fieldType = accessor.returnType;
1226 } else {
1227 fieldType = accessor.parameters[0].type;
1228 }
1229 // Create or update the implicit field.
1230 String fieldName = accessor.displayName;
1231 FieldElementImpl field = implicitFields[fieldName];
1232 if (field == null) {
1233 field = new FieldElementImpl(fieldName, -1);
1234 implicitFields[fieldName] = field;
1235 field.enclosingElement = this;
1236 field.synthetic = true;
1237 field.final2 = e.kind == UnlinkedExecutableKind.getter;
1238 field.type = fieldType;
1239 } else {
1240 field.final2 = false;
1241 }
1242 accessor.variable = field;
1243 if (e.kind == UnlinkedExecutableKind.getter) {
1244 field.getter = accessor;
1245 } else {
1246 field.setter = accessor;
1247 }
1248 }
1249 }
1250 // Combine explicit and implicit fields and property accessors.
1251 _fields = <FieldElement>[]
1252 ..addAll(explicitFields)
1253 ..addAll(implicitFields.values);
1254 _accessors = <PropertyAccessorElement>[]
1255 ..addAll(explicitAccessors)
1256 ..addAll(implicitAccessors);
1257 }
1258
1259 bool _safeIsOrInheritsProxy(
1260 ClassElement element, HashSet<ClassElement> visited) {
1261 if (visited.contains(element)) {
1262 return false;
1263 }
1264 visited.add(element);
1265 if (element.isProxy) {
1266 return true;
1267 } else if (element.supertype != null &&
1268 _safeIsOrInheritsProxy(element.supertype.element, visited)) {
1269 return true;
1270 }
1271 List<InterfaceType> supertypes = element.interfaces;
1272 for (int i = 0; i < supertypes.length; i++) {
1273 if (_safeIsOrInheritsProxy(supertypes[i].element, visited)) {
1274 return true;
1275 }
1276 }
1277 supertypes = element.mixins;
1278 for (int i = 0; i < supertypes.length; i++) {
1279 if (_safeIsOrInheritsProxy(supertypes[i].element, visited)) {
1280 return true;
1281 }
1282 }
1283 return false;
1284 }
1285 }
1286
1287 /**
1288 * A concrete implementation of a [CompilationUnitElement].
1289 */
1290 class CompilationUnitElementImpl extends UriReferencedElementImpl
1291 implements CompilationUnitElement {
1292 /**
1293 * The context in which this unit is resynthesized, or `null` if the
1294 * element is not resynthesized a summary.
1295 */
1296 final ResynthesizerContext resynthesizerContext;
1297
1298 /**
1299 * The unlinked representation of the unit in the summary.
1300 */
1301 final UnlinkedUnit _unlinkedUnit;
1302
1303 /**
1304 * The unlinked representation of the part in the summary.
1305 */
1306 final UnlinkedPart _unlinkedPart;
1307
1308 /**
1309 * The source that corresponds to this compilation unit.
1310 */
1311 @override
1312 Source source;
1313
1314 /**
1315 * The source of the library containing this compilation unit.
1316 *
1317 * This is the same as the source of the containing [LibraryElement],
1318 * except that it does not require the containing [LibraryElement] to be
1319 * computed.
1320 */
1321 Source librarySource;
1322
1323 /**
1324 * A table mapping the offset of a directive to the annotations associated
1325 * with that directive, or `null` if none of the annotations in the
1326 * compilation unit have annotations.
1327 */
1328 Map<int, List<ElementAnnotation>> annotationMap = null;
1329
1330 /**
1331 * A list containing all of the top-level accessors (getters and setters)
1332 * contained in this compilation unit.
1333 */
1334 List<PropertyAccessorElement> _accessors;
1335
1336 /**
1337 * A list containing all of the enums contained in this compilation unit.
1338 */
1339 List<ClassElement> _enums;
1340
1341 /**
1342 * A list containing all of the top-level functions contained in this
1343 * compilation unit.
1344 */
1345 List<FunctionElement> _functions;
1346
1347 /**
1348 * A list containing all of the function type aliases contained in this
1349 * compilation unit.
1350 */
1351 List<FunctionTypeAliasElement> _typeAliases;
1352
1353 /**
1354 * A list containing all of the types contained in this compilation unit.
1355 */
1356 List<ClassElement> _types;
1357
1358 /**
1359 * A list containing all of the variables contained in this compilation unit.
1360 */
1361 List<TopLevelVariableElement> _variables;
1362
1363 /**
1364 * A map from offsets to elements of this unit at these offsets.
1365 */
1366 final Map<int, Element> _offsetToElementMap = new HashMap<int, Element>();
1367
1368 /**
1369 * Resynthesized explicit top-level property accessors.
1370 */
1371 UnitExplicitTopLevelAccessors _explicitTopLevelAccessors;
1372
1373 /**
1374 * Resynthesized explicit top-level variables.
1375 */
1376 UnitExplicitTopLevelVariables _explicitTopLevelVariables;
1377
1378 /**
1379 * Description of top-level variable replacements that should be applied
1380 * to implicit top-level variables because of re-linking top-level property
1381 * accessors between different unit of the same library.
1382 */
1383 Map<TopLevelVariableElement, TopLevelVariableElement>
1384 _topLevelVariableReplaceMap;
1385
1386 /**
1387 * Initialize a newly created compilation unit element to have the given
1388 * [name].
1389 */
1390 CompilationUnitElementImpl(String name)
1391 : resynthesizerContext = null,
1392 _unlinkedUnit = null,
1393 _unlinkedPart = null,
1394 super(name, -1);
1395
1396 /**
1397 * Initialize using the given serialized information.
1398 */
1399 CompilationUnitElementImpl.forSerialized(
1400 LibraryElementImpl enclosingLibrary,
1401 this.resynthesizerContext,
1402 this._unlinkedUnit,
1403 this._unlinkedPart,
1404 String name)
1405 : super.forSerialized(null) {
1406 _enclosingElement = enclosingLibrary;
1407 _name = name;
1408 _nameOffset = -1;
1409 }
1410
1411 @override
1412 List<PropertyAccessorElement> get accessors {
1413 if (_unlinkedUnit != null) {
1414 if (_accessors == null) {
1415 _explicitTopLevelAccessors ??=
1416 resynthesizerContext.buildTopLevelAccessors();
1417 _explicitTopLevelVariables ??=
1418 resynthesizerContext.buildTopLevelVariables();
1419 List<PropertyAccessorElementImpl> accessors =
1420 <PropertyAccessorElementImpl>[];
1421 accessors.addAll(_explicitTopLevelAccessors.accessors);
1422 accessors.addAll(_explicitTopLevelVariables.implicitAccessors);
1423 _accessors = accessors;
1424 }
1425 }
1426 return _accessors ?? PropertyAccessorElement.EMPTY_LIST;
1427 }
1428
1429 /**
1430 * Set the top-level accessors (getters and setters) contained in this
1431 * compilation unit to the given [accessors].
1432 */
1433 void set accessors(List<PropertyAccessorElement> accessors) {
1434 for (PropertyAccessorElement accessor in accessors) {
1435 (accessor as PropertyAccessorElementImpl).enclosingElement = this;
1436 }
1437 this._accessors = accessors;
1438 }
1439
1440 @override
1441 int get codeLength {
1442 if (_unlinkedUnit != null) {
1443 return _unlinkedUnit.codeRange?.length;
1444 }
1445 return super.codeLength;
1446 }
1447
1448 @override
1449 int get codeOffset {
1450 if (_unlinkedUnit != null) {
1451 return _unlinkedUnit.codeRange?.offset;
1452 }
1453 return super.codeOffset;
1454 }
1455
1456 @override
1457 LibraryElement get enclosingElement =>
1458 super.enclosingElement as LibraryElement;
1459
1460 @override
1461 CompilationUnitElementImpl get enclosingUnit {
1462 return this;
1463 }
1464
1465 @override
1466 List<ClassElement> get enums {
1467 if (_unlinkedUnit != null) {
1468 _enums ??= _unlinkedUnit.enums
1469 .map((e) => new EnumElementImpl.forSerialized(e, this))
1470 .toList(growable: false);
1471 }
1472 return _enums ?? const <ClassElement>[];
1473 }
1474
1475 /**
1476 * Set the enums contained in this compilation unit to the given [enums].
1477 */
1478 void set enums(List<ClassElement> enums) {
1479 assert(_unlinkedUnit == null);
1480 for (ClassElement enumDeclaration in enums) {
1481 (enumDeclaration as EnumElementImpl).enclosingElement = this;
1482 }
1483 this._enums = enums;
1484 }
1485
1486 @override
1487 List<FunctionElement> get functions {
1488 if (_unlinkedUnit != null) {
1489 _functions ??= _unlinkedUnit.executables
1490 .where((e) => e.kind == UnlinkedExecutableKind.functionOrMethod)
1491 .map((e) => new FunctionElementImpl.forSerialized(e, this))
1492 .toList(growable: false);
1493 }
1494 return _functions ?? const <FunctionElement>[];
1495 }
1496
1497 /**
1498 * Set the top-level functions contained in this compilation unit to the given
1499 * [functions].
1500 */
1501 void set functions(List<FunctionElement> functions) {
1502 for (FunctionElement function in functions) {
1503 (function as FunctionElementImpl).enclosingElement = this;
1504 }
1505 this._functions = functions;
1506 }
1507
1508 @override
1509 List<FunctionTypeAliasElement> get functionTypeAliases {
1510 if (_unlinkedUnit != null) {
1511 _typeAliases ??= _unlinkedUnit.typedefs
1512 .map((t) => new FunctionTypeAliasElementImpl.forSerialized(t, this))
1513 .toList(growable: false);
1514 }
1515 return _typeAliases ?? const <FunctionTypeAliasElement>[];
1516 }
1517
1518 @override
1519 int get hashCode => source.hashCode;
1520
1521 @override
1522 bool get hasLoadLibraryFunction {
1523 List<FunctionElement> functions = this.functions;
1524 for (int i = 0; i < functions.length; i++) {
1525 if (functions[i].name == FunctionElement.LOAD_LIBRARY_NAME) {
1526 return true;
1527 }
1528 }
1529 return false;
1530 }
1531
1532 @override
1533 String get identifier => source.encoding;
1534
1535 @override
1536 ElementKind get kind => ElementKind.COMPILATION_UNIT;
1537
1538 @override
1539 List<ElementAnnotation> get metadata {
1540 if (_unlinkedPart != null) {
1541 return _metadata ??= _buildAnnotations(
1542 library.definingCompilationUnit as CompilationUnitElementImpl,
1543 _unlinkedPart.annotations);
1544 }
1545 return super.metadata;
1546 }
1547
1548 @override
1549 List<TopLevelVariableElement> get topLevelVariables {
1550 if (_unlinkedUnit != null) {
1551 if (_variables == null) {
1552 _explicitTopLevelAccessors ??=
1553 resynthesizerContext.buildTopLevelAccessors();
1554 _explicitTopLevelVariables ??=
1555 resynthesizerContext.buildTopLevelVariables();
1556 List<TopLevelVariableElementImpl> variables =
1557 <TopLevelVariableElementImpl>[];
1558 variables.addAll(_explicitTopLevelVariables.variables);
1559 variables.addAll(_explicitTopLevelAccessors.implicitVariables);
1560 // Ensure that getters and setters in different units use
1561 // the same top-level variables.
1562 (enclosingElement as LibraryElementImpl)
1563 .resynthesizerContext
1564 .patchTopLevelAccessors();
1565 _variables = variables;
1566 _topLevelVariableReplaceMap?.forEach((from, to) {
1567 int index = _variables.indexOf(from);
1568 _variables[index] = to;
1569 });
1570 _topLevelVariableReplaceMap = null;
1571 }
1572 }
1573 return _variables ?? TopLevelVariableElement.EMPTY_LIST;
1574 }
1575
1576 /**
1577 * Set the top-level variables contained in this compilation unit to the given
1578 * [variables].
1579 */
1580 void set topLevelVariables(List<TopLevelVariableElement> variables) {
1581 assert(!isResynthesized);
1582 for (TopLevelVariableElement field in variables) {
1583 (field as TopLevelVariableElementImpl).enclosingElement = this;
1584 }
1585 this._variables = variables;
1586 }
1587
1588 /**
1589 * Set the function type aliases contained in this compilation unit to the
1590 * given [typeAliases].
1591 */
1592 void set typeAliases(List<FunctionTypeAliasElement> typeAliases) {
1593 assert(_unlinkedUnit == null);
1594 for (FunctionTypeAliasElement typeAlias in typeAliases) {
1595 (typeAlias as FunctionTypeAliasElementImpl).enclosingElement = this;
1596 }
1597 this._typeAliases = typeAliases;
1598 }
1599
1600 @override
1601 TypeParameterizedElementMixin get typeParameterContext => null;
1602
1603 @override
1604 List<ClassElement> get types {
1605 if (_unlinkedUnit != null) {
1606 _types ??= _unlinkedUnit.classes
1607 .map((c) => new ClassElementImpl.forSerialized(c, this))
1608 .toList(growable: false);
1609 }
1610 return _types ?? const <ClassElement>[];
1611 }
1612
1613 /**
1614 * Set the types contained in this compilation unit to the given [types].
1615 */
1616 void set types(List<ClassElement> types) {
1617 assert(_unlinkedUnit == null);
1618 for (ClassElement type in types) {
1619 // Another implementation of ClassElement is _DeferredClassElement,
1620 // which is used to resynthesize classes lazily. We cannot cast it
1621 // to ClassElementImpl, and it already can provide correct values of the
1622 // 'enclosingElement' property.
1623 if (type is ClassElementImpl) {
1624 type.enclosingElement = this;
1625 }
1626 }
1627 this._types = types;
1628 }
1629
1630 @override
1631 bool operator ==(Object object) =>
1632 object is CompilationUnitElementImpl && source == object.source;
1633
1634 @override
1635 accept(ElementVisitor visitor) => visitor.visitCompilationUnitElement(this);
1636
1637 /**
1638 * This method is invoked after this unit was incrementally resolved.
1639 */
1640 void afterIncrementalResolution() {
1641 _offsetToElementMap.clear();
1642 }
1643
1644 @override
1645 void appendTo(StringBuffer buffer) {
1646 if (source == null) {
1647 buffer.write("{compilation unit}");
1648 } else {
1649 buffer.write(source.fullName);
1650 }
1651 }
1652
1653 @override
1654 CompilationUnit computeNode() => unit;
1655
1656 /**
1657 * Return the annotations associated with the directive at the given [offset],
1658 * or an empty list if the directive has no annotations or if there is no
1659 * directive at the given offset.
1660 */
1661 List<ElementAnnotation> getAnnotations(int offset) {
1662 if (annotationMap == null) {
1663 return const <ElementAnnotation>[];
1664 }
1665 return annotationMap[offset] ?? const <ElementAnnotation>[];
1666 }
1667
1668 @override
1669 ElementImpl getChild(String identifier) {
1670 //
1671 // The casts in this method are safe because the set methods would have
1672 // thrown a CCE if any of the elements in the arrays were not of the
1673 // expected types.
1674 //
1675 for (PropertyAccessorElement accessor in accessors) {
1676 PropertyAccessorElementImpl accessorImpl = accessor;
1677 if (accessorImpl.identifier == identifier) {
1678 return accessorImpl;
1679 }
1680 }
1681 for (TopLevelVariableElement variable in topLevelVariables) {
1682 TopLevelVariableElementImpl variableImpl = variable;
1683 if (variableImpl.identifier == identifier) {
1684 return variableImpl;
1685 }
1686 }
1687 for (FunctionElement function in functions) {
1688 FunctionElementImpl functionImpl = function;
1689 if (functionImpl.identifier == identifier) {
1690 return functionImpl;
1691 }
1692 }
1693 for (FunctionTypeAliasElement typeAlias in functionTypeAliases) {
1694 FunctionTypeAliasElementImpl typeAliasImpl = typeAlias;
1695 if (typeAliasImpl.identifier == identifier) {
1696 return typeAliasImpl;
1697 }
1698 }
1699 for (ClassElement type in types) {
1700 ClassElementImpl typeImpl = type;
1701 if (typeImpl.name == identifier) {
1702 return typeImpl;
1703 }
1704 }
1705 for (ClassElement type in _enums) {
1706 EnumElementImpl typeImpl = type;
1707 if (typeImpl.identifier == identifier) {
1708 return typeImpl;
1709 }
1710 }
1711 return null;
1712 }
1713
1714 @override
1715 Element getElementAt(int offset) {
1716 if (_offsetToElementMap.isEmpty) {
1717 accept(new _BuildOffsetToElementMap(_offsetToElementMap));
1718 }
1719 return _offsetToElementMap[offset];
1720 }
1721
1722 @override
1723 ClassElement getEnum(String enumName) {
1724 for (ClassElement enumDeclaration in _enums) {
1725 if (enumDeclaration.name == enumName) {
1726 return enumDeclaration;
1727 }
1728 }
1729 return null;
1730 }
1731
1732 @override
1733 ClassElement getType(String className) {
1734 for (ClassElement type in types) {
1735 if (type.name == className) {
1736 return type;
1737 }
1738 }
1739 return null;
1740 }
1741
1742 /**
1743 * Replace the given [from] top-level variable with [to] in this compilation u nit.
1744 */
1745 void replaceTopLevelVariable(
1746 TopLevelVariableElement from, TopLevelVariableElement to) {
1747 if (_unlinkedUnit != null) {
1748 // Getters and setter in different units should be patched to use the
1749 // same variables before these variables were asked and returned.
1750 assert(_variables == null);
1751 _topLevelVariableReplaceMap ??=
1752 <TopLevelVariableElement, TopLevelVariableElement>{};
1753 _topLevelVariableReplaceMap[from] = to;
1754 } else {
1755 int index = _variables.indexOf(from);
1756 _variables[index] = to;
1757 }
1758 }
1759
1760 /**
1761 * Set the annotations associated with the directive at the given [offset] to
1762 * the given list of [annotations].
1763 */
1764 void setAnnotations(int offset, List<ElementAnnotation> annotations) {
1765 annotationMap ??= new HashMap<int, List<ElementAnnotation>>();
1766 annotationMap[offset] = annotations;
1767 }
1768
1769 @override
1770 void visitChildren(ElementVisitor visitor) {
1771 super.visitChildren(visitor);
1772 safelyVisitChildren(accessors, visitor);
1773 safelyVisitChildren(_enums, visitor);
1774 safelyVisitChildren(functions, visitor);
1775 safelyVisitChildren(functionTypeAliases, visitor);
1776 safelyVisitChildren(types, visitor);
1777 safelyVisitChildren(topLevelVariables, visitor);
1778 }
1779 }
1780
1781 /**
1782 * A [FieldElement] for a 'const' or 'final' field that has an initializer.
1783 *
1784 * TODO(paulberry): we should rename this class to reflect the fact that it's
1785 * used for both const and final fields. However, we shouldn't do so until
1786 * we've created an API for reading the values of constants; until that API is
1787 * available, clients are likely to read constant values by casting to
1788 * ConstFieldElementImpl, so it would be a breaking change to rename this
1789 * class.
1790 */
1791 class ConstFieldElementImpl extends FieldElementImpl with ConstVariableElement {
1792 /**
1793 * Initialize a newly created synthetic field element to have the given
1794 * [name] and [offset].
1795 */
1796 ConstFieldElementImpl(String name, int offset) : super(name, offset);
1797
1798 /**
1799 * Initialize a newly created field element to have the given [name].
1800 */
1801 ConstFieldElementImpl.forNode(Identifier name) : super.forNode(name);
1802
1803 /**
1804 * Initialize using the given serialized information.
1805 */
1806 ConstFieldElementImpl.forSerialized(
1807 UnlinkedVariable unlinkedVariable, ElementImpl enclosingElement)
1808 : super.forSerialized(unlinkedVariable, enclosingElement);
1809 }
1810
1811 /**
1812 * A field element representing an enum constant.
1813 */
1814 class ConstFieldElementImpl_EnumValue extends ConstFieldElementImpl_ofEnum {
1815 final UnlinkedEnumValue _unlinkedEnumValue;
1816 final int _index;
1817
1818 ConstFieldElementImpl_EnumValue(
1819 EnumElementImpl enumElement, this._unlinkedEnumValue, this._index)
1820 : super(enumElement);
1821
1822 @override
1823 String get documentationComment {
1824 if (_unlinkedEnumValue != null) {
1825 return _unlinkedEnumValue?.documentationComment?.text;
1826 }
1827 return super.documentationComment;
1828 }
1829
1830 @override
1831 EvaluationResultImpl get evaluationResult {
1832 if (_evaluationResult == null) {
1833 Map<String, DartObjectImpl> fieldMap = <String, DartObjectImpl>{
1834 name: new DartObjectImpl(
1835 context.typeProvider.intType, new IntState(_index))
1836 };
1837 DartObjectImpl value =
1838 new DartObjectImpl(type, new GenericState(fieldMap));
1839 _evaluationResult = new EvaluationResultImpl(value);
1840 }
1841 return _evaluationResult;
1842 }
1843
1844 @override
1845 String get name {
1846 if (_unlinkedEnumValue != null) {
1847 return _unlinkedEnumValue.name;
1848 }
1849 return super.name;
1850 }
1851
1852 @override
1853 int get nameOffset {
1854 if (_unlinkedEnumValue != null) {
1855 return _unlinkedEnumValue.nameOffset;
1856 }
1857 return super.nameOffset;
1858 }
1859
1860 @override
1861 InterfaceType get type => _enum.type;
1862 }
1863
1864 /**
1865 * The synthetic `values` field of an enum.
1866 */
1867 class ConstFieldElementImpl_EnumValues extends ConstFieldElementImpl_ofEnum {
1868 ConstFieldElementImpl_EnumValues(EnumElementImpl enumElement)
1869 : super(enumElement) {
1870 synthetic = true;
1871 }
1872
1873 @override
1874 EvaluationResultImpl get evaluationResult {
1875 if (_evaluationResult == null) {
1876 List<DartObjectImpl> constantValues = <DartObjectImpl>[];
1877 for (FieldElement field in _enum.fields) {
1878 if (field is ConstFieldElementImpl_EnumValue) {
1879 constantValues.add(field.evaluationResult.value);
1880 }
1881 }
1882 _evaluationResult = new EvaluationResultImpl(
1883 new DartObjectImpl(type, new ListState(constantValues)));
1884 }
1885 return _evaluationResult;
1886 }
1887
1888 @override
1889 String get name => 'values';
1890
1891 @override
1892 InterfaceType get type {
1893 if (_type == null) {
1894 InterfaceType listType = context.typeProvider.listType;
1895 return _type = listType.instantiate(<DartType>[_enum.type]);
1896 }
1897 return _type;
1898 }
1899 }
1900
1901 /**
1902 * An abstract constant field of an enum.
1903 */
1904 abstract class ConstFieldElementImpl_ofEnum extends ConstFieldElementImpl {
1905 final EnumElementImpl _enum;
1906
1907 ConstFieldElementImpl_ofEnum(this._enum) : super(null, -1) {
1908 enclosingElement = _enum;
1909 }
1910
1911 @override
1912 void set const3(bool isConst) {
1913 assert(false);
1914 }
1915
1916 @override
1917 void set evaluationResult(_) {
1918 assert(false);
1919 }
1920
1921 @override
1922 void set final2(bool isFinal) {
1923 assert(false);
1924 }
1925
1926 @override
1927 bool get isConst => true;
1928
1929 @override
1930 bool get isStatic => true;
1931
1932 @override
1933 void set static(bool isStatic) {
1934 assert(false);
1935 }
1936
1937 void set type(DartType type) {
1938 assert(false);
1939 }
1940 }
1941
1942 /**
1943 * A [LocalVariableElement] for a local 'const' variable that has an
1944 * initializer.
1945 */
1946 class ConstLocalVariableElementImpl extends LocalVariableElementImpl
1947 with ConstVariableElement {
1948 /**
1949 * Initialize a newly created local variable element to have the given [name]
1950 * and [offset].
1951 */
1952 ConstLocalVariableElementImpl(String name, int offset) : super(name, offset);
1953
1954 /**
1955 * Initialize a newly created local variable element to have the given [name].
1956 */
1957 ConstLocalVariableElementImpl.forNode(Identifier name) : super.forNode(name);
1958
1959 /**
1960 * Initialize using the given serialized information.
1961 */
1962 ConstLocalVariableElementImpl.forSerialized(UnlinkedVariable unlinkedVariable,
1963 ExecutableElementImpl enclosingExecutable)
1964 : super.forSerialized(unlinkedVariable, enclosingExecutable);
1965 }
1966
1967 /**
1968 * A concrete implementation of a [ConstructorElement].
1969 */
1970 class ConstructorElementImpl extends ExecutableElementImpl
1971 implements ConstructorElement {
1972 /**
1973 * The constructor to which this constructor is redirecting.
1974 */
1975 ConstructorElement _redirectedConstructor;
1976
1977 /**
1978 * The initializers for this constructor (used for evaluating constant
1979 * instance creation expressions).
1980 */
1981 List<ConstructorInitializer> _constantInitializers;
1982
1983 /**
1984 * The offset of the `.` before this constructor name or `null` if not named.
1985 */
1986 int _periodOffset;
1987
1988 /**
1989 * Return the offset of the character immediately following the last character
1990 * of this constructor's name, or `null` if not named.
1991 */
1992 int _nameEnd;
1993
1994 /**
1995 * True if this constructor has been found by constant evaluation to be free
1996 * of redirect cycles, and is thus safe to evaluate.
1997 */
1998 bool _isCycleFree = false;
1999
2000 /**
2001 * Initialize a newly created constructor element to have the given [name] and
2002 * [offset].
2003 */
2004 ConstructorElementImpl(String name, int offset) : super(name, offset);
2005
2006 /**
2007 * Initialize a newly created constructor element to have the given [name].
2008 */
2009 ConstructorElementImpl.forNode(Identifier name) : super.forNode(name);
2010
2011 /**
2012 * Initialize using the given serialized information.
2013 */
2014 ConstructorElementImpl.forSerialized(
2015 UnlinkedExecutable serializedExecutable, ClassElementImpl enclosingClass)
2016 : super.forSerialized(serializedExecutable, enclosingClass);
2017
2018 /**
2019 * Set whether this constructor represents a 'const' constructor.
2020 */
2021 void set const2(bool isConst) {
2022 assert(serializedExecutable == null);
2023 setModifier(Modifier.CONST, isConst);
2024 }
2025
2026 List<ConstructorInitializer> get constantInitializers {
2027 if (serializedExecutable != null && _constantInitializers == null) {
2028 _constantInitializers ??= serializedExecutable.constantInitializers
2029 .map((i) => _buildConstructorInitializer(i))
2030 .toList(growable: false);
2031 }
2032 return _constantInitializers;
2033 }
2034
2035 void set constantInitializers(
2036 List<ConstructorInitializer> constantInitializers) {
2037 assert(serializedExecutable == null);
2038 _constantInitializers = constantInitializers;
2039 }
2040
2041 @override
2042 ClassElementImpl get enclosingElement =>
2043 super.enclosingElement as ClassElementImpl;
2044
2045 @override
2046 TypeParameterizedElementMixin get enclosingTypeParameterContext =>
2047 super.enclosingElement as ClassElementImpl;
2048
2049 /**
2050 * Set whether this constructor represents a factory method.
2051 */
2052 void set factory(bool isFactory) {
2053 assert(serializedExecutable == null);
2054 setModifier(Modifier.FACTORY, isFactory);
2055 }
2056
2057 @override
2058 bool get isConst {
2059 if (serializedExecutable != null) {
2060 return serializedExecutable.isConst;
2061 }
2062 return hasModifier(Modifier.CONST);
2063 }
2064
2065 bool get isCycleFree {
2066 if (serializedExecutable != null) {
2067 return serializedExecutable.isConst &&
2068 !enclosingUnit.resynthesizerContext
2069 .isInConstCycle(serializedExecutable.constCycleSlot);
2070 }
2071 return _isCycleFree;
2072 }
2073
2074 void set isCycleFree(bool isCycleFree) {
2075 // This property is updated in ConstantEvaluationEngine even for
2076 // resynthesized constructors, so we don't have the usual assert here.
2077 _isCycleFree = isCycleFree;
2078 }
2079
2080 @override
2081 bool get isDefaultConstructor {
2082 // unnamed
2083 String name = this.name;
2084 if (name != null && name.length != 0) {
2085 return false;
2086 }
2087 // no required parameters
2088 for (ParameterElement parameter in parameters) {
2089 if (parameter.parameterKind == ParameterKind.REQUIRED) {
2090 return false;
2091 }
2092 }
2093 // OK, can be used as default constructor
2094 return true;
2095 }
2096
2097 @override
2098 bool get isFactory {
2099 if (serializedExecutable != null) {
2100 return serializedExecutable.isFactory;
2101 }
2102 return hasModifier(Modifier.FACTORY);
2103 }
2104
2105 @override
2106 bool get isStatic => false;
2107
2108 @override
2109 ElementKind get kind => ElementKind.CONSTRUCTOR;
2110
2111 @override
2112 int get nameEnd {
2113 if (serializedExecutable != null) {
2114 if (serializedExecutable.name.isNotEmpty) {
2115 return serializedExecutable.nameEnd;
2116 } else {
2117 return serializedExecutable.nameOffset + enclosingElement.name.length;
2118 }
2119 }
2120 return _nameEnd;
2121 }
2122
2123 void set nameEnd(int nameEnd) {
2124 assert(serializedExecutable == null);
2125 _nameEnd = nameEnd;
2126 }
2127
2128 @override
2129 int get periodOffset {
2130 if (serializedExecutable != null) {
2131 if (serializedExecutable.name.isNotEmpty) {
2132 return serializedExecutable.periodOffset;
2133 }
2134 }
2135 return _periodOffset;
2136 }
2137
2138 void set periodOffset(int periodOffset) {
2139 assert(serializedExecutable == null);
2140 _periodOffset = periodOffset;
2141 }
2142
2143 @override
2144 ConstructorElement get redirectedConstructor {
2145 if (serializedExecutable != null && _redirectedConstructor == null) {
2146 if (serializedExecutable.isRedirectedConstructor) {
2147 if (serializedExecutable.isFactory) {
2148 _redirectedConstructor = enclosingUnit.resynthesizerContext
2149 .resolveConstructorRef(
2150 enclosingElement, serializedExecutable.redirectedConstructor);
2151 } else {
2152 _redirectedConstructor = enclosingElement.getNamedConstructor(
2153 serializedExecutable.redirectedConstructorName);
2154 }
2155 } else {
2156 return null;
2157 }
2158 }
2159 return _redirectedConstructor;
2160 }
2161
2162 void set redirectedConstructor(ConstructorElement redirectedConstructor) {
2163 assert(serializedExecutable == null);
2164 _redirectedConstructor = redirectedConstructor;
2165 }
2166
2167 @override
2168 DartType get returnType => enclosingElement.type;
2169
2170 void set returnType(DartType returnType) {
2171 assert(false);
2172 }
2173
2174 @override
2175 FunctionType get type {
2176 return _type ??= new FunctionTypeImpl(this);
2177 }
2178
2179 void set type(FunctionType type) {
2180 assert(false);
2181 }
2182
2183 @override
2184 accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
2185
2186 @override
2187 void appendTo(StringBuffer buffer) {
2188 if (enclosingElement == null) {
2189 String message;
2190 String name = displayName;
2191 if (name != null && !name.isEmpty) {
2192 message =
2193 'Found constructor element named $name with no enclosing element';
2194 } else {
2195 message = 'Found unnamed constructor element with no enclosing element';
2196 }
2197 AnalysisEngine.instance.logger.logError(message);
2198 buffer.write('<unknown class>');
2199 } else {
2200 buffer.write(enclosingElement.displayName);
2201 }
2202 String name = displayName;
2203 if (name != null && !name.isEmpty) {
2204 buffer.write(".");
2205 buffer.write(name);
2206 }
2207 super.appendTo(buffer);
2208 }
2209
2210 @override
2211 ConstructorDeclaration computeNode() =>
2212 getNodeMatching((node) => node is ConstructorDeclaration);
2213
2214 /**
2215 * Resynthesize the AST for the given serialized constructor initializer.
2216 */
2217 ConstructorInitializer _buildConstructorInitializer(
2218 UnlinkedConstructorInitializer serialized) {
2219 UnlinkedConstructorInitializerKind kind = serialized.kind;
2220 String name = serialized.name;
2221 List<Expression> arguments = <Expression>[];
2222 {
2223 int numArguments = serialized.arguments.length;
2224 int numNames = serialized.argumentNames.length;
2225 for (int i = 0; i < numArguments; i++) {
2226 Expression expression = enclosingUnit.resynthesizerContext
2227 .buildExpression(this, serialized.arguments[i]);
2228 int nameIndex = numNames + i - numArguments;
2229 if (nameIndex >= 0) {
2230 expression = AstFactory.namedExpression2(
2231 serialized.argumentNames[nameIndex], expression);
2232 }
2233 arguments.add(expression);
2234 }
2235 }
2236 switch (kind) {
2237 case UnlinkedConstructorInitializerKind.field:
2238 ConstructorFieldInitializer initializer =
2239 AstFactory.constructorFieldInitializer(
2240 false,
2241 name,
2242 enclosingUnit.resynthesizerContext
2243 .buildExpression(this, serialized.expression));
2244 initializer.fieldName.staticElement = enclosingElement.getField(name);
2245 return initializer;
2246 case UnlinkedConstructorInitializerKind.superInvocation:
2247 SuperConstructorInvocation initializer =
2248 AstFactory.superConstructorInvocation2(
2249 name.isNotEmpty ? name : null, arguments);
2250 ClassElement superElement = enclosingElement.supertype.element;
2251 ConstructorElement element = name.isEmpty
2252 ? superElement.unnamedConstructor
2253 : superElement.getNamedConstructor(name);
2254 initializer.staticElement = element;
2255 initializer.constructorName?.staticElement = element;
2256 return initializer;
2257 case UnlinkedConstructorInitializerKind.thisInvocation:
2258 RedirectingConstructorInvocation initializer =
2259 AstFactory.redirectingConstructorInvocation2(
2260 name.isNotEmpty ? name : null, arguments);
2261 ConstructorElement element = name.isEmpty
2262 ? enclosingElement.unnamedConstructor
2263 : enclosingElement.getNamedConstructor(name);
2264 initializer.staticElement = element;
2265 initializer.constructorName?.staticElement = element;
2266 return initializer;
2267 }
2268 return null;
2269 }
2270 }
2271
2272 /**
2273 * A [TopLevelVariableElement] for a top-level 'const' variable that has an
2274 * initializer.
2275 */
2276 class ConstTopLevelVariableElementImpl extends TopLevelVariableElementImpl
2277 with ConstVariableElement {
2278 /**
2279 * Initialize a newly created synthetic top-level variable element to have the
2280 * given [name] and [offset].
2281 */
2282 ConstTopLevelVariableElementImpl(String name, int offset)
2283 : super(name, offset);
2284
2285 /**
2286 * Initialize a newly created top-level variable element to have the given
2287 * [name].
2288 */
2289 ConstTopLevelVariableElementImpl.forNode(Identifier name)
2290 : super.forNode(name);
2291
2292 /**
2293 * Initialize using the given serialized information.
2294 */
2295 ConstTopLevelVariableElementImpl.forSerialized(
2296 UnlinkedVariable unlinkedVariable, ElementImpl enclosingElement)
2297 : super.forSerialized(unlinkedVariable, enclosingElement);
2298 }
2299
2300 /**
2301 * Mixin used by elements that represent constant variables and have
2302 * initializers.
2303 *
2304 * Note that in correct Dart code, all constant variables must have
2305 * initializers. However, analyzer also needs to handle incorrect Dart code,
2306 * in which case there might be some constant variables that lack initializers.
2307 * This interface is only used for constant variables that have initializers.
2308 *
2309 * This class is not intended to be part of the public API for analyzer.
2310 */
2311 abstract class ConstVariableElement
2312 implements ElementImpl, ConstantEvaluationTarget {
2313 /**
2314 * If this element represents a constant variable, and it has an initializer,
2315 * a copy of the initializer for the constant. Otherwise `null`.
2316 *
2317 * Note that in correct Dart code, all constant variables must have
2318 * initializers. However, analyzer also needs to handle incorrect Dart code,
2319 * in which case there might be some constant variables that lack
2320 * initializers.
2321 */
2322 Expression _constantInitializer;
2323
2324 EvaluationResultImpl _evaluationResult;
2325
2326 Expression get constantInitializer {
2327 if (_constantInitializer == null && _unlinkedConst != null) {
2328 _constantInitializer = enclosingUnit.resynthesizerContext
2329 .buildExpression(this, _unlinkedConst);
2330 }
2331 return _constantInitializer;
2332 }
2333
2334 void set constantInitializer(Expression constantInitializer) {
2335 assert(_unlinkedConst == null);
2336 _constantInitializer = constantInitializer;
2337 }
2338
2339 EvaluationResultImpl get evaluationResult => _evaluationResult;
2340
2341 void set evaluationResult(EvaluationResultImpl evaluationResult) {
2342 _evaluationResult = evaluationResult;
2343 }
2344
2345 /**
2346 * If this element is resynthesized from the summary, return the unlinked
2347 * initializer, otherwise return `null`.
2348 */
2349 UnlinkedConst get _unlinkedConst;
2350
2351 /**
2352 * Return a representation of the value of this variable, forcing the value
2353 * to be computed if it had not previously been computed, or `null` if either
2354 * this variable was not declared with the 'const' modifier or if the value of
2355 * this variable could not be computed because of errors.
2356 */
2357 DartObject computeConstantValue() {
2358 if (evaluationResult == null) {
2359 context?.computeResult(this, CONSTANT_VALUE);
2360 }
2361 return evaluationResult?.value;
2362 }
2363 }
2364
2365 /**
2366 * A [FieldFormalParameterElementImpl] for parameters that have an initializer.
2367 */
2368 class DefaultFieldFormalParameterElementImpl
2369 extends FieldFormalParameterElementImpl with ConstVariableElement {
2370 /**
2371 * Initialize a newly created parameter element to have the given [name] and
2372 * [nameOffset].
2373 */
2374 DefaultFieldFormalParameterElementImpl(String name, int nameOffset)
2375 : super(name, nameOffset);
2376
2377 /**
2378 * Initialize a newly created parameter element to have the given [name].
2379 */
2380 DefaultFieldFormalParameterElementImpl.forNode(Identifier name)
2381 : super.forNode(name);
2382
2383 /**
2384 * Initialize using the given serialized information.
2385 */
2386 DefaultFieldFormalParameterElementImpl.forSerialized(
2387 UnlinkedParam unlinkedParam, ElementImpl enclosingElement)
2388 : super.forSerialized(unlinkedParam, enclosingElement);
2389 }
2390
2391 /**
2392 * A [ParameterElement] for parameters that have an initializer.
2393 */
2394 class DefaultParameterElementImpl extends ParameterElementImpl
2395 with ConstVariableElement {
2396 /**
2397 * Initialize a newly created parameter element to have the given [name] and
2398 * [nameOffset].
2399 */
2400 DefaultParameterElementImpl(String name, int nameOffset)
2401 : super(name, nameOffset);
2402
2403 /**
2404 * Initialize a newly created parameter element to have the given [name].
2405 */
2406 DefaultParameterElementImpl.forNode(Identifier name) : super.forNode(name);
2407
2408 /**
2409 * Initialize using the given serialized information.
2410 */
2411 DefaultParameterElementImpl.forSerialized(
2412 UnlinkedParam unlinkedParam, ElementImpl enclosingElement)
2413 : super.forSerialized(unlinkedParam, enclosingElement);
2414
2415 @override
2416 DefaultFormalParameter computeNode() =>
2417 getNodeMatching((node) => node is DefaultFormalParameter);
2418 }
2419
2420 /**
2421 * The synthetic element representing the declaration of the type `dynamic`.
2422 */
2423 class DynamicElementImpl extends ElementImpl implements TypeDefiningElement {
2424 /**
2425 * Return the unique instance of this class.
2426 */
2427 static DynamicElementImpl get instance =>
2428 DynamicTypeImpl.instance.element as DynamicElementImpl;
2429
2430 @override
2431 DynamicTypeImpl type;
2432
2433 /**
2434 * Initialize a newly created instance of this class. Instances of this class
2435 * should <b>not</b> be created except as part of creating the type associated
2436 * with this element. The single instance of this class should be accessed
2437 * through the method [instance].
2438 */
2439 DynamicElementImpl() : super(Keyword.DYNAMIC.syntax, -1) {
2440 setModifier(Modifier.SYNTHETIC, true);
2441 }
2442
2443 @override
2444 ElementKind get kind => ElementKind.DYNAMIC;
2445
2446 @override
2447 accept(ElementVisitor visitor) => null;
2448 }
2449
2450 /**
2451 * A concrete implementation of an [ElementAnnotation].
2452 */
2453 class ElementAnnotationImpl implements ElementAnnotation {
2454 /**
2455 * The name of the top-level variable used to mark a method parameter as
2456 * covariant.
2457 */
2458 static String _COVARIANT_VARIABLE_NAME = "checked";
2459
2460 /**
2461 * The name of the class used to mark an element as being deprecated.
2462 */
2463 static String _DEPRECATED_CLASS_NAME = "Deprecated";
2464
2465 /**
2466 * The name of the top-level variable used to mark an element as being
2467 * deprecated.
2468 */
2469 static String _DEPRECATED_VARIABLE_NAME = "deprecated";
2470
2471 /**
2472 * The name of the top-level variable used to mark a method as being a
2473 * factory.
2474 */
2475 static String _FACTORY_VARIABLE_NAME = "factory";
2476
2477 /**
2478 * The name of the class used to JS annotate an element.
2479 */
2480 static String _JS_CLASS_NAME = "JS";
2481
2482 /**
2483 * The name of `js` library, used to define JS annotations.
2484 */
2485 static String _JS_LIB_NAME = "js";
2486
2487 /**
2488 * The name of `meta` library, used to define analysis annotations.
2489 */
2490 static String _META_LIB_NAME = "meta";
2491
2492 /**
2493 * The name of the top-level variable used to mark a method as requiring
2494 * overriders to call super.
2495 */
2496 static String _MUST_CALL_SUPER_VARIABLE_NAME = "mustCallSuper";
2497
2498 /**
2499 * The name of the top-level variable used to mark a method as being expected
2500 * to override an inherited method.
2501 */
2502 static String _OVERRIDE_VARIABLE_NAME = "override";
2503
2504 /**
2505 * The name of the top-level variable used to mark a method as being
2506 * protected.
2507 */
2508 static String _PROTECTED_VARIABLE_NAME = "protected";
2509
2510 /**
2511 * The name of the top-level variable used to mark a class as implementing a
2512 * proxy object.
2513 */
2514 static String PROXY_VARIABLE_NAME = "proxy";
2515
2516 /**
2517 * The name of the class used to mark a parameter as being required.
2518 */
2519 static String _REQUIRED_CLASS_NAME = "Required";
2520
2521 /**
2522 * The name of the top-level variable used to mark a parameter as being
2523 * required.
2524 */
2525 static String _REQUIRED_VARIABLE_NAME = "required";
2526
2527 /**
2528 * The name of the top-level variable used to mark a member as intended to be
2529 * overridden.
2530 */
2531 static String _VIRTUAL_VARIABLE_NAME = "virtual";
2532
2533 /**
2534 * The element representing the field, variable, or constructor being used as
2535 * an annotation.
2536 */
2537 Element element;
2538
2539 /**
2540 * The compilation unit in which this annotation appears.
2541 */
2542 CompilationUnitElementImpl compilationUnit;
2543
2544 /**
2545 * The AST of the annotation itself, cloned from the resolved AST for the
2546 * source code.
2547 */
2548 Annotation annotationAst;
2549
2550 /**
2551 * The result of evaluating this annotation as a compile-time constant
2552 * expression, or `null` if the compilation unit containing the variable has
2553 * not been resolved.
2554 */
2555 EvaluationResultImpl evaluationResult;
2556
2557 /**
2558 * Initialize a newly created annotation. The given [compilationUnit] is the
2559 * compilation unit in which the annotation appears.
2560 */
2561 ElementAnnotationImpl(this.compilationUnit);
2562
2563 @override
2564 DartObject get constantValue => evaluationResult?.value;
2565
2566 @override
2567 AnalysisContext get context => compilationUnit.library.context;
2568
2569 /**
2570 * Return `true` if this annotation marks the associated parameter as being
2571 * covariant, meaning it is allowed to have a narrower type in an override.
2572 */
2573 bool get isCovariant =>
2574 element is PropertyAccessorElement &&
2575 element.name == _COVARIANT_VARIABLE_NAME &&
2576 element.library?.name == _META_LIB_NAME;
2577
2578 @override
2579 bool get isDeprecated {
2580 if (element?.library?.isDartCore == true) {
2581 if (element is ConstructorElement) {
2582 return element.enclosingElement.name == _DEPRECATED_CLASS_NAME;
2583 } else if (element is PropertyAccessorElement) {
2584 return element.name == _DEPRECATED_VARIABLE_NAME;
2585 }
2586 }
2587 return false;
2588 }
2589
2590 @override
2591 bool get isFactory =>
2592 element is PropertyAccessorElement &&
2593 element.name == _FACTORY_VARIABLE_NAME &&
2594 element.library?.name == _META_LIB_NAME;
2595
2596 @override
2597 bool get isJS =>
2598 element is ConstructorElement &&
2599 element.enclosingElement.name == _JS_CLASS_NAME &&
2600 element.library?.name == _JS_LIB_NAME;
2601
2602 @override
2603 bool get isMustCallSuper =>
2604 element is PropertyAccessorElement &&
2605 element.name == _MUST_CALL_SUPER_VARIABLE_NAME &&
2606 element.library?.name == _META_LIB_NAME;
2607
2608 @override
2609 bool get isOverride =>
2610 element is PropertyAccessorElement &&
2611 element.name == _OVERRIDE_VARIABLE_NAME &&
2612 element.library?.isDartCore == true;
2613
2614 @override
2615 bool get isProtected =>
2616 element is PropertyAccessorElement &&
2617 element.name == _PROTECTED_VARIABLE_NAME &&
2618 element.library?.name == _META_LIB_NAME;
2619
2620 @override
2621 bool get isProxy =>
2622 element is PropertyAccessorElement &&
2623 element.name == PROXY_VARIABLE_NAME &&
2624 element.library?.isDartCore == true;
2625
2626 @override
2627 bool get isRequired =>
2628 element is ConstructorElement &&
2629 element.enclosingElement.name == _REQUIRED_CLASS_NAME &&
2630 element.library?.name == _META_LIB_NAME ||
2631 element is PropertyAccessorElement &&
2632 element.name == _REQUIRED_VARIABLE_NAME &&
2633 element.library?.name == _META_LIB_NAME;
2634
2635 /**
2636 * Return `true` if this annotation marks the associated member as supporting
2637 * overrides.
2638 *
2639 * This is currently used by fields in Strong Mode, as other members are
2640 * already virtual-by-default.
2641 */
2642 bool get isVirtual =>
2643 element is PropertyAccessorElement &&
2644 element.name == _VIRTUAL_VARIABLE_NAME &&
2645 element.library?.name == _META_LIB_NAME;
2646
2647 /**
2648 * Get the library containing this annotation.
2649 */
2650 Source get librarySource => compilationUnit.librarySource;
2651
2652 @override
2653 Source get source => compilationUnit.source;
2654
2655 @override
2656 DartObject computeConstantValue() {
2657 if (evaluationResult == null) {
2658 context?.computeResult(this, CONSTANT_VALUE);
2659 }
2660 return constantValue;
2661 }
2662
2663 @override
2664 String toString() => '@$element';
2665 }
2666
2667 /**
2668 * A base class for concrete implementations of an [Element].
2669 */
2670 abstract class ElementImpl implements Element {
2671 /**
2672 * An Unicode right arrow.
2673 */
2674 static final String RIGHT_ARROW = " \u2192 ";
2675
2676 static int _NEXT_ID = 0;
2677
2678 final int id = _NEXT_ID++;
2679
2680 /**
2681 * The enclosing element of this element, or `null` if this element is at the
2682 * root of the element structure.
2683 */
2684 ElementImpl _enclosingElement;
2685
2686 /**
2687 * The name of this element.
2688 */
2689 String _name;
2690
2691 /**
2692 * The offset of the name of this element in the file that contains the
2693 * declaration of this element.
2694 */
2695 int _nameOffset = 0;
2696
2697 /**
2698 * A bit-encoded form of the modifiers associated with this element.
2699 */
2700 int _modifiers = 0;
2701
2702 /**
2703 * A list containing all of the metadata associated with this element.
2704 */
2705 List<ElementAnnotation> _metadata;
2706
2707 /**
2708 * A cached copy of the calculated hashCode for this element.
2709 */
2710 int _cachedHashCode;
2711
2712 /**
2713 * A cached copy of the calculated location for this element.
2714 */
2715 ElementLocation _cachedLocation;
2716
2717 /**
2718 * The documentation comment for this element.
2719 */
2720 String _docComment;
2721
2722 /**
2723 * The offset of the beginning of the element's code in the file that contains
2724 * the element, or `null` if the element is synthetic.
2725 */
2726 int _codeOffset;
2727
2728 /**
2729 * The length of the element's code, or `null` if the element is synthetic.
2730 */
2731 int _codeLength;
2732
2733 /**
2734 * Initialize a newly created element to have the given [name] at the given
2735 * [_nameOffset].
2736 */
2737 ElementImpl(String name, this._nameOffset) {
2738 this._name = StringUtilities.intern(name);
2739 }
2740
2741 /**
2742 * Initialize a newly created element to have the given [name].
2743 */
2744 ElementImpl.forNode(Identifier name)
2745 : this(name == null ? "" : name.name, name == null ? -1 : name.offset);
2746
2747 /**
2748 * Initialize from serialized information.
2749 */
2750 ElementImpl.forSerialized(this._enclosingElement);
2751
2752 /**
2753 * The length of the element's code, or `null` if the element is synthetic.
2754 */
2755 int get codeLength => _codeLength;
2756
2757 /**
2758 * The offset of the beginning of the element's code in the file that contains
2759 * the element, or `null` if the element is synthetic.
2760 */
2761 int get codeOffset => _codeOffset;
2762
2763 @override
2764 AnalysisContext get context {
2765 if (_enclosingElement == null) {
2766 return null;
2767 }
2768 return _enclosingElement.context;
2769 }
2770
2771 @override
2772 String get displayName => _name;
2773
2774 @override
2775 String get documentationComment => _docComment;
2776
2777 /**
2778 * The documentation comment source for this element.
2779 */
2780 void set documentationComment(String doc) {
2781 assert(!isResynthesized);
2782 _docComment = doc?.replaceAll('\r\n', '\n');
2783 }
2784
2785 @override
2786 Element get enclosingElement => _enclosingElement;
2787
2788 /**
2789 * Set the enclosing element of this element to the given [element].
2790 *
2791 * Throws [FrozenHashCodeException] if the hashCode can't be changed.
2792 */
2793 void set enclosingElement(Element element) {
2794 _enclosingElement = element as ElementImpl;
2795 }
2796
2797 /**
2798 * Return the enclosing unit element (which might be the same as `this`), or
2799 * `null` if this element is not contained in any compilation unit.
2800 */
2801 CompilationUnitElementImpl get enclosingUnit {
2802 return _enclosingElement?.enclosingUnit;
2803 }
2804
2805 @override
2806 int get hashCode {
2807 // TODO: We might want to re-visit this optimization in the future.
2808 // We cache the hash code value as this is a very frequently called method.
2809 if (_cachedHashCode == null) {
2810 _cachedHashCode = location.hashCode;
2811 }
2812 return _cachedHashCode;
2813 }
2814
2815 /**
2816 * Return an identifier that uniquely identifies this element among the
2817 * children of this element's parent.
2818 */
2819 String get identifier => name;
2820
2821 @override
2822 bool get isDeprecated {
2823 for (ElementAnnotation annotation in metadata) {
2824 if (annotation.isDeprecated) {
2825 return true;
2826 }
2827 }
2828 return false;
2829 }
2830
2831 @override
2832 bool get isFactory {
2833 for (ElementAnnotation annotation in metadata) {
2834 if (annotation.isFactory) {
2835 return true;
2836 }
2837 }
2838 return false;
2839 }
2840
2841 @override
2842 bool get isJS {
2843 for (ElementAnnotation annotation in metadata) {
2844 if (annotation.isJS) {
2845 return true;
2846 }
2847 }
2848 return false;
2849 }
2850
2851 @override
2852 bool get isOverride {
2853 for (ElementAnnotation annotation in metadata) {
2854 if (annotation.isOverride) {
2855 return true;
2856 }
2857 }
2858 return false;
2859 }
2860
2861 @override
2862 bool get isPrivate {
2863 String name = displayName;
2864 if (name == null) {
2865 return true;
2866 }
2867 return Identifier.isPrivateName(name);
2868 }
2869
2870 @override
2871 bool get isProtected {
2872 for (ElementAnnotation annotation in metadata) {
2873 if (annotation.isProtected) {
2874 return true;
2875 }
2876 }
2877 return false;
2878 }
2879
2880 @override
2881 bool get isPublic => !isPrivate;
2882
2883 @override
2884 bool get isRequired {
2885 for (ElementAnnotation annotation in metadata) {
2886 if (annotation.isRequired) {
2887 return true;
2888 }
2889 }
2890 return false;
2891 }
2892
2893 /**
2894 * Return `true` if this element is resynthesized from a summary.
2895 */
2896 bool get isResynthesized => enclosingUnit?.resynthesizerContext != null;
2897
2898 @override
2899 bool get isSynthetic => hasModifier(Modifier.SYNTHETIC);
2900
2901 @override
2902 LibraryElement get library =>
2903 getAncestor((element) => element is LibraryElement);
2904
2905 @override
2906 Source get librarySource => library?.source;
2907
2908 @override
2909 ElementLocation get location {
2910 if (_cachedLocation == null) {
2911 if (library == null) {
2912 return new ElementLocationImpl.con1(this);
2913 }
2914 _cachedLocation = new ElementLocationImpl.con1(this);
2915 }
2916 return _cachedLocation;
2917 }
2918
2919 List<ElementAnnotation> get metadata {
2920 return _metadata ?? const <ElementAnnotation>[];
2921 }
2922
2923 void set metadata(List<ElementAnnotation> metadata) {
2924 assert(!isResynthesized);
2925 _metadata = metadata;
2926 }
2927
2928 @override
2929 String get name => _name;
2930
2931 /**
2932 * Changes the name of this element.
2933 *
2934 * Throws [FrozenHashCodeException] if the hashCode can't be changed.
2935 */
2936 void set name(String name) {
2937 this._name = name;
2938 }
2939
2940 @override
2941 int get nameLength => displayName != null ? displayName.length : 0;
2942
2943 @override
2944 int get nameOffset => _nameOffset;
2945
2946 /**
2947 * Sets the offset of the name of this element in the file that contains the
2948 * declaration of this element.
2949 *
2950 * Throws [FrozenHashCodeException] if the hashCode can't be changed.
2951 */
2952 void set nameOffset(int offset) {
2953 _nameOffset = offset;
2954 }
2955
2956 @override
2957 Source get source {
2958 if (_enclosingElement == null) {
2959 return null;
2960 }
2961 return _enclosingElement.source;
2962 }
2963
2964 /**
2965 * Set whether this element is synthetic.
2966 */
2967 void set synthetic(bool isSynthetic) {
2968 setModifier(Modifier.SYNTHETIC, isSynthetic);
2969 }
2970
2971 /**
2972 * Return the context to resolve type parameters in, or `null` if neither this
2973 * element nor any of its ancestors is of a kind that can declare type
2974 * parameters.
2975 */
2976 TypeParameterizedElementMixin get typeParameterContext {
2977 return _enclosingElement?.typeParameterContext;
2978 }
2979
2980 @override
2981 CompilationUnit get unit => context.resolveCompilationUnit(source, library);
2982
2983 @override
2984 bool operator ==(Object object) {
2985 if (identical(this, object)) {
2986 return true;
2987 }
2988 return object is Element &&
2989 object.kind == kind &&
2990 object.location == location;
2991 }
2992
2993 /**
2994 * Append to the given [buffer] a comma-separated list of the names of the
2995 * types of this element and every enclosing element.
2996 */
2997 void appendPathTo(StringBuffer buffer) {
2998 Element element = this;
2999 while (element != null) {
3000 if (element != this) {
3001 buffer.write(', ');
3002 }
3003 buffer.write(element.runtimeType);
3004 String name = element.name;
3005 if (name != null) {
3006 buffer.write(' (');
3007 buffer.write(name);
3008 buffer.write(')');
3009 }
3010 element = element.enclosingElement;
3011 }
3012 }
3013
3014 /**
3015 * Append a textual representation of this element to the given [buffer].
3016 */
3017 void appendTo(StringBuffer buffer) {
3018 if (_name == null) {
3019 buffer.write("<unnamed ");
3020 buffer.write(runtimeType.toString());
3021 buffer.write(">");
3022 } else {
3023 buffer.write(_name);
3024 }
3025 }
3026
3027 @override
3028 String computeDocumentationComment() => documentationComment;
3029
3030 @override
3031 AstNode computeNode() => getNodeMatching((node) => node is AstNode);
3032
3033 /**
3034 * Set this element as the enclosing element for given [element].
3035 */
3036 void encloseElement(ElementImpl element) {
3037 element.enclosingElement = this;
3038 }
3039
3040 @override
3041 Element/*=E*/ getAncestor/*<E extends Element >*/(
3042 Predicate<Element> predicate) {
3043 Element ancestor = _enclosingElement;
3044 while (ancestor != null && !predicate(ancestor)) {
3045 ancestor = ancestor.enclosingElement;
3046 }
3047 return ancestor as Element/*=E*/;
3048 }
3049
3050 /**
3051 * Return the child of this element that is uniquely identified by the given
3052 * [identifier], or `null` if there is no such child.
3053 */
3054 ElementImpl getChild(String identifier) => null;
3055
3056 @override
3057 String getExtendedDisplayName(String shortName) {
3058 if (shortName == null) {
3059 shortName = displayName;
3060 }
3061 Source source = this.source;
3062 if (source != null) {
3063 return "$shortName (${source.fullName})";
3064 }
3065 return shortName;
3066 }
3067
3068 /**
3069 * Return the resolved [AstNode] of the given type enclosing [getNameOffset].
3070 */
3071 AstNode getNodeMatching(Predicate<AstNode> predicate) {
3072 CompilationUnit unit = this.unit;
3073 if (unit == null) {
3074 return null;
3075 }
3076 int offset = nameOffset;
3077 AstNode node = new NodeLocator(offset).searchWithin(unit);
3078 if (node == null) {
3079 return null;
3080 }
3081 return node.getAncestor(predicate);
3082 }
3083
3084 /**
3085 * Return `true` if this element has the given [modifier] associated with it.
3086 */
3087 bool hasModifier(Modifier modifier) =>
3088 BooleanArray.get(_modifiers, modifier.ordinal);
3089
3090 @override
3091 bool isAccessibleIn(LibraryElement library) {
3092 if (Identifier.isPrivateName(name)) {
3093 return library == this.library;
3094 }
3095 return true;
3096 }
3097
3098 /**
3099 * Use the given [visitor] to visit all of the [children] in the given array.
3100 */
3101 void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
3102 if (children != null) {
3103 for (Element child in children) {
3104 child.accept(visitor);
3105 }
3106 }
3107 }
3108
3109 /**
3110 * Set the code range for this element.
3111 */
3112 void setCodeRange(int offset, int length) {
3113 assert(!isResynthesized);
3114 _codeOffset = offset;
3115 _codeLength = length;
3116 }
3117
3118 /**
3119 * Set whether the given [modifier] is associated with this element to
3120 * correspond to the given [value].
3121 */
3122 void setModifier(Modifier modifier, bool value) {
3123 _modifiers = BooleanArray.set(_modifiers, modifier.ordinal, value);
3124 }
3125
3126 @override
3127 String toString() {
3128 StringBuffer buffer = new StringBuffer();
3129 appendTo(buffer);
3130 return buffer.toString();
3131 }
3132
3133 @override
3134 void visitChildren(ElementVisitor visitor) {
3135 // There are no children to visit
3136 }
3137
3138 /**
3139 * Return annotations for the given [unlinkedConsts] in the [unit].
3140 */
3141 List<ElementAnnotation> _buildAnnotations(
3142 CompilationUnitElementImpl unit, List<UnlinkedConst> unlinkedConsts) {
3143 int length = unlinkedConsts.length;
3144 if (length != 0) {
3145 List<ElementAnnotation> annotations = new List<ElementAnnotation>(length);
3146 ResynthesizerContext context = unit.resynthesizerContext;
3147 for (int i = 0; i < length; i++) {
3148 annotations[i] = context.buildAnnotation(this, unlinkedConsts[i]);
3149 }
3150 return annotations;
3151 } else {
3152 return const <ElementAnnotation>[];
3153 }
3154 }
3155
3156 static int _findElementIndexUsingIdentical(List items, Object item) {
3157 int length = items.length;
3158 for (int i = 0; i < length; i++) {
3159 if (identical(items[i], item)) {
3160 return i;
3161 }
3162 }
3163 throw new StateError('Unable to find $item in $items');
3164 }
3165 }
3166
3167 /**
3168 * A concrete implementation of an [ElementLocation].
3169 */
3170 class ElementLocationImpl implements ElementLocation {
3171 /**
3172 * The character used to separate components in the encoded form.
3173 */
3174 static int _SEPARATOR_CHAR = 0x3B;
3175
3176 /**
3177 * The path to the element whose location is represented by this object.
3178 */
3179 List<String> _components;
3180
3181 /**
3182 * The object managing [indexKeyId] and [indexLocationId].
3183 */
3184 Object indexOwner;
3185
3186 /**
3187 * A cached id of this location in index.
3188 */
3189 int indexKeyId;
3190
3191 /**
3192 * A cached id of this location in index.
3193 */
3194 int indexLocationId;
3195
3196 /**
3197 * Initialize a newly created location to represent the given [element].
3198 */
3199 ElementLocationImpl.con1(Element element) {
3200 List<String> components = new List<String>();
3201 Element ancestor = element;
3202 while (ancestor != null) {
3203 components.insert(0, (ancestor as ElementImpl).identifier);
3204 ancestor = ancestor.enclosingElement;
3205 }
3206 this._components = components;
3207 }
3208
3209 /**
3210 * Initialize a newly created location from the given [encoding].
3211 */
3212 ElementLocationImpl.con2(String encoding) {
3213 this._components = _decode(encoding);
3214 }
3215
3216 /**
3217 * Initialize a newly created location from the given [components].
3218 */
3219 ElementLocationImpl.con3(List<String> components) {
3220 this._components = components;
3221 }
3222
3223 @override
3224 List<String> get components => _components;
3225
3226 @override
3227 String get encoding {
3228 StringBuffer buffer = new StringBuffer();
3229 int length = _components.length;
3230 for (int i = 0; i < length; i++) {
3231 if (i > 0) {
3232 buffer.writeCharCode(_SEPARATOR_CHAR);
3233 }
3234 _encode(buffer, _components[i]);
3235 }
3236 return buffer.toString();
3237 }
3238
3239 @override
3240 int get hashCode {
3241 int result = 0;
3242 for (int i = 0; i < _components.length; i++) {
3243 String component = _components[i];
3244 result = JenkinsSmiHash.combine(result, component.hashCode);
3245 }
3246 return result;
3247 }
3248
3249 @override
3250 bool operator ==(Object object) {
3251 if (identical(this, object)) {
3252 return true;
3253 }
3254 if (object is ElementLocationImpl) {
3255 List<String> otherComponents = object._components;
3256 int length = _components.length;
3257 if (otherComponents.length != length) {
3258 return false;
3259 }
3260 for (int i = 0; i < length; i++) {
3261 if (_components[i] != otherComponents[i]) {
3262 return false;
3263 }
3264 }
3265 return true;
3266 }
3267 return false;
3268 }
3269
3270 @override
3271 String toString() => encoding;
3272
3273 /**
3274 * Decode the [encoding] of a location into a list of components and return
3275 * the components.
3276 */
3277 List<String> _decode(String encoding) {
3278 List<String> components = new List<String>();
3279 StringBuffer buffer = new StringBuffer();
3280 int index = 0;
3281 int length = encoding.length;
3282 while (index < length) {
3283 int currentChar = encoding.codeUnitAt(index);
3284 if (currentChar == _SEPARATOR_CHAR) {
3285 if (index + 1 < length &&
3286 encoding.codeUnitAt(index + 1) == _SEPARATOR_CHAR) {
3287 buffer.writeCharCode(_SEPARATOR_CHAR);
3288 index += 2;
3289 } else {
3290 components.add(buffer.toString());
3291 buffer = new StringBuffer();
3292 index++;
3293 }
3294 } else {
3295 buffer.writeCharCode(currentChar);
3296 index++;
3297 }
3298 }
3299 components.add(buffer.toString());
3300 return components;
3301 }
3302
3303 /**
3304 * Append an encoded form of the given [component] to the given [buffer].
3305 */
3306 void _encode(StringBuffer buffer, String component) {
3307 int length = component.length;
3308 for (int i = 0; i < length; i++) {
3309 int currentChar = component.codeUnitAt(i);
3310 if (currentChar == _SEPARATOR_CHAR) {
3311 buffer.writeCharCode(_SEPARATOR_CHAR);
3312 }
3313 buffer.writeCharCode(currentChar);
3314 }
3315 }
3316 }
3317
3318 /**
3319 * An [AbstractClassElementImpl] which is an enum.
3320 */
3321 class EnumElementImpl extends AbstractClassElementImpl {
3322 /**
3323 * The unlinked representation of the enum in the summary.
3324 */
3325 final UnlinkedEnum _unlinkedEnum;
3326
3327 /**
3328 * The type defined by the enum.
3329 */
3330 InterfaceType _type;
3331
3332 /**
3333 * Initialize a newly created class element to have the given [name] at the
3334 * given [offset] in the file that contains the declaration of this element.
3335 */
3336 EnumElementImpl(String name, int offset)
3337 : _unlinkedEnum = null,
3338 super(name, offset);
3339
3340 /**
3341 * Initialize a newly created class element to have the given [name].
3342 */
3343 EnumElementImpl.forNode(Identifier name)
3344 : _unlinkedEnum = null,
3345 super.forNode(name);
3346
3347 /**
3348 * Initialize using the given serialized information.
3349 */
3350 EnumElementImpl.forSerialized(
3351 this._unlinkedEnum, CompilationUnitElementImpl enclosingUnit)
3352 : super.forSerialized(enclosingUnit);
3353
3354 /**
3355 * Set whether this class is abstract.
3356 */
3357 void set abstract(bool isAbstract) {
3358 assert(_unlinkedEnum == null);
3359 }
3360
3361 @override
3362 List<PropertyAccessorElement> get accessors {
3363 if (_unlinkedEnum != null && _accessors == null) {
3364 _resynthesizeFieldsAndPropertyAccessors();
3365 }
3366 return _accessors ?? const <PropertyAccessorElement>[];
3367 }
3368
3369 @override
3370 void set accessors(List<PropertyAccessorElement> accessors) {
3371 assert(_unlinkedEnum == null);
3372 super.accessors = accessors;
3373 }
3374
3375 @override
3376 List<InterfaceType> get allSupertypes => <InterfaceType>[supertype];
3377
3378 @override
3379 int get codeLength {
3380 if (_unlinkedEnum != null) {
3381 return _unlinkedEnum.codeRange?.length;
3382 }
3383 return super.codeLength;
3384 }
3385
3386 @override
3387 int get codeOffset {
3388 if (_unlinkedEnum != null) {
3389 return _unlinkedEnum.codeRange?.offset;
3390 }
3391 return super.codeOffset;
3392 }
3393
3394 @override
3395 List<ConstructorElement> get constructors {
3396 // The equivalent code for enums in the spec shows a single constructor,
3397 // but that constructor is not callable (since it is a compile-time error
3398 // to subclass, mix-in, implement, or explicitly instantiate an enum).
3399 // So we represent this as having no constructors.
3400 return const <ConstructorElement>[];
3401 }
3402
3403 @override
3404 String get documentationComment {
3405 if (_unlinkedEnum != null) {
3406 return _unlinkedEnum?.documentationComment?.text;
3407 }
3408 return super.documentationComment;
3409 }
3410
3411 @override
3412 List<FieldElement> get fields {
3413 if (_unlinkedEnum != null && _fields == null) {
3414 _resynthesizeFieldsAndPropertyAccessors();
3415 }
3416 return _fields ?? const <FieldElement>[];
3417 }
3418
3419 @override
3420 void set fields(List<FieldElement> fields) {
3421 assert(_unlinkedEnum == null);
3422 super.fields = fields;
3423 }
3424
3425 @override
3426 bool get hasNonFinalField => false;
3427
3428 @override
3429 bool get hasReferenceToSuper => false;
3430
3431 @override
3432 bool get hasStaticMember => true;
3433
3434 @override
3435 List<InterfaceType> get interfaces => const <InterfaceType>[];
3436
3437 @override
3438 bool get isAbstract => false;
3439
3440 @override
3441 bool get isEnum => true;
3442
3443 @override
3444 bool get isMixinApplication => false;
3445
3446 @override
3447 bool get isOrInheritsProxy => false;
3448
3449 @override
3450 bool get isProxy => false;
3451
3452 @override
3453 bool get isValidMixin => false;
3454
3455 @override
3456 List<ElementAnnotation> get metadata {
3457 if (_unlinkedEnum != null) {
3458 return _metadata ??=
3459 _buildAnnotations(enclosingUnit, _unlinkedEnum.annotations);
3460 }
3461 return super.metadata;
3462 }
3463
3464 @override
3465 List<MethodElement> get methods => const <MethodElement>[];
3466
3467 @override
3468 List<InterfaceType> get mixins => const <InterfaceType>[];
3469
3470 @override
3471 String get name {
3472 if (_unlinkedEnum != null) {
3473 return _unlinkedEnum.name;
3474 }
3475 return super.name;
3476 }
3477
3478 @override
3479 int get nameOffset {
3480 if (_unlinkedEnum != null) {
3481 return _unlinkedEnum.nameOffset;
3482 }
3483 return super.nameOffset;
3484 }
3485
3486 @override
3487 InterfaceType get supertype => context.typeProvider.objectType;
3488
3489 @override
3490 InterfaceType get type {
3491 if (_type == null) {
3492 InterfaceTypeImpl type = new InterfaceTypeImpl(this);
3493 type.typeArguments = const <DartType>[];
3494 _type = type;
3495 }
3496 return _type;
3497 }
3498
3499 @override
3500 List<TypeParameterElement> get typeParameters =>
3501 const <TypeParameterElement>[];
3502
3503 @override
3504 ConstructorElement get unnamedConstructor => null;
3505
3506 @override
3507 void appendTo(StringBuffer buffer) {
3508 buffer.write('enum ');
3509 String name = displayName;
3510 if (name == null) {
3511 buffer.write("{unnamed enum}");
3512 } else {
3513 buffer.write(name);
3514 }
3515 }
3516
3517 @override
3518 MethodElement getMethod(String name) => null;
3519
3520 @override
3521 ConstructorElement getNamedConstructor(String name) => null;
3522
3523 @override
3524 bool isSuperConstructorAccessible(ConstructorElement constructor) => false;
3525
3526 void _resynthesizeFieldsAndPropertyAccessors() {
3527 List<FieldElementImpl> fields = <FieldElementImpl>[];
3528 // Build the 'index' field.
3529 fields.add(new FieldElementImpl('index', -1)
3530 ..enclosingElement = this
3531 ..synthetic = true
3532 ..final2 = true
3533 ..type = context.typeProvider.intType);
3534 // Build the 'values' field.
3535 fields.add(new ConstFieldElementImpl_EnumValues(this));
3536 // Build fields for all enum constants.
3537 for (int i = 0; i < _unlinkedEnum.values.length; i++) {
3538 UnlinkedEnumValue unlinkedValue = _unlinkedEnum.values[i];
3539 ConstFieldElementImpl_EnumValue field =
3540 new ConstFieldElementImpl_EnumValue(this, unlinkedValue, i);
3541 fields.add(field);
3542 }
3543 // done
3544 _fields = fields;
3545 _accessors = fields
3546 .map((FieldElementImpl field) =>
3547 new PropertyAccessorElementImpl_ImplicitGetter(field)
3548 ..enclosingElement = this)
3549 .toList(growable: false);
3550 }
3551 }
3552
3553 /**
3554 * A base class for concrete implementations of an [ExecutableElement].
3555 */
3556 abstract class ExecutableElementImpl extends ElementImpl
3557 with TypeParameterizedElementMixin
3558 implements ExecutableElement {
3559 /**
3560 * The unlinked representation of the executable in the summary.
3561 */
3562 final UnlinkedExecutable serializedExecutable;
3563
3564 /**
3565 * A list containing all of the functions defined within this executable
3566 * element.
3567 */
3568 List<FunctionElement> _functions;
3569
3570 /**
3571 * A list containing all of the labels defined within this executable element.
3572 */
3573 List<LabelElement> _labels;
3574
3575 /**
3576 * A list containing all of the local variables defined within this executable
3577 * element.
3578 */
3579 List<LocalVariableElement> _localVariables;
3580
3581 /**
3582 * A list containing all of the parameters defined by this executable element.
3583 */
3584 List<ParameterElement> _parameters;
3585
3586 /**
3587 * A list containing all of the type parameters defined for this executable
3588 * element.
3589 */
3590 List<TypeParameterElement> _typeParameters;
3591
3592 /**
3593 * The return type defined by this executable element.
3594 */
3595 DartType _returnType;
3596
3597 /**
3598 * The type of function defined by this executable element.
3599 */
3600 FunctionType _type;
3601
3602 /**
3603 * Initialize a newly created executable element to have the given [name] and
3604 * [offset].
3605 */
3606 ExecutableElementImpl(String name, int offset)
3607 : serializedExecutable = null,
3608 super(name, offset);
3609
3610 /**
3611 * Initialize a newly created executable element to have the given [name].
3612 */
3613 ExecutableElementImpl.forNode(Identifier name)
3614 : serializedExecutable = null,
3615 super.forNode(name);
3616
3617 /**
3618 * Initialize using the given serialized information.
3619 */
3620 ExecutableElementImpl.forSerialized(
3621 this.serializedExecutable, ElementImpl enclosingElement)
3622 : super.forSerialized(enclosingElement);
3623
3624 /**
3625 * Set whether this executable element's body is asynchronous.
3626 */
3627 void set asynchronous(bool isAsynchronous) {
3628 assert(serializedExecutable == null);
3629 setModifier(Modifier.ASYNCHRONOUS, isAsynchronous);
3630 }
3631
3632 @override
3633 int get codeLength {
3634 if (serializedExecutable != null) {
3635 return serializedExecutable.codeRange?.length;
3636 }
3637 return super.codeLength;
3638 }
3639
3640 @override
3641 int get codeOffset {
3642 if (serializedExecutable != null) {
3643 return serializedExecutable.codeRange?.offset;
3644 }
3645 return super.codeOffset;
3646 }
3647
3648 @override
3649 String get displayName {
3650 if (serializedExecutable != null) {
3651 return serializedExecutable.name;
3652 }
3653 return super.displayName;
3654 }
3655
3656 @override
3657 String get documentationComment {
3658 if (serializedExecutable != null) {
3659 return serializedExecutable?.documentationComment?.text;
3660 }
3661 return super.documentationComment;
3662 }
3663
3664 /**
3665 * Set whether this executable element is external.
3666 */
3667 void set external(bool isExternal) {
3668 assert(serializedExecutable == null);
3669 setModifier(Modifier.EXTERNAL, isExternal);
3670 }
3671
3672 @override
3673 List<FunctionElement> get functions {
3674 if (serializedExecutable != null) {
3675 _functions ??= FunctionElementImpl.resynthesizeList(
3676 this, serializedExecutable.localFunctions);
3677 }
3678 return _functions ?? const <FunctionElement>[];
3679 }
3680
3681 /**
3682 * Set the functions defined within this executable element to the given
3683 * [functions].
3684 */
3685 void set functions(List<FunctionElement> functions) {
3686 assert(serializedExecutable == null);
3687 for (FunctionElement function in functions) {
3688 (function as FunctionElementImpl).enclosingElement = this;
3689 }
3690 this._functions = functions;
3691 }
3692
3693 /**
3694 * Set whether this method's body is a generator.
3695 */
3696 void set generator(bool isGenerator) {
3697 assert(serializedExecutable == null);
3698 setModifier(Modifier.GENERATOR, isGenerator);
3699 }
3700
3701 @override
3702 bool get hasImplicitReturnType {
3703 if (serializedExecutable != null) {
3704 return serializedExecutable.returnType == null &&
3705 serializedExecutable.kind != UnlinkedExecutableKind.constructor;
3706 }
3707 return hasModifier(Modifier.IMPLICIT_TYPE);
3708 }
3709
3710 /**
3711 * Set whether this executable element has an implicit return type.
3712 */
3713 void set hasImplicitReturnType(bool hasImplicitReturnType) {
3714 assert(serializedExecutable == null);
3715 setModifier(Modifier.IMPLICIT_TYPE, hasImplicitReturnType);
3716 }
3717
3718 @override
3719 bool get isAbstract {
3720 if (serializedExecutable != null) {
3721 return serializedExecutable.isAbstract;
3722 }
3723 return hasModifier(Modifier.ABSTRACT);
3724 }
3725
3726 @override
3727 bool get isAsynchronous {
3728 if (serializedExecutable != null) {
3729 return serializedExecutable.isAsynchronous;
3730 }
3731 return hasModifier(Modifier.ASYNCHRONOUS);
3732 }
3733
3734 @override
3735 bool get isExternal {
3736 if (serializedExecutable != null) {
3737 return serializedExecutable.isExternal;
3738 }
3739 return hasModifier(Modifier.EXTERNAL);
3740 }
3741
3742 @override
3743 bool get isGenerator {
3744 if (serializedExecutable != null) {
3745 return serializedExecutable.isGenerator;
3746 }
3747 return hasModifier(Modifier.GENERATOR);
3748 }
3749
3750 @override
3751 bool get isOperator => false;
3752
3753 @override
3754 bool get isSynchronous => !isAsynchronous;
3755
3756 @override
3757 List<LabelElement> get labels {
3758 if (serializedExecutable != null) {
3759 _labels ??= LabelElementImpl.resynthesizeList(
3760 this, serializedExecutable.localLabels);
3761 }
3762 return _labels ?? const <LabelElement>[];
3763 }
3764
3765 /**
3766 * Set the labels defined within this executable element to the given
3767 * [labels].
3768 */
3769 void set labels(List<LabelElement> labels) {
3770 assert(serializedExecutable == null);
3771 for (LabelElement label in labels) {
3772 (label as LabelElementImpl).enclosingElement = this;
3773 }
3774 this._labels = labels;
3775 }
3776
3777 @override
3778 List<LocalVariableElement> get localVariables {
3779 if (serializedExecutable != null && _localVariables == null) {
3780 List<UnlinkedVariable> unlinkedVariables =
3781 serializedExecutable.localVariables;
3782 int length = unlinkedVariables.length;
3783 if (length != 0) {
3784 List<LocalVariableElementImpl> localVariables =
3785 new List<LocalVariableElementImpl>(length);
3786 for (int i = 0; i < length; i++) {
3787 localVariables[i] = new LocalVariableElementImpl.forSerializedFactory(
3788 unlinkedVariables[i], this);
3789 }
3790 _localVariables = localVariables;
3791 } else {
3792 _localVariables = const <LocalVariableElement>[];
3793 }
3794 }
3795 return _localVariables ?? const <LocalVariableElement>[];
3796 }
3797
3798 /**
3799 * Set the local variables defined within this executable element to the given
3800 * [variables].
3801 */
3802 void set localVariables(List<LocalVariableElement> variables) {
3803 assert(serializedExecutable == null);
3804 for (LocalVariableElement variable in variables) {
3805 (variable as LocalVariableElementImpl).enclosingElement = this;
3806 }
3807 this._localVariables = variables;
3808 }
3809
3810 @override
3811 List<ElementAnnotation> get metadata {
3812 if (serializedExecutable != null) {
3813 return _metadata ??=
3814 _buildAnnotations(enclosingUnit, serializedExecutable.annotations);
3815 }
3816 return super.metadata;
3817 }
3818
3819 @override
3820 String get name {
3821 if (serializedExecutable != null) {
3822 return serializedExecutable.name;
3823 }
3824 return super.name;
3825 }
3826
3827 @override
3828 int get nameOffset {
3829 if (serializedExecutable != null) {
3830 return serializedExecutable.nameOffset;
3831 }
3832 return super.nameOffset;
3833 }
3834
3835 @override
3836 List<ParameterElement> get parameters {
3837 if (serializedExecutable != null) {
3838 _parameters ??= ParameterElementImpl.resynthesizeList(
3839 serializedExecutable.parameters, this);
3840 }
3841 return _parameters ?? const <ParameterElement>[];
3842 }
3843
3844 /**
3845 * Set the parameters defined by this executable element to the given
3846 * [parameters].
3847 */
3848 void set parameters(List<ParameterElement> parameters) {
3849 assert(serializedExecutable == null);
3850 for (ParameterElement parameter in parameters) {
3851 (parameter as ParameterElementImpl).enclosingElement = this;
3852 }
3853 this._parameters = parameters;
3854 }
3855
3856 @override
3857 DartType get returnType {
3858 if (serializedExecutable != null && _returnType == null) {
3859 bool isSetter =
3860 serializedExecutable.kind == UnlinkedExecutableKind.setter;
3861 _returnType = enclosingUnit.resynthesizerContext.resolveLinkedType(
3862 serializedExecutable.inferredReturnTypeSlot,
3863 typeParameterContext) ??
3864 enclosingUnit.resynthesizerContext.resolveTypeRef(
3865 serializedExecutable.returnType, typeParameterContext,
3866 defaultVoid: isSetter && context.analysisOptions.strongMode);
3867 }
3868 return _returnType;
3869 }
3870
3871 void set returnType(DartType returnType) {
3872 assert(serializedExecutable == null);
3873 _returnType = returnType;
3874 }
3875
3876 @override
3877 FunctionType get type {
3878 if (serializedExecutable != null) {
3879 _type ??= new FunctionTypeImpl.elementWithNameAndArgs(
3880 this, null, allEnclosingTypeParameterTypes, false);
3881 }
3882 return _type;
3883 }
3884
3885 void set type(FunctionType type) {
3886 assert(serializedExecutable == null);
3887 _type = type;
3888 }
3889
3890 @override
3891 TypeParameterizedElementMixin get typeParameterContext => this;
3892
3893 @override
3894 List<TypeParameterElement> get typeParameters {
3895 if (serializedExecutable != null) {
3896 return super.typeParameters;
3897 }
3898 return _typeParameters ?? const <TypeParameterElement>[];
3899 }
3900
3901 /**
3902 * Set the type parameters defined by this executable element to the given
3903 * [typeParameters].
3904 */
3905 void set typeParameters(List<TypeParameterElement> typeParameters) {
3906 assert(serializedExecutable == null);
3907 for (TypeParameterElement parameter in typeParameters) {
3908 (parameter as TypeParameterElementImpl).enclosingElement = this;
3909 }
3910 this._typeParameters = typeParameters;
3911 }
3912
3913 @override
3914 List<UnlinkedTypeParam> get unlinkedTypeParams =>
3915 serializedExecutable.typeParameters;
3916
3917 @override
3918 void appendTo(StringBuffer buffer) {
3919 if (this.kind != ElementKind.GETTER) {
3920 int typeParameterCount = typeParameters.length;
3921 if (typeParameterCount > 0) {
3922 buffer.write('<');
3923 for (int i = 0; i < typeParameterCount; i++) {
3924 if (i > 0) {
3925 buffer.write(", ");
3926 }
3927 (typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
3928 }
3929 buffer.write('>');
3930 }
3931 buffer.write("(");
3932 String closing = null;
3933 ParameterKind kind = ParameterKind.REQUIRED;
3934 int parameterCount = parameters.length;
3935 for (int i = 0; i < parameterCount; i++) {
3936 if (i > 0) {
3937 buffer.write(", ");
3938 }
3939 ParameterElement parameter = parameters[i];
3940 ParameterKind parameterKind = parameter.parameterKind;
3941 if (parameterKind != kind) {
3942 if (closing != null) {
3943 buffer.write(closing);
3944 }
3945 if (parameterKind == ParameterKind.POSITIONAL) {
3946 buffer.write("[");
3947 closing = "]";
3948 } else if (parameterKind == ParameterKind.NAMED) {
3949 buffer.write("{");
3950 closing = "}";
3951 } else {
3952 closing = null;
3953 }
3954 }
3955 kind = parameterKind;
3956 parameter.appendToWithoutDelimiters(buffer);
3957 }
3958 if (closing != null) {
3959 buffer.write(closing);
3960 }
3961 buffer.write(")");
3962 }
3963 if (type != null) {
3964 buffer.write(ElementImpl.RIGHT_ARROW);
3965 buffer.write(type.returnType);
3966 }
3967 }
3968
3969 @override
3970 ElementImpl getChild(String identifier) {
3971 for (FunctionElement function in _functions) {
3972 FunctionElementImpl functionImpl = function;
3973 if (functionImpl.identifier == identifier) {
3974 return functionImpl;
3975 }
3976 }
3977 for (LabelElement label in _labels) {
3978 LabelElementImpl labelImpl = label;
3979 if (labelImpl.identifier == identifier) {
3980 return labelImpl;
3981 }
3982 }
3983 for (LocalVariableElement variable in _localVariables) {
3984 LocalVariableElementImpl variableImpl = variable;
3985 if (variableImpl.identifier == identifier) {
3986 return variableImpl;
3987 }
3988 }
3989 for (ParameterElement parameter in parameters) {
3990 ParameterElementImpl parameterImpl = parameter;
3991 if (parameterImpl.identifier == identifier) {
3992 return parameterImpl;
3993 }
3994 }
3995 return null;
3996 }
3997
3998 @override
3999 void visitChildren(ElementVisitor visitor) {
4000 super.visitChildren(visitor);
4001 safelyVisitChildren(typeParameters, visitor);
4002 safelyVisitChildren(parameters, visitor);
4003 safelyVisitChildren(_functions, visitor);
4004 safelyVisitChildren(_labels, visitor);
4005 safelyVisitChildren(_localVariables, visitor);
4006 }
4007 }
4008
4009 /**
4010 * A concrete implementation of an [ExportElement].
4011 */
4012 class ExportElementImpl extends UriReferencedElementImpl
4013 implements ExportElement {
4014 /**
4015 * The unlinked representation of the export in the summary.
4016 */
4017 final UnlinkedExportPublic _unlinkedExportPublic;
4018
4019 /**
4020 * The unlinked representation of the export in the summary.
4021 */
4022 final UnlinkedExportNonPublic _unlinkedExportNonPublic;
4023
4024 /**
4025 * The library that is exported from this library by this export directive.
4026 */
4027 LibraryElement _exportedLibrary;
4028
4029 /**
4030 * The combinators that were specified as part of the export directive in the
4031 * order in which they were specified.
4032 */
4033 List<NamespaceCombinator> _combinators;
4034
4035 /**
4036 * The URI that was selected based on the [context] declared variables.
4037 */
4038 String _selectedUri;
4039
4040 /**
4041 * Initialize a newly created export element at the given [offset].
4042 */
4043 ExportElementImpl(int offset)
4044 : _unlinkedExportPublic = null,
4045 _unlinkedExportNonPublic = null,
4046 super(null, offset);
4047
4048 /**
4049 * Initialize using the given serialized information.
4050 */
4051 ExportElementImpl.forSerialized(this._unlinkedExportPublic,
4052 this._unlinkedExportNonPublic, LibraryElementImpl enclosingLibrary)
4053 : super.forSerialized(enclosingLibrary);
4054
4055 @override
4056 List<NamespaceCombinator> get combinators {
4057 if (_unlinkedExportPublic != null && _combinators == null) {
4058 _combinators = ImportElementImpl
4059 ._buildCombinators(_unlinkedExportPublic.combinators);
4060 }
4061 return _combinators ?? const <NamespaceCombinator>[];
4062 }
4063
4064 void set combinators(List<NamespaceCombinator> combinators) {
4065 assert(_unlinkedExportPublic == null);
4066 _combinators = combinators;
4067 }
4068
4069 @override
4070 LibraryElement get exportedLibrary {
4071 if (_unlinkedExportNonPublic != null && _exportedLibrary == null) {
4072 LibraryElementImpl library = enclosingElement as LibraryElementImpl;
4073 _exportedLibrary = library.resynthesizerContext.buildExportedLibrary(uri);
4074 }
4075 return _exportedLibrary;
4076 }
4077
4078 void set exportedLibrary(LibraryElement exportedLibrary) {
4079 assert(_unlinkedExportNonPublic == null);
4080 _exportedLibrary = exportedLibrary;
4081 }
4082
4083 @override
4084 String get identifier => exportedLibrary.name;
4085
4086 @override
4087 ElementKind get kind => ElementKind.EXPORT;
4088
4089 @override
4090 List<ElementAnnotation> get metadata {
4091 if (_unlinkedExportNonPublic != null) {
4092 return _metadata ??= _buildAnnotations(
4093 library.definingCompilationUnit as CompilationUnitElementImpl,
4094 _unlinkedExportNonPublic.annotations);
4095 }
4096 return super.metadata;
4097 }
4098
4099 void set metadata(List<ElementAnnotation> metadata) {
4100 assert(_unlinkedExportNonPublic == null);
4101 super.metadata = metadata;
4102 }
4103
4104 @override
4105 int get nameOffset {
4106 if (_unlinkedExportNonPublic != null) {
4107 return _unlinkedExportNonPublic.offset;
4108 }
4109 return super.nameOffset;
4110 }
4111
4112 @override
4113 String get uri {
4114 if (_unlinkedExportPublic != null) {
4115 return _selectedUri ??= _selectUri(
4116 _unlinkedExportPublic.uri, _unlinkedExportPublic.configurations);
4117 }
4118 return super.uri;
4119 }
4120
4121 @override
4122 void set uri(String uri) {
4123 assert(_unlinkedExportPublic == null);
4124 super.uri = uri;
4125 }
4126
4127 @override
4128 int get uriEnd {
4129 if (_unlinkedExportNonPublic != null) {
4130 return _unlinkedExportNonPublic.uriEnd;
4131 }
4132 return super.uriEnd;
4133 }
4134
4135 @override
4136 void set uriEnd(int uriEnd) {
4137 assert(_unlinkedExportNonPublic == null);
4138 super.uriEnd = uriEnd;
4139 }
4140
4141 @override
4142 int get uriOffset {
4143 if (_unlinkedExportNonPublic != null) {
4144 return _unlinkedExportNonPublic.uriOffset;
4145 }
4146 return super.uriOffset;
4147 }
4148
4149 @override
4150 void set uriOffset(int uriOffset) {
4151 assert(_unlinkedExportNonPublic == null);
4152 super.uriOffset = uriOffset;
4153 }
4154
4155 @override
4156 accept(ElementVisitor visitor) => visitor.visitExportElement(this);
4157
4158 @override
4159 void appendTo(StringBuffer buffer) {
4160 buffer.write("export ");
4161 (exportedLibrary as LibraryElementImpl).appendTo(buffer);
4162 }
4163 }
4164
4165 /**
4166 * A concrete implementation of a [FieldElement].
4167 */
4168 class FieldElementImpl extends PropertyInducingElementImpl
4169 implements FieldElement {
4170 /**
4171 * Initialize a newly created synthetic field element to have the given [name]
4172 * at the given [offset].
4173 */
4174 FieldElementImpl(String name, int offset) : super(name, offset);
4175
4176 /**
4177 * Initialize a newly created field element to have the given [name].
4178 */
4179 FieldElementImpl.forNode(Identifier name) : super.forNode(name);
4180
4181 /**
4182 * Initialize using the given serialized information.
4183 */
4184 FieldElementImpl.forSerialized(
4185 UnlinkedVariable unlinkedVariable, ElementImpl enclosingElement)
4186 : super.forSerialized(unlinkedVariable, enclosingElement);
4187
4188 /**
4189 * Initialize using the given serialized information.
4190 */
4191 factory FieldElementImpl.forSerializedFactory(
4192 UnlinkedVariable unlinkedVariable, ClassElementImpl enclosingClass) {
4193 if (unlinkedVariable.initializer?.bodyExpr != null &&
4194 (unlinkedVariable.isConst ||
4195 unlinkedVariable.isFinal && !unlinkedVariable.isStatic)) {
4196 return new ConstFieldElementImpl.forSerialized(
4197 unlinkedVariable, enclosingClass);
4198 } else {
4199 return new FieldElementImpl.forSerialized(
4200 unlinkedVariable, enclosingClass);
4201 }
4202 }
4203
4204 @override
4205 ClassElement get enclosingElement => super.enclosingElement as ClassElement;
4206
4207 @override
4208 bool get isEnumConstant =>
4209 enclosingElement != null ? enclosingElement.isEnum : false;
4210
4211 @override
4212 bool get isStatic {
4213 if (_unlinkedVariable != null) {
4214 return _unlinkedVariable.isStatic;
4215 }
4216 return hasModifier(Modifier.STATIC);
4217 }
4218
4219 @override
4220 bool get isVirtual {
4221 for (ElementAnnotationImpl annotation in metadata) {
4222 if (annotation.isVirtual) {
4223 return true;
4224 }
4225 }
4226 return false;
4227 }
4228
4229 @override
4230 ElementKind get kind => ElementKind.FIELD;
4231
4232 /**
4233 * Set whether this field is static.
4234 */
4235 void set static(bool isStatic) {
4236 assert(_unlinkedVariable == null);
4237 setModifier(Modifier.STATIC, isStatic);
4238 }
4239
4240 @override
4241 accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
4242
4243 @override
4244 AstNode computeNode() {
4245 if (isEnumConstant) {
4246 return getNodeMatching((node) => node is EnumConstantDeclaration);
4247 } else {
4248 return getNodeMatching((node) => node is VariableDeclaration);
4249 }
4250 }
4251 }
4252
4253 /**
4254 * A [ParameterElementImpl] that has the additional information of the
4255 * [FieldElement] associated with the parameter.
4256 */
4257 class FieldFormalParameterElementImpl extends ParameterElementImpl
4258 implements FieldFormalParameterElement {
4259 /**
4260 * The field associated with this field formal parameter.
4261 */
4262 FieldElement _field;
4263
4264 /**
4265 * Initialize a newly created parameter element to have the given [name] and
4266 * [nameOffset].
4267 */
4268 FieldFormalParameterElementImpl(String name, int nameOffset)
4269 : super(name, nameOffset);
4270
4271 /**
4272 * Initialize a newly created parameter element to have the given [name].
4273 */
4274 FieldFormalParameterElementImpl.forNode(Identifier name)
4275 : super.forNode(name);
4276
4277 /**
4278 * Initialize using the given serialized information.
4279 */
4280 FieldFormalParameterElementImpl.forSerialized(
4281 UnlinkedParam unlinkedParam, ElementImpl enclosingElement)
4282 : super.forSerialized(unlinkedParam, enclosingElement);
4283
4284 @override
4285 FieldElement get field {
4286 if (_unlinkedParam != null && _field == null) {
4287 Element enclosingClass = enclosingElement?.enclosingElement;
4288 if (enclosingClass is ClassElement) {
4289 _field = enclosingClass.getField(_unlinkedParam.name);
4290 }
4291 }
4292 return _field;
4293 }
4294
4295 void set field(FieldElement field) {
4296 assert(_unlinkedParam == null);
4297 _field = field;
4298 }
4299
4300 @override
4301 bool get isInitializingFormal => true;
4302
4303 @override
4304 DartType get type {
4305 if (_unlinkedParam != null && _unlinkedParam.type == null) {
4306 _type ??= field?.type ?? DynamicTypeImpl.instance;
4307 }
4308 return super.type;
4309 }
4310
4311 @override
4312 void set type(DartType type) {
4313 assert(_unlinkedParam == null);
4314 _type = type;
4315 }
4316
4317 @override
4318 accept(ElementVisitor visitor) =>
4319 visitor.visitFieldFormalParameterElement(this);
4320 }
4321
4322 /**
4323 * A concrete implementation of a [FunctionElement].
4324 */
4325 class FunctionElementImpl extends ExecutableElementImpl
4326 implements FunctionElement {
4327 /**
4328 * The offset to the beginning of the visible range for this element.
4329 */
4330 int _visibleRangeOffset = 0;
4331
4332 /**
4333 * The length of the visible range for this element, or `-1` if this element
4334 * does not have a visible range.
4335 */
4336 int _visibleRangeLength = -1;
4337
4338 /**
4339 * Initialize a newly created function element to have the given [name] and
4340 * [offset].
4341 */
4342 FunctionElementImpl(String name, int offset) : super(name, offset);
4343
4344 /**
4345 * Initialize a newly created function element to have the given [name].
4346 */
4347 FunctionElementImpl.forNode(Identifier name) : super.forNode(name);
4348
4349 /**
4350 * Initialize a newly created function element to have no name and the given
4351 * [nameOffset]. This is used for function expressions, that have no name.
4352 */
4353 FunctionElementImpl.forOffset(int nameOffset) : super("", nameOffset);
4354
4355 /**
4356 * Initialize using the given serialized information.
4357 */
4358 FunctionElementImpl.forSerialized(
4359 UnlinkedExecutable serializedExecutable, ElementImpl enclosingElement)
4360 : super.forSerialized(serializedExecutable, enclosingElement);
4361
4362 /**
4363 * Synthesize an unnamed function element that takes [parameters] and returns
4364 * [returnType].
4365 */
4366 FunctionElementImpl.synthetic(
4367 List<ParameterElement> parameters, DartType returnType)
4368 : super("", -1) {
4369 synthetic = true;
4370 this.returnType = returnType;
4371 this.parameters = parameters;
4372
4373 type = new FunctionTypeImpl(this);
4374 }
4375
4376 @override
4377 TypeParameterizedElementMixin get enclosingTypeParameterContext {
4378 return (enclosingElement as ElementImpl).typeParameterContext;
4379 }
4380
4381 @override
4382 String get identifier {
4383 String identifier = super.identifier;
4384 Element enclosing = this.enclosingElement;
4385 if (enclosing is ExecutableElement) {
4386 int id = ElementImpl._findElementIndexUsingIdentical(
4387 enclosing.functions, this);
4388 identifier += "@$id";
4389 }
4390 return identifier;
4391 }
4392
4393 @override
4394 bool get isEntryPoint {
4395 return isStatic && displayName == FunctionElement.MAIN_FUNCTION_NAME;
4396 }
4397
4398 @override
4399 bool get isStatic => enclosingElement is CompilationUnitElement;
4400
4401 @override
4402 ElementKind get kind => ElementKind.FUNCTION;
4403
4404 @override
4405 SourceRange get visibleRange {
4406 if (serializedExecutable != null) {
4407 if (serializedExecutable.visibleLength == 0) {
4408 return null;
4409 }
4410 return new SourceRange(serializedExecutable.visibleOffset,
4411 serializedExecutable.visibleLength);
4412 }
4413 if (_visibleRangeLength < 0) {
4414 return null;
4415 }
4416 return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
4417 }
4418
4419 @override
4420 accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
4421
4422 @override
4423 void appendTo(StringBuffer buffer) {
4424 String name = displayName;
4425 if (name != null) {
4426 buffer.write(name);
4427 }
4428 super.appendTo(buffer);
4429 }
4430
4431 @override
4432 FunctionDeclaration computeNode() =>
4433 getNodeMatching((node) => node is FunctionDeclaration);
4434
4435 /**
4436 * Set the visible range for this element to the range starting at the given
4437 * [offset] with the given [length].
4438 */
4439 void setVisibleRange(int offset, int length) {
4440 assert(serializedExecutable == null);
4441 _visibleRangeOffset = offset;
4442 _visibleRangeLength = length;
4443 }
4444
4445 /**
4446 * Set the parameters defined by this type alias to the given [parameters]
4447 * without becoming the parent of the parameters. This should only be used by
4448 * the [TypeResolverVisitor] when creating a synthetic type alias.
4449 */
4450 void shareParameters(List<ParameterElement> parameters) {
4451 this._parameters = parameters;
4452 }
4453
4454 /**
4455 * Set the type parameters defined by this type alias to the given
4456 * [parameters] without becoming the parent of the parameters. This should
4457 * only be used by the [TypeResolverVisitor] when creating a synthetic type
4458 * alias.
4459 */
4460 void shareTypeParameters(List<TypeParameterElement> typeParameters) {
4461 this._typeParameters = typeParameters;
4462 }
4463
4464 /**
4465 * Create and return [FunctionElement]s for the given [unlinkedFunctions].
4466 */
4467 static List<FunctionElement> resynthesizeList(
4468 ExecutableElementImpl executableElement,
4469 List<UnlinkedExecutable> unlinkedFunctions) {
4470 int length = unlinkedFunctions.length;
4471 if (length != 0) {
4472 List<FunctionElement> elements = new List<FunctionElement>(length);
4473 for (int i = 0; i < length; i++) {
4474 elements[i] = new FunctionElementImpl.forSerialized(
4475 unlinkedFunctions[i], executableElement);
4476 }
4477 return elements;
4478 } else {
4479 return const <FunctionElement>[];
4480 }
4481 }
4482 }
4483
4484 /**
4485 * Implementation of [FunctionElementImpl] for a function typed parameter.
4486 */
4487 class FunctionElementImpl_forFunctionTypedParameter
4488 extends FunctionElementImpl {
4489 @override
4490 final CompilationUnitElementImpl enclosingUnit;
4491
4492 /**
4493 * The enclosing function typed [ParameterElementImpl].
4494 */
4495 final ParameterElementImpl _parameter;
4496
4497 FunctionElementImpl_forFunctionTypedParameter(
4498 this.enclosingUnit, this._parameter)
4499 : super('', -1);
4500
4501 @override
4502 TypeParameterizedElementMixin get enclosingTypeParameterContext =>
4503 _parameter.typeParameterContext;
4504
4505 @override
4506 bool get isSynthetic => true;
4507 }
4508
4509 /**
4510 * Implementation of [FunctionElementImpl] for a synthetic function element
4511 * that was synthesized by a LUB computation.
4512 */
4513 class FunctionElementImpl_forLUB extends FunctionElementImpl {
4514 @override
4515 final CompilationUnitElementImpl enclosingUnit;
4516
4517 @override
4518 final TypeParameterizedElementMixin enclosingTypeParameterContext;
4519
4520 final EntityRef _entityRef;
4521
4522 FunctionElementImpl_forLUB(
4523 this.enclosingUnit, this.enclosingTypeParameterContext, this._entityRef)
4524 : super('', -1);
4525
4526 @override
4527 bool get isSynthetic => true;
4528
4529 @override
4530 List<ParameterElement> get parameters {
4531 return _parameters ??= ParameterElementImpl
4532 .resynthesizeList(_entityRef.syntheticParams, this, synthetic: true);
4533 }
4534
4535 @override
4536 void set parameters(List<ParameterElement> parameters) {
4537 assert(false);
4538 }
4539
4540 @override
4541 DartType get returnType {
4542 return _returnType ??= enclosingUnit.resynthesizerContext
4543 .resolveTypeRef(_entityRef.syntheticReturnType, typeParameterContext);
4544 }
4545
4546 @override
4547 void set returnType(DartType returnType) {
4548 assert(false);
4549 }
4550
4551 @override
4552 FunctionType get type {
4553 return _type ??=
4554 new FunctionTypeImpl.elementWithNameAndArgs(this, null, null, false);
4555 }
4556
4557 @override
4558 void set type(FunctionType type) {
4559 assert(false);
4560 }
4561 }
4562
4563 /**
4564 * A concrete implementation of a [FunctionTypeAliasElement].
4565 */
4566 class FunctionTypeAliasElementImpl extends ElementImpl
4567 with TypeParameterizedElementMixin
4568 implements FunctionTypeAliasElement {
4569 /**
4570 * The unlinked representation of the type in the summary.
4571 */
4572 final UnlinkedTypedef _unlinkedTypedef;
4573
4574 /**
4575 * A list containing all of the parameters defined by this type alias.
4576 */
4577 List<ParameterElement> _parameters;
4578
4579 /**
4580 * The return type defined by this type alias.
4581 */
4582 DartType _returnType;
4583
4584 /**
4585 * The type of function defined by this type alias.
4586 */
4587 FunctionType _type;
4588
4589 /**
4590 * A list containing all of the type parameters defined for this type.
4591 */
4592 List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
4593
4594 /**
4595 * Initialize a newly created type alias element to have the given name.
4596 *
4597 * [name] the name of this element
4598 * [nameOffset] the offset of the name of this element in the file that
4599 * contains the declaration of this element
4600 */
4601 FunctionTypeAliasElementImpl(String name, int nameOffset)
4602 : _unlinkedTypedef = null,
4603 super(name, nameOffset);
4604
4605 /**
4606 * Initialize a newly created type alias element to have the given [name].
4607 */
4608 FunctionTypeAliasElementImpl.forNode(Identifier name)
4609 : _unlinkedTypedef = null,
4610 super.forNode(name);
4611
4612 /**
4613 * Initialize using the given serialized information.
4614 */
4615 FunctionTypeAliasElementImpl.forSerialized(
4616 this._unlinkedTypedef, CompilationUnitElementImpl enclosingUnit)
4617 : super.forSerialized(enclosingUnit);
4618
4619 @override
4620 int get codeLength {
4621 if (_unlinkedTypedef != null) {
4622 return _unlinkedTypedef.codeRange?.length;
4623 }
4624 return super.codeLength;
4625 }
4626
4627 @override
4628 int get codeOffset {
4629 if (_unlinkedTypedef != null) {
4630 return _unlinkedTypedef.codeRange?.offset;
4631 }
4632 return super.codeOffset;
4633 }
4634
4635 @override
4636 String get displayName => name;
4637
4638 @override
4639 String get documentationComment {
4640 if (_unlinkedTypedef != null) {
4641 return _unlinkedTypedef?.documentationComment?.text;
4642 }
4643 return super.documentationComment;
4644 }
4645
4646 @override
4647 CompilationUnitElement get enclosingElement =>
4648 super.enclosingElement as CompilationUnitElement;
4649
4650 @override
4651 TypeParameterizedElementMixin get enclosingTypeParameterContext => null;
4652
4653 @override
4654 CompilationUnitElementImpl get enclosingUnit =>
4655 _enclosingElement as CompilationUnitElementImpl;
4656
4657 @override
4658 ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
4659
4660 @override
4661 List<ElementAnnotation> get metadata {
4662 if (_unlinkedTypedef != null) {
4663 return _metadata ??=
4664 _buildAnnotations(enclosingUnit, _unlinkedTypedef.annotations);
4665 }
4666 return super.metadata;
4667 }
4668
4669 @override
4670 String get name {
4671 if (_unlinkedTypedef != null) {
4672 return _unlinkedTypedef.name;
4673 }
4674 return super.name;
4675 }
4676
4677 @override
4678 int get nameOffset {
4679 if (_unlinkedTypedef != null) {
4680 return _unlinkedTypedef.nameOffset;
4681 }
4682 return super.nameOffset;
4683 }
4684
4685 @override
4686 List<ParameterElement> get parameters {
4687 if (_unlinkedTypedef != null) {
4688 _parameters ??= ParameterElementImpl.resynthesizeList(
4689 _unlinkedTypedef.parameters, this);
4690 }
4691 return _parameters ?? const <ParameterElement>[];
4692 }
4693
4694 /**
4695 * Set the parameters defined by this type alias to the given [parameters].
4696 */
4697 void set parameters(List<ParameterElement> parameters) {
4698 assert(_unlinkedTypedef == null);
4699 if (parameters != null) {
4700 for (ParameterElement parameter in parameters) {
4701 (parameter as ParameterElementImpl).enclosingElement = this;
4702 }
4703 }
4704 this._parameters = parameters;
4705 }
4706
4707 @override
4708 DartType get returnType {
4709 if (_unlinkedTypedef != null && _returnType == null) {
4710 _returnType = enclosingUnit.resynthesizerContext
4711 .resolveTypeRef(_unlinkedTypedef.returnType, this);
4712 }
4713 return _returnType;
4714 }
4715
4716 void set returnType(DartType returnType) {
4717 assert(_unlinkedTypedef == null);
4718 _returnType = returnType;
4719 }
4720
4721 @override
4722 FunctionType get type {
4723 if (_unlinkedTypedef != null && _type == null) {
4724 _type = new FunctionTypeImpl.forTypedef(this);
4725 }
4726 return _type;
4727 }
4728
4729 void set type(FunctionType type) {
4730 assert(_unlinkedTypedef == null);
4731 _type = type;
4732 }
4733
4734 @override
4735 TypeParameterizedElementMixin get typeParameterContext => this;
4736
4737 @override
4738 List<TypeParameterElement> get typeParameters {
4739 if (_unlinkedTypedef != null) {
4740 return super.typeParameters;
4741 }
4742 return _typeParameters;
4743 }
4744
4745 /**
4746 * Set the type parameters defined for this type to the given
4747 * [typeParameters].
4748 */
4749 void set typeParameters(List<TypeParameterElement> typeParameters) {
4750 assert(_unlinkedTypedef == null);
4751 for (TypeParameterElement typeParameter in typeParameters) {
4752 (typeParameter as TypeParameterElementImpl).enclosingElement = this;
4753 }
4754 this._typeParameters = typeParameters;
4755 }
4756
4757 @override
4758 List<UnlinkedTypeParam> get unlinkedTypeParams =>
4759 _unlinkedTypedef.typeParameters;
4760
4761 @override
4762 accept(ElementVisitor visitor) => visitor.visitFunctionTypeAliasElement(this);
4763
4764 @override
4765 void appendTo(StringBuffer buffer) {
4766 buffer.write("typedef ");
4767 buffer.write(displayName);
4768 int typeParameterCount = _typeParameters.length;
4769 if (typeParameterCount > 0) {
4770 buffer.write("<");
4771 for (int i = 0; i < typeParameterCount; i++) {
4772 if (i > 0) {
4773 buffer.write(", ");
4774 }
4775 (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
4776 }
4777 buffer.write(">");
4778 }
4779 buffer.write("(");
4780 int parameterCount = _parameters.length;
4781 for (int i = 0; i < parameterCount; i++) {
4782 if (i > 0) {
4783 buffer.write(", ");
4784 }
4785 (_parameters[i] as ParameterElementImpl).appendTo(buffer);
4786 }
4787 buffer.write(")");
4788 if (type != null) {
4789 buffer.write(ElementImpl.RIGHT_ARROW);
4790 buffer.write(type.returnType);
4791 } else if (returnType != null) {
4792 buffer.write(ElementImpl.RIGHT_ARROW);
4793 buffer.write(returnType);
4794 }
4795 }
4796
4797 @override
4798 FunctionTypeAlias computeNode() =>
4799 getNodeMatching((node) => node is FunctionTypeAlias);
4800
4801 @override
4802 ElementImpl getChild(String identifier) {
4803 for (ParameterElement parameter in parameters) {
4804 ParameterElementImpl parameterImpl = parameter;
4805 if (parameterImpl.identifier == identifier) {
4806 return parameterImpl;
4807 }
4808 }
4809 for (TypeParameterElement typeParameter in _typeParameters) {
4810 TypeParameterElementImpl typeParameterImpl = typeParameter;
4811 if (typeParameterImpl.identifier == identifier) {
4812 return typeParameterImpl;
4813 }
4814 }
4815 return null;
4816 }
4817
4818 @override
4819 void visitChildren(ElementVisitor visitor) {
4820 super.visitChildren(visitor);
4821 safelyVisitChildren(parameters, visitor);
4822 safelyVisitChildren(_typeParameters, visitor);
4823 }
4824 }
4825
4826 /**
4827 * A concrete implementation of a [HideElementCombinator].
4828 */
4829 class HideElementCombinatorImpl implements HideElementCombinator {
4830 /**
4831 * The unlinked representation of the combinator in the summary.
4832 */
4833 final UnlinkedCombinator _unlinkedCombinator;
4834
4835 /**
4836 * The names that are not to be made visible in the importing library even if
4837 * they are defined in the imported library.
4838 */
4839 List<String> _hiddenNames;
4840
4841 HideElementCombinatorImpl() : _unlinkedCombinator = null;
4842
4843 /**
4844 * Initialize using the given serialized information.
4845 */
4846 HideElementCombinatorImpl.forSerialized(this._unlinkedCombinator);
4847
4848 @override
4849 List<String> get hiddenNames {
4850 if (_unlinkedCombinator != null) {
4851 _hiddenNames ??= _unlinkedCombinator.hides.toList(growable: false);
4852 }
4853 return _hiddenNames ?? const <String>[];
4854 }
4855
4856 void set hiddenNames(List<String> hiddenNames) {
4857 assert(_unlinkedCombinator == null);
4858 _hiddenNames = hiddenNames;
4859 }
4860
4861 @override
4862 String toString() {
4863 StringBuffer buffer = new StringBuffer();
4864 buffer.write("show ");
4865 int count = hiddenNames.length;
4866 for (int i = 0; i < count; i++) {
4867 if (i > 0) {
4868 buffer.write(", ");
4869 }
4870 buffer.write(hiddenNames[i]);
4871 }
4872 return buffer.toString();
4873 }
4874 }
4875
4876 /**
4877 * A concrete implementation of an [ImportElement].
4878 */
4879 class ImportElementImpl extends UriReferencedElementImpl
4880 implements ImportElement {
4881 /**
4882 * The unlinked representation of the import in the summary.
4883 */
4884 final UnlinkedImport _unlinkedImport;
4885
4886 /**
4887 * The index of the dependency in the `imports` list.
4888 */
4889 final int _linkedDependency;
4890
4891 /**
4892 * The offset of the prefix of this import in the file that contains the this
4893 * import directive, or `-1` if this import is synthetic.
4894 */
4895 int _prefixOffset = 0;
4896
4897 /**
4898 * The library that is imported into this library by this import directive.
4899 */
4900 LibraryElement _importedLibrary;
4901
4902 /**
4903 * The combinators that were specified as part of the import directive in the
4904 * order in which they were specified.
4905 */
4906 List<NamespaceCombinator> _combinators;
4907
4908 /**
4909 * The prefix that was specified as part of the import directive, or `null` if
4910 * there was no prefix specified.
4911 */
4912 PrefixElement _prefix;
4913
4914 /**
4915 * The URI that was selected based on the [context] declared variables.
4916 */
4917 String _selectedUri;
4918
4919 /**
4920 * Initialize a newly created import element at the given [offset].
4921 * The offset may be `-1` if the import is synthetic.
4922 */
4923 ImportElementImpl(int offset)
4924 : _unlinkedImport = null,
4925 _linkedDependency = null,
4926 super(null, offset);
4927
4928 /**
4929 * Initialize using the given serialized information.
4930 */
4931 ImportElementImpl.forSerialized(this._unlinkedImport, this._linkedDependency,
4932 LibraryElementImpl enclosingLibrary)
4933 : super.forSerialized(enclosingLibrary);
4934
4935 @override
4936 List<NamespaceCombinator> get combinators {
4937 if (_unlinkedImport != null && _combinators == null) {
4938 _combinators = _buildCombinators(_unlinkedImport.combinators);
4939 }
4940 return _combinators ?? const <NamespaceCombinator>[];
4941 }
4942
4943 void set combinators(List<NamespaceCombinator> combinators) {
4944 assert(_unlinkedImport == null);
4945 _combinators = combinators;
4946 }
4947
4948 /**
4949 * Set whether this import is for a deferred library.
4950 */
4951 void set deferred(bool isDeferred) {
4952 assert(_unlinkedImport == null);
4953 setModifier(Modifier.DEFERRED, isDeferred);
4954 }
4955
4956 @override
4957 String get identifier => "${importedLibrary.identifier}@$nameOffset";
4958
4959 @override
4960 LibraryElement get importedLibrary {
4961 if (_linkedDependency != null) {
4962 if (_importedLibrary == null) {
4963 LibraryElementImpl library = enclosingElement as LibraryElementImpl;
4964 if (_linkedDependency == 0) {
4965 _importedLibrary = library;
4966 } else {
4967 _importedLibrary = library.resynthesizerContext
4968 .buildImportedLibrary(_linkedDependency);
4969 }
4970 }
4971 }
4972 return _importedLibrary;
4973 }
4974
4975 void set importedLibrary(LibraryElement importedLibrary) {
4976 assert(_unlinkedImport == null);
4977 _importedLibrary = importedLibrary;
4978 }
4979
4980 @override
4981 bool get isDeferred {
4982 if (_unlinkedImport != null) {
4983 return _unlinkedImport.isDeferred;
4984 }
4985 return hasModifier(Modifier.DEFERRED);
4986 }
4987
4988 @override
4989 bool get isSynthetic {
4990 if (_unlinkedImport != null) {
4991 return _unlinkedImport.isImplicit;
4992 }
4993 return super.isSynthetic;
4994 }
4995
4996 @override
4997 ElementKind get kind => ElementKind.IMPORT;
4998
4999 @override
5000 List<ElementAnnotation> get metadata {
5001 if (_unlinkedImport != null) {
5002 return _metadata ??= _buildAnnotations(
5003 library.definingCompilationUnit as CompilationUnitElementImpl,
5004 _unlinkedImport.annotations);
5005 }
5006 return super.metadata;
5007 }
5008
5009 void set metadata(List<ElementAnnotation> metadata) {
5010 assert(_unlinkedImport == null);
5011 super.metadata = metadata;
5012 }
5013
5014 @override
5015 int get nameOffset {
5016 if (_unlinkedImport != null) {
5017 if (_unlinkedImport.isImplicit) {
5018 return -1;
5019 }
5020 return _unlinkedImport.offset;
5021 }
5022 return super.nameOffset;
5023 }
5024
5025 PrefixElement get prefix {
5026 if (_unlinkedImport != null) {
5027 if (_unlinkedImport.prefixReference != 0 && _prefix == null) {
5028 LibraryElementImpl library = enclosingElement as LibraryElementImpl;
5029 _prefix = new PrefixElementImpl.forSerialized(_unlinkedImport, library);
5030 }
5031 }
5032 return _prefix;
5033 }
5034
5035 void set prefix(PrefixElement prefix) {
5036 assert(_unlinkedImport == null);
5037 _prefix = prefix;
5038 }
5039
5040 @override
5041 int get prefixOffset {
5042 if (_unlinkedImport != null) {
5043 return _unlinkedImport.prefixOffset;
5044 }
5045 return _prefixOffset;
5046 }
5047
5048 void set prefixOffset(int prefixOffset) {
5049 assert(_unlinkedImport == null);
5050 _prefixOffset = prefixOffset;
5051 }
5052
5053 @override
5054 String get uri {
5055 if (_unlinkedImport != null) {
5056 if (_unlinkedImport.isImplicit) {
5057 return null;
5058 }
5059 return _selectedUri ??=
5060 _selectUri(_unlinkedImport.uri, _unlinkedImport.configurations);
5061 }
5062 return super.uri;
5063 }
5064
5065 @override
5066 void set uri(String uri) {
5067 assert(_unlinkedImport == null);
5068 super.uri = uri;
5069 }
5070
5071 @override
5072 int get uriEnd {
5073 if (_unlinkedImport != null) {
5074 if (_unlinkedImport.isImplicit) {
5075 return -1;
5076 }
5077 return _unlinkedImport.uriEnd;
5078 }
5079 return super.uriEnd;
5080 }
5081
5082 @override
5083 void set uriEnd(int uriEnd) {
5084 assert(_unlinkedImport == null);
5085 super.uriEnd = uriEnd;
5086 }
5087
5088 @override
5089 int get uriOffset {
5090 if (_unlinkedImport != null) {
5091 if (_unlinkedImport.isImplicit) {
5092 return -1;
5093 }
5094 return _unlinkedImport.uriOffset;
5095 }
5096 return super.uriOffset;
5097 }
5098
5099 @override
5100 void set uriOffset(int uriOffset) {
5101 assert(_unlinkedImport == null);
5102 super.uriOffset = uriOffset;
5103 }
5104
5105 @override
5106 accept(ElementVisitor visitor) => visitor.visitImportElement(this);
5107
5108 @override
5109 void appendTo(StringBuffer buffer) {
5110 buffer.write("import ");
5111 (importedLibrary as LibraryElementImpl).appendTo(buffer);
5112 }
5113
5114 @override
5115 void visitChildren(ElementVisitor visitor) {
5116 super.visitChildren(visitor);
5117 prefix?.accept(visitor);
5118 }
5119
5120 static List<NamespaceCombinator> _buildCombinators(
5121 List<UnlinkedCombinator> unlinkedCombinators) {
5122 int length = unlinkedCombinators.length;
5123 if (length != 0) {
5124 List<NamespaceCombinator> combinators =
5125 new List<NamespaceCombinator>(length);
5126 for (int i = 0; i < length; i++) {
5127 UnlinkedCombinator unlinkedCombinator = unlinkedCombinators[i];
5128 combinators[i] = unlinkedCombinator.shows.isNotEmpty
5129 ? new ShowElementCombinatorImpl.forSerialized(unlinkedCombinator)
5130 : new HideElementCombinatorImpl.forSerialized(unlinkedCombinator);
5131 }
5132 return combinators;
5133 } else {
5134 return const <NamespaceCombinator>[];
5135 }
5136 }
5137 }
5138
5139 /**
5140 * A concrete implementation of a [LabelElement].
5141 */
5142 class LabelElementImpl extends ElementImpl implements LabelElement {
5143 /**
5144 * The unlinked representation of the label in the summary.
5145 */
5146 final UnlinkedLabel _unlinkedLabel;
5147
5148 /**
5149 * A flag indicating whether this label is associated with a `switch`
5150 * statement.
5151 */
5152 // TODO(brianwilkerson) Make this a modifier.
5153 final bool _onSwitchStatement;
5154
5155 /**
5156 * A flag indicating whether this label is associated with a `switch` member
5157 * (`case` or `default`).
5158 */
5159 // TODO(brianwilkerson) Make this a modifier.
5160 final bool _onSwitchMember;
5161
5162 /**
5163 * Initialize a newly created label element to have the given [name].
5164 * [onSwitchStatement] should be `true` if this label is associated with a
5165 * `switch` statement and [onSwitchMember] should be `true` if this label is
5166 * associated with a `switch` member.
5167 */
5168 LabelElementImpl(String name, int nameOffset, this._onSwitchStatement,
5169 this._onSwitchMember)
5170 : _unlinkedLabel = null,
5171 super(name, nameOffset);
5172
5173 /**
5174 * Initialize a newly created label element to have the given [name].
5175 * [_onSwitchStatement] should be `true` if this label is associated with a
5176 * `switch` statement and [_onSwitchMember] should be `true` if this label is
5177 * associated with a `switch` member.
5178 */
5179 LabelElementImpl.forNode(
5180 Identifier name, this._onSwitchStatement, this._onSwitchMember)
5181 : _unlinkedLabel = null,
5182 super.forNode(name);
5183
5184 /**
5185 * Initialize using the given serialized information.
5186 */
5187 LabelElementImpl.forSerialized(
5188 UnlinkedLabel unlinkedLabel, ExecutableElementImpl enclosingExecutable)
5189 : _unlinkedLabel = unlinkedLabel,
5190 _onSwitchStatement = unlinkedLabel.isOnSwitchStatement,
5191 _onSwitchMember = unlinkedLabel.isOnSwitchMember,
5192 super.forSerialized(enclosingExecutable);
5193
5194 @override
5195 String get displayName => name;
5196
5197 @override
5198 ExecutableElement get enclosingElement =>
5199 super.enclosingElement as ExecutableElement;
5200
5201 /**
5202 * Return `true` if this label is associated with a `switch` member (`case` or
5203 * `default`).
5204 */
5205 bool get isOnSwitchMember => _onSwitchMember;
5206
5207 /**
5208 * Return `true` if this label is associated with a `switch` statement.
5209 */
5210 bool get isOnSwitchStatement => _onSwitchStatement;
5211
5212 @override
5213 ElementKind get kind => ElementKind.LABEL;
5214
5215 @override
5216 String get name {
5217 if (_unlinkedLabel != null) {
5218 return _unlinkedLabel.name;
5219 }
5220 return super.name;
5221 }
5222
5223 @override
5224 int get nameOffset {
5225 if (_unlinkedLabel != null) {
5226 return _unlinkedLabel.nameOffset;
5227 }
5228 return super.nameOffset;
5229 }
5230
5231 @override
5232 accept(ElementVisitor visitor) => visitor.visitLabelElement(this);
5233
5234 /**
5235 * Create and return [LabelElement]s for the given [unlinkedLabels].
5236 */
5237 static List<LabelElement> resynthesizeList(
5238 ExecutableElementImpl enclosingExecutable,
5239 List<UnlinkedLabel> unlinkedLabels) {
5240 int length = unlinkedLabels.length;
5241 if (length != 0) {
5242 List<LabelElement> elements = new List<LabelElement>(length);
5243 for (int i = 0; i < length; i++) {
5244 elements[i] = new LabelElementImpl.forSerialized(
5245 unlinkedLabels[i], enclosingExecutable);
5246 }
5247 return elements;
5248 } else {
5249 return const <LabelElement>[];
5250 }
5251 }
5252 }
5253
5254 /**
5255 * A concrete implementation of a [LibraryElement].
5256 */
5257 class LibraryElementImpl extends ElementImpl implements LibraryElement {
5258 /**
5259 * The analysis context in which this library is defined.
5260 */
5261 final AnalysisContext context;
5262
5263 final LibraryResynthesizerContext resynthesizerContext;
5264
5265 final UnlinkedUnit _unlinkedDefiningUnit;
5266
5267 /**
5268 * The compilation unit that defines this library.
5269 */
5270 CompilationUnitElement _definingCompilationUnit;
5271
5272 /**
5273 * The entry point for this library, or `null` if this library does not have
5274 * an entry point.
5275 */
5276 FunctionElement _entryPoint;
5277
5278 /**
5279 * A list containing specifications of all of the imports defined in this
5280 * library.
5281 */
5282 List<ImportElement> _imports;
5283
5284 /**
5285 * A list containing specifications of all of the exports defined in this
5286 * library.
5287 */
5288 List<ExportElement> _exports;
5289
5290 /**
5291 * A list containing the strongly connected component in the import/export
5292 * graph in which the current library resides. Computed on demand, null
5293 * if not present. If _libraryCycle is set, then the _libraryCycle field
5294 * for all libraries reachable from this library in the import/export graph
5295 * is also set.
5296 */
5297 List<LibraryElement> _libraryCycle = null;
5298
5299 /**
5300 * A list containing all of the compilation units that are included in this
5301 * library using a `part` directive.
5302 */
5303 List<CompilationUnitElement> _parts = CompilationUnitElement.EMPTY_LIST;
5304
5305 /**
5306 * The element representing the synthetic function `loadLibrary` that is
5307 * defined for this library, or `null` if the element has not yet been created .
5308 */
5309 FunctionElement _loadLibraryFunction;
5310
5311 @override
5312 final int nameLength;
5313
5314 /**
5315 * The export [Namespace] of this library, `null` if it has not been
5316 * computed yet.
5317 */
5318 Namespace _exportNamespace;
5319
5320 /**
5321 * The public [Namespace] of this library, `null` if it has not been
5322 * computed yet.
5323 */
5324 Namespace _publicNamespace;
5325
5326 /**
5327 * A bit-encoded form of the capabilities associated with this library.
5328 */
5329 int _resolutionCapabilities = 0;
5330
5331 /**
5332 * The cached list of prefixes.
5333 */
5334 List<PrefixElement> _prefixes;
5335
5336 /**
5337 * Initialize a newly created library element in the given [context] to have
5338 * the given [name] and [offset].
5339 */
5340 LibraryElementImpl(this.context, String name, int offset, this.nameLength)
5341 : resynthesizerContext = null,
5342 _unlinkedDefiningUnit = null,
5343 super(name, offset);
5344
5345 /**
5346 * Initialize a newly created library element in the given [context] to have
5347 * the given [name].
5348 */
5349 LibraryElementImpl.forNode(this.context, LibraryIdentifier name)
5350 : nameLength = name != null ? name.length : 0,
5351 resynthesizerContext = null,
5352 _unlinkedDefiningUnit = null,
5353 super.forNode(name);
5354
5355 /**
5356 * Initialize using the given serialized information.
5357 */
5358 LibraryElementImpl.forSerialized(this.context, String name, int offset,
5359 this.nameLength, this.resynthesizerContext, this._unlinkedDefiningUnit)
5360 : super.forSerialized(null) {
5361 _name = name;
5362 _nameOffset = offset;
5363 setResolutionCapability(
5364 LibraryResolutionCapability.resolvedTypeNames, true);
5365 setResolutionCapability(
5366 LibraryResolutionCapability.constantExpressions, true);
5367 }
5368
5369 @override
5370 int get codeLength {
5371 CompilationUnitElement unit = _definingCompilationUnit;
5372 if (unit is CompilationUnitElementImpl) {
5373 return unit.codeLength;
5374 }
5375 return null;
5376 }
5377
5378 @override
5379 int get codeOffset {
5380 CompilationUnitElement unit = _definingCompilationUnit;
5381 if (unit is CompilationUnitElementImpl) {
5382 return unit.codeOffset;
5383 }
5384 return null;
5385 }
5386
5387 @override
5388 CompilationUnitElement get definingCompilationUnit =>
5389 _definingCompilationUnit;
5390
5391 /**
5392 * Set the compilation unit that defines this library to the given compilation
5393 * [unit].
5394 */
5395 void set definingCompilationUnit(CompilationUnitElement unit) {
5396 assert((unit as CompilationUnitElementImpl).librarySource == unit.source);
5397 (unit as CompilationUnitElementImpl).enclosingElement = this;
5398 this._definingCompilationUnit = unit;
5399 }
5400
5401 @override
5402 String get documentationComment {
5403 if (_unlinkedDefiningUnit != null) {
5404 return _unlinkedDefiningUnit?.libraryDocumentationComment?.text;
5405 }
5406 return super.documentationComment;
5407 }
5408
5409 FunctionElement get entryPoint {
5410 if (resynthesizerContext != null) {
5411 _entryPoint ??= resynthesizerContext.findEntryPoint();
5412 }
5413 return _entryPoint;
5414 }
5415
5416 void set entryPoint(FunctionElement entryPoint) {
5417 _entryPoint = entryPoint;
5418 }
5419
5420 @override
5421 List<LibraryElement> get exportedLibraries {
5422 HashSet<LibraryElement> libraries = new HashSet<LibraryElement>();
5423 for (ExportElement element in exports) {
5424 LibraryElement library = element.exportedLibrary;
5425 if (library != null) {
5426 libraries.add(library);
5427 }
5428 }
5429 return libraries.toList(growable: false);
5430 }
5431
5432 @override
5433 Namespace get exportNamespace {
5434 if (resynthesizerContext != null) {
5435 _exportNamespace ??= resynthesizerContext.buildExportNamespace();
5436 }
5437 return _exportNamespace;
5438 }
5439
5440 void set exportNamespace(Namespace exportNamespace) {
5441 _exportNamespace = exportNamespace;
5442 }
5443
5444 @override
5445 List<ExportElement> get exports {
5446 if (_unlinkedDefiningUnit != null && _exports == null) {
5447 List<UnlinkedExportNonPublic> unlinkedNonPublicExports =
5448 _unlinkedDefiningUnit.exports;
5449 List<UnlinkedExportPublic> unlinkedPublicExports =
5450 _unlinkedDefiningUnit.publicNamespace.exports;
5451 assert(
5452 _unlinkedDefiningUnit.exports.length == unlinkedPublicExports.length);
5453 int length = unlinkedNonPublicExports.length;
5454 if (length != 0) {
5455 List<ExportElement> exports = new List<ExportElement>(length);
5456 for (int i = 0; i < length; i++) {
5457 UnlinkedExportPublic serializedExportPublic =
5458 unlinkedPublicExports[i];
5459 UnlinkedExportNonPublic serializedExportNonPublic =
5460 unlinkedNonPublicExports[i];
5461 exports[i] = new ExportElementImpl.forSerialized(
5462 serializedExportPublic, serializedExportNonPublic, library);
5463 }
5464 _exports = exports;
5465 } else {
5466 _exports = const <ExportElement>[];
5467 }
5468 }
5469 return _exports ?? const <ExportElement>[];
5470 }
5471
5472 /**
5473 * Set the specifications of all of the exports defined in this library to the
5474 * given list of [exports].
5475 */
5476 void set exports(List<ExportElement> exports) {
5477 assert(_unlinkedDefiningUnit == null);
5478 for (ExportElement exportElement in exports) {
5479 (exportElement as ExportElementImpl).enclosingElement = this;
5480 }
5481 this._exports = exports;
5482 }
5483
5484 @override
5485 bool get hasExtUri => hasModifier(Modifier.HAS_EXT_URI);
5486
5487 /**
5488 * Set whether this library has an import of a "dart-ext" URI.
5489 */
5490 void set hasExtUri(bool hasExtUri) {
5491 setModifier(Modifier.HAS_EXT_URI, hasExtUri);
5492 }
5493
5494 @override
5495 bool get hasLoadLibraryFunction {
5496 if (_definingCompilationUnit.hasLoadLibraryFunction) {
5497 return true;
5498 }
5499 for (int i = 0; i < _parts.length; i++) {
5500 if (_parts[i].hasLoadLibraryFunction) {
5501 return true;
5502 }
5503 }
5504 return false;
5505 }
5506
5507 @override
5508 String get identifier => _definingCompilationUnit.source.encoding;
5509
5510 @override
5511 List<LibraryElement> get importedLibraries {
5512 HashSet<LibraryElement> libraries = new HashSet<LibraryElement>();
5513 for (ImportElement element in imports) {
5514 LibraryElement library = element.importedLibrary;
5515 if (library != null) {
5516 libraries.add(library);
5517 }
5518 }
5519 return libraries.toList(growable: false);
5520 }
5521
5522 @override
5523 List<ImportElement> get imports {
5524 if (_unlinkedDefiningUnit != null && _imports == null) {
5525 List<UnlinkedImport> unlinkedImports = _unlinkedDefiningUnit.imports;
5526 int length = unlinkedImports.length;
5527 if (length != 0) {
5528 List<ImportElement> imports = new List<ImportElement>(length);
5529 LinkedLibrary linkedLibrary = resynthesizerContext.linkedLibrary;
5530 for (int i = 0; i < length; i++) {
5531 imports[i] = new ImportElementImpl.forSerialized(
5532 unlinkedImports[i], linkedLibrary.importDependencies[i], library);
5533 }
5534 _imports = imports;
5535 } else {
5536 _imports = const <ImportElement>[];
5537 }
5538 }
5539 return _imports ?? ImportElement.EMPTY_LIST;
5540 }
5541
5542 /**
5543 * Set the specifications of all of the imports defined in this library to the
5544 * given list of [imports].
5545 */
5546 void set imports(List<ImportElement> imports) {
5547 assert(_unlinkedDefiningUnit == null);
5548 for (ImportElement importElement in imports) {
5549 (importElement as ImportElementImpl).enclosingElement = this;
5550 PrefixElementImpl prefix = importElement.prefix as PrefixElementImpl;
5551 if (prefix != null) {
5552 prefix.enclosingElement = this;
5553 }
5554 }
5555 this._imports = imports;
5556 this._prefixes = null;
5557 }
5558
5559 @override
5560 bool get isBrowserApplication =>
5561 entryPoint != null && isOrImportsBrowserLibrary;
5562
5563 @override
5564 bool get isDartAsync => name == "dart.async";
5565
5566 @override
5567 bool get isDartCore => name == "dart.core";
5568
5569 @override
5570 bool get isInSdk =>
5571 StringUtilities.startsWith5(name, 0, 0x64, 0x61, 0x72, 0x74, 0x2E);
5572
5573 /**
5574 * Return `true` if the receiver directly or indirectly imports the
5575 * 'dart:html' libraries.
5576 */
5577 bool get isOrImportsBrowserLibrary {
5578 List<LibraryElement> visited = new List<LibraryElement>();
5579 Source htmlLibSource = context.sourceFactory.forUri(DartSdk.DART_HTML);
5580 visited.add(this);
5581 for (int index = 0; index < visited.length; index++) {
5582 LibraryElement library = visited[index];
5583 Source source = library.definingCompilationUnit.source;
5584 if (source == htmlLibSource) {
5585 return true;
5586 }
5587 for (LibraryElement importedLibrary in library.importedLibraries) {
5588 if (!visited.contains(importedLibrary)) {
5589 visited.add(importedLibrary);
5590 }
5591 }
5592 for (LibraryElement exportedLibrary in library.exportedLibraries) {
5593 if (!visited.contains(exportedLibrary)) {
5594 visited.add(exportedLibrary);
5595 }
5596 }
5597 }
5598 return false;
5599 }
5600
5601 @override
5602 bool get isResynthesized {
5603 return resynthesizerContext != null;
5604 }
5605
5606 @override
5607 ElementKind get kind => ElementKind.LIBRARY;
5608
5609 @override
5610 LibraryElement get library => this;
5611
5612 @override
5613 List<LibraryElement> get libraryCycle {
5614 if (_libraryCycle != null) {
5615 return _libraryCycle;
5616 }
5617
5618 // Global counter for this run of the algorithm
5619 int counter = 0;
5620 // The discovery times of each library
5621 Map<LibraryElementImpl, int> indices = {};
5622 // The set of scc candidates
5623 Set<LibraryElementImpl> active = new Set();
5624 // The stack of discovered elements
5625 List<LibraryElementImpl> stack = [];
5626 // For a given library that has not yet been processed by this run of the
5627 // algorithm, compute the strongly connected components.
5628 int scc(LibraryElementImpl library) {
5629 int index = counter++;
5630 int root = index;
5631 indices[library] = index;
5632 active.add(library);
5633 stack.add(library);
5634 LibraryElementImpl getActualLibrary(LibraryElement lib) {
5635 // TODO(paulberry): this means that computing a library cycle will be
5636 // expensive for libraries resynthesized from summaries, since it will
5637 // require fully resynthesizing all the libraries in the cycle as well
5638 // as any libraries they import or export. Try to find a better way.
5639 if (lib is LibraryElementHandle) {
5640 return lib.actualElement;
5641 } else {
5642 return lib;
5643 }
5644 }
5645
5646 void recurse(LibraryElementImpl child) {
5647 if (!indices.containsKey(child)) {
5648 // We haven't visited this child yet, so recurse on the child,
5649 // returning the lowest numbered node reachable from the child. If
5650 // the child can reach a root which is lower numbered than anything
5651 // we've reached so far, update the root.
5652 root = min(root, scc(child));
5653 } else if (active.contains(child)) {
5654 // The child has been visited, but has not yet been placed into a
5655 // component. If the child is higher than anything we've seen so far
5656 // update the root appropriately.
5657 root = min(root, indices[child]);
5658 }
5659 }
5660
5661 // Recurse on all of the children in the import/export graph, filtering
5662 // out those for which library cycles have already been computed.
5663 library.exportedLibraries
5664 .map(getActualLibrary)
5665 .where((l) => l._libraryCycle == null)
5666 .forEach(recurse);
5667 library.importedLibraries
5668 .map(getActualLibrary)
5669 .where((l) => l._libraryCycle == null)
5670 .forEach(recurse);
5671
5672 if (root == index) {
5673 // This is the root of a strongly connected component.
5674 // Pop the elements, and share the component across all
5675 // of the elements.
5676 List<LibraryElement> component = <LibraryElement>[];
5677 LibraryElementImpl cur = null;
5678 do {
5679 cur = stack.removeLast();
5680 active.remove(cur);
5681 component.add(cur);
5682 cur._libraryCycle = component;
5683 } while (cur != library);
5684 }
5685 return root;
5686 }
5687
5688 scc(library);
5689 return _libraryCycle;
5690 }
5691
5692 @override
5693 FunctionElement get loadLibraryFunction {
5694 assert(_loadLibraryFunction != null);
5695 return _loadLibraryFunction;
5696 }
5697
5698 @override
5699 List<ElementAnnotation> get metadata {
5700 if (_unlinkedDefiningUnit != null) {
5701 _metadata ??= _buildAnnotations(
5702 _definingCompilationUnit as CompilationUnitElementImpl,
5703 _unlinkedDefiningUnit.libraryAnnotations);
5704 return _metadata;
5705 }
5706 return super.metadata;
5707 }
5708
5709 @override
5710 List<CompilationUnitElement> get parts => _parts;
5711
5712 /**
5713 * Set the compilation units that are included in this library using a `part`
5714 * directive to the given list of [parts].
5715 */
5716 void set parts(List<CompilationUnitElement> parts) {
5717 for (CompilationUnitElement compilationUnit in parts) {
5718 assert((compilationUnit as CompilationUnitElementImpl).librarySource ==
5719 source);
5720 (compilationUnit as CompilationUnitElementImpl).enclosingElement = this;
5721 }
5722 this._parts = parts;
5723 }
5724
5725 @override
5726 List<PrefixElement> get prefixes {
5727 if (_prefixes == null) {
5728 HashSet<PrefixElement> prefixes = new HashSet<PrefixElement>();
5729 for (ImportElement element in imports) {
5730 PrefixElement prefix = element.prefix;
5731 if (prefix != null) {
5732 prefixes.add(prefix);
5733 }
5734 }
5735 _prefixes = prefixes.toList(growable: false);
5736 }
5737 return _prefixes;
5738 }
5739
5740 @override
5741 Namespace get publicNamespace {
5742 if (resynthesizerContext != null) {
5743 _publicNamespace ??= resynthesizerContext.buildPublicNamespace();
5744 }
5745 return _publicNamespace;
5746 }
5747
5748 void set publicNamespace(Namespace publicNamespace) {
5749 _publicNamespace = publicNamespace;
5750 }
5751
5752 @override
5753 Source get source {
5754 if (_definingCompilationUnit == null) {
5755 return null;
5756 }
5757 return _definingCompilationUnit.source;
5758 }
5759
5760 @override
5761 List<CompilationUnitElement> get units {
5762 List<CompilationUnitElement> units = new List<CompilationUnitElement>();
5763 units.add(_definingCompilationUnit);
5764 units.addAll(_parts);
5765 return units;
5766 }
5767
5768 @override
5769 accept(ElementVisitor visitor) => visitor.visitLibraryElement(this);
5770
5771 /**
5772 * Create the [FunctionElement] to be returned by [loadLibraryFunction],
5773 * using types provided by [typeProvider].
5774 */
5775 void createLoadLibraryFunction(TypeProvider typeProvider) {
5776 FunctionElementImpl function =
5777 new FunctionElementImpl(FunctionElement.LOAD_LIBRARY_NAME, -1);
5778 function.synthetic = true;
5779 function.enclosingElement = this;
5780 function.returnType = typeProvider.futureDynamicType;
5781 function.type = new FunctionTypeImpl(function);
5782 _loadLibraryFunction = function;
5783 }
5784
5785 @override
5786 ElementImpl getChild(String identifier) {
5787 CompilationUnitElementImpl unitImpl = _definingCompilationUnit;
5788 if (unitImpl.identifier == identifier) {
5789 return unitImpl;
5790 }
5791 for (CompilationUnitElement part in _parts) {
5792 CompilationUnitElementImpl partImpl = part;
5793 if (partImpl.identifier == identifier) {
5794 return partImpl;
5795 }
5796 }
5797 for (ImportElement importElement in imports) {
5798 ImportElementImpl importElementImpl = importElement;
5799 if (importElementImpl.identifier == identifier) {
5800 return importElementImpl;
5801 }
5802 }
5803 for (ExportElement exportElement in exports) {
5804 ExportElementImpl exportElementImpl = exportElement;
5805 if (exportElementImpl.identifier == identifier) {
5806 return exportElementImpl;
5807 }
5808 }
5809 return null;
5810 }
5811
5812 @override
5813 List<ImportElement> getImportsWithPrefix(PrefixElement prefixElement) {
5814 var imports = this.imports;
5815 int count = imports.length;
5816 List<ImportElement> importList = new List<ImportElement>();
5817 for (int i = 0; i < count; i++) {
5818 if (identical(imports[i].prefix, prefixElement)) {
5819 importList.add(imports[i]);
5820 }
5821 }
5822 return importList;
5823 }
5824
5825 @override
5826 ClassElement getType(String className) {
5827 ClassElement type = _definingCompilationUnit.getType(className);
5828 if (type != null) {
5829 return type;
5830 }
5831 for (CompilationUnitElement part in _parts) {
5832 type = part.getType(className);
5833 if (type != null) {
5834 return type;
5835 }
5836 }
5837 return null;
5838 }
5839
5840 /** Given an update to this library which may have added or deleted edges
5841 * in the import/export graph originating from this node only, remove any
5842 * cached library cycles in the element model which may have been invalidated.
5843 */
5844 void invalidateLibraryCycles() {
5845 // If we have pre-computed library cycle information, then we must
5846 // invalidate the information both on this element, and on certain
5847 // other elements. Edges originating at this node may have been
5848 // added or deleted. A deleted edge that points outside of this cycle
5849 // cannot change the cycle information for anything outside of this cycle,
5850 // and so it is sufficient to delete the cached library information on this
5851 // cycle. An added edge which points to another node within the cycle
5852 // only invalidates the cycle. An added edge which points to a node earlier
5853 // in the topological sort of cycles induces no invalidation (since there
5854 // are by definition no back edges from earlier cycles in the topological
5855 // order, and hence no possible cycle can have been introduced. The only
5856 // remaining case is that we have added an edge to a node which is later
5857 // in the topological sort of cycles. This can induce cycles, since it
5858 // represents a new back edge. It would be sufficient to invalidate the
5859 // cycle information for all nodes that are between the target and the
5860 // node in the topological order. For simplicity, we simply invalidate
5861 // all nodes which are reachable from the source node.
5862 // Note that in the invalidation phase, we do not cut off when we encounter
5863 // a node with no library cycle information, since we do not know whether
5864 // we are in the case where invalidation has already been performed, or we
5865 // are in the case where library cycles have simply never been computed from
5866 // a newly reachable node.
5867 Set<LibraryElementImpl> active = new HashSet();
5868 void invalidate(LibraryElement element) {
5869 LibraryElementImpl library =
5870 element is LibraryElementHandle ? element.actualElement : element;
5871 if (active.add(library)) {
5872 if (library._libraryCycle != null) {
5873 library._libraryCycle.forEach(invalidate);
5874 library._libraryCycle = null;
5875 }
5876 library.exportedLibraries.forEach(invalidate);
5877 library.importedLibraries.forEach(invalidate);
5878 }
5879 }
5880
5881 invalidate(this);
5882 }
5883
5884 /**
5885 * Set whether the library has the given [capability] to
5886 * correspond to the given [value].
5887 */
5888 void setResolutionCapability(
5889 LibraryResolutionCapability capability, bool value) {
5890 _resolutionCapabilities =
5891 BooleanArray.set(_resolutionCapabilities, capability.index, value);
5892 }
5893
5894 @override
5895 void visitChildren(ElementVisitor visitor) {
5896 super.visitChildren(visitor);
5897 _definingCompilationUnit?.accept(visitor);
5898 safelyVisitChildren(exports, visitor);
5899 safelyVisitChildren(imports, visitor);
5900 safelyVisitChildren(_parts, visitor);
5901 }
5902
5903 /**
5904 * Return `true` if the [library] has the given [capability].
5905 */
5906 static bool hasResolutionCapability(
5907 LibraryElement library, LibraryResolutionCapability capability) {
5908 return library is LibraryElementImpl &&
5909 BooleanArray.get(library._resolutionCapabilities, capability.index);
5910 }
5911 }
5912
5913 /**
5914 * Enum of possible resolution capabilities that a [LibraryElementImpl] has.
5915 */
5916 enum LibraryResolutionCapability {
5917 /**
5918 * All elements have their types resolved.
5919 */
5920 resolvedTypeNames,
5921
5922 /**
5923 * All (potentially) constants expressions are set into corresponding
5924 * elements.
5925 */
5926 constantExpressions,
5927 }
5928
5929 /**
5930 * The context in which the library is resynthesized.
5931 */
5932 abstract class LibraryResynthesizerContext {
5933 /**
5934 * Return the [LinkedLibrary] that corresponds to the library being
5935 * resynthesized.
5936 */
5937 LinkedLibrary get linkedLibrary;
5938
5939 /**
5940 * Return the exported [LibraryElement] for with the given [relativeUri].
5941 */
5942 LibraryElement buildExportedLibrary(String relativeUri);
5943
5944 /**
5945 * Return the export namespace of the library.
5946 */
5947 Namespace buildExportNamespace();
5948
5949 /**
5950 * Return the imported [LibraryElement] for the given dependency in the
5951 * linked library.
5952 */
5953 LibraryElement buildImportedLibrary(int dependency);
5954
5955 /**
5956 * Return the public namespace of the library.
5957 */
5958 Namespace buildPublicNamespace();
5959
5960 /**
5961 * Find the entry point of the library.
5962 */
5963 FunctionElement findEntryPoint();
5964
5965 /**
5966 * Ensure that getters and setters in different units use the same
5967 * top-level variables.
5968 */
5969 void patchTopLevelAccessors();
5970 }
5971
5972 /**
5973 * A concrete implementation of a [LocalVariableElement].
5974 */
5975 class LocalVariableElementImpl extends NonParameterVariableElementImpl
5976 implements LocalVariableElement {
5977 /**
5978 * The offset to the beginning of the visible range for this element.
5979 */
5980 int _visibleRangeOffset = 0;
5981
5982 /**
5983 * The length of the visible range for this element, or `-1` if this element
5984 * does not have a visible range.
5985 */
5986 int _visibleRangeLength = -1;
5987
5988 /**
5989 * Initialize a newly created method element to have the given [name] and
5990 * [offset].
5991 */
5992 LocalVariableElementImpl(String name, int offset) : super(name, offset);
5993
5994 /**
5995 * Initialize a newly created local variable element to have the given [name].
5996 */
5997 LocalVariableElementImpl.forNode(Identifier name) : super.forNode(name);
5998
5999 /**
6000 * Initialize using the given serialized information.
6001 */
6002 LocalVariableElementImpl.forSerialized(UnlinkedVariable unlinkedVariable,
6003 ExecutableElementImpl enclosingExecutable)
6004 : super.forSerialized(unlinkedVariable, enclosingExecutable);
6005
6006 /**
6007 * Initialize using the given serialized information.
6008 */
6009 factory LocalVariableElementImpl.forSerializedFactory(
6010 UnlinkedVariable unlinkedVariable,
6011 ExecutableElementImpl enclosingExecutable) {
6012 if (unlinkedVariable.isConst &&
6013 unlinkedVariable.initializer?.bodyExpr != null) {
6014 return new ConstLocalVariableElementImpl.forSerialized(
6015 unlinkedVariable, enclosingExecutable);
6016 } else {
6017 return new LocalVariableElementImpl.forSerialized(
6018 unlinkedVariable, enclosingExecutable);
6019 }
6020 }
6021
6022 @override
6023 String get identifier {
6024 String identifier = super.identifier;
6025 Element enclosing = this.enclosingElement;
6026 if (enclosing is ExecutableElement) {
6027 int id = ElementImpl._findElementIndexUsingIdentical(
6028 enclosing.localVariables, this);
6029 identifier += "@$id";
6030 }
6031 return identifier;
6032 }
6033
6034 @override
6035 bool get isPotentiallyMutatedInClosure => true;
6036
6037 @override
6038 bool get isPotentiallyMutatedInScope => true;
6039
6040 @override
6041 ElementKind get kind => ElementKind.LOCAL_VARIABLE;
6042
6043 @override
6044 SourceRange get visibleRange {
6045 if (_unlinkedVariable != null) {
6046 if (_unlinkedVariable.visibleLength == 0) {
6047 return null;
6048 }
6049 return new SourceRange(
6050 _unlinkedVariable.visibleOffset, _unlinkedVariable.visibleLength);
6051 }
6052 if (_visibleRangeLength < 0) {
6053 return null;
6054 }
6055 return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
6056 }
6057
6058 @override
6059 accept(ElementVisitor visitor) => visitor.visitLocalVariableElement(this);
6060
6061 @override
6062 void appendTo(StringBuffer buffer) {
6063 buffer.write(type);
6064 buffer.write(" ");
6065 buffer.write(displayName);
6066 }
6067
6068 @override
6069 Declaration computeNode() => getNodeMatching(
6070 (node) => node is DeclaredIdentifier || node is VariableDeclaration);
6071
6072 /**
6073 * Set the visible range for this element to the range starting at the given
6074 * [offset] with the given [length].
6075 */
6076 void setVisibleRange(int offset, int length) {
6077 assert(_unlinkedVariable == null);
6078 _visibleRangeOffset = offset;
6079 _visibleRangeLength = length;
6080 }
6081 }
6082
6083 /**
6084 * A concrete implementation of a [MethodElement].
6085 */
6086 class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
6087 /**
6088 * Initialize a newly created method element to have the given [name] at the
6089 * given [offset].
6090 */
6091 MethodElementImpl(String name, int offset) : super(name, offset);
6092
6093 /**
6094 * Initialize a newly created method element to have the given [name].
6095 */
6096 MethodElementImpl.forNode(Identifier name) : super.forNode(name);
6097
6098 /**
6099 * Initialize using the given serialized information.
6100 */
6101 MethodElementImpl.forSerialized(
6102 UnlinkedExecutable serializedExecutable, ClassElementImpl enclosingClass)
6103 : super.forSerialized(serializedExecutable, enclosingClass);
6104
6105 /**
6106 * Set whether this method is abstract.
6107 */
6108 void set abstract(bool isAbstract) {
6109 assert(serializedExecutable == null);
6110 setModifier(Modifier.ABSTRACT, isAbstract);
6111 }
6112
6113 @override
6114 List<TypeParameterType> get allEnclosingTypeParameterTypes {
6115 if (isStatic) {
6116 return const <TypeParameterType>[];
6117 }
6118 return super.allEnclosingTypeParameterTypes;
6119 }
6120
6121 @override
6122 String get displayName {
6123 String displayName = super.displayName;
6124 if ("unary-" == displayName) {
6125 return "-";
6126 }
6127 return displayName;
6128 }
6129
6130 @override
6131 ClassElement get enclosingElement => super.enclosingElement as ClassElement;
6132
6133 @override
6134 TypeParameterizedElementMixin get enclosingTypeParameterContext =>
6135 super.enclosingElement as ClassElementImpl;
6136
6137 @override
6138 bool get isOperator {
6139 String name = displayName;
6140 if (name.isEmpty) {
6141 return false;
6142 }
6143 int first = name.codeUnitAt(0);
6144 return !((0x61 <= first && first <= 0x7A) ||
6145 (0x41 <= first && first <= 0x5A) ||
6146 first == 0x5F ||
6147 first == 0x24);
6148 }
6149
6150 @override
6151 bool get isStatic {
6152 if (serializedExecutable != null) {
6153 return serializedExecutable.isStatic;
6154 }
6155 return hasModifier(Modifier.STATIC);
6156 }
6157
6158 @override
6159 ElementKind get kind => ElementKind.METHOD;
6160
6161 @override
6162 String get name {
6163 String name = super.name;
6164 if (name == '-' && parameters.isEmpty) {
6165 return 'unary-';
6166 }
6167 return super.name;
6168 }
6169
6170 /**
6171 * Set whether this method is static.
6172 */
6173 void set static(bool isStatic) {
6174 assert(serializedExecutable == null);
6175 setModifier(Modifier.STATIC, isStatic);
6176 }
6177
6178 @override
6179 accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
6180
6181 @override
6182 void appendTo(StringBuffer buffer) {
6183 buffer.write(displayName);
6184 super.appendTo(buffer);
6185 }
6186
6187 @override
6188 MethodDeclaration computeNode() =>
6189 getNodeMatching((node) => node is MethodDeclaration);
6190 }
6191
6192 /**
6193 * The constants for all of the modifiers defined by the Dart language and for a
6194 * few additional flags that are useful.
6195 *
6196 * Clients may not extend, implement or mix-in this class.
6197 */
6198 class Modifier implements Comparable<Modifier> {
6199 /**
6200 * Indicates that the modifier 'abstract' was applied to the element.
6201 */
6202 static const Modifier ABSTRACT = const Modifier('ABSTRACT', 0);
6203
6204 /**
6205 * Indicates that an executable element has a body marked as being
6206 * asynchronous.
6207 */
6208 static const Modifier ASYNCHRONOUS = const Modifier('ASYNCHRONOUS', 1);
6209
6210 /**
6211 * Indicates that the modifier 'const' was applied to the element.
6212 */
6213 static const Modifier CONST = const Modifier('CONST', 2);
6214
6215 /**
6216 * Indicates that the import element represents a deferred library.
6217 */
6218 static const Modifier DEFERRED = const Modifier('DEFERRED', 3);
6219
6220 /**
6221 * Indicates that a class element was defined by an enum declaration.
6222 */
6223 static const Modifier ENUM = const Modifier('ENUM', 4);
6224
6225 /**
6226 * Indicates that a class element was defined by an enum declaration.
6227 */
6228 static const Modifier EXTERNAL = const Modifier('EXTERNAL', 5);
6229
6230 /**
6231 * Indicates that the modifier 'factory' was applied to the element.
6232 */
6233 static const Modifier FACTORY = const Modifier('FACTORY', 6);
6234
6235 /**
6236 * Indicates that the modifier 'final' was applied to the element.
6237 */
6238 static const Modifier FINAL = const Modifier('FINAL', 7);
6239
6240 /**
6241 * Indicates that an executable element has a body marked as being a
6242 * generator.
6243 */
6244 static const Modifier GENERATOR = const Modifier('GENERATOR', 8);
6245
6246 /**
6247 * Indicates that the pseudo-modifier 'get' was applied to the element.
6248 */
6249 static const Modifier GETTER = const Modifier('GETTER', 9);
6250
6251 /**
6252 * A flag used for libraries indicating that the defining compilation unit
6253 * contains at least one import directive whose URI uses the "dart-ext"
6254 * scheme.
6255 */
6256 static const Modifier HAS_EXT_URI = const Modifier('HAS_EXT_URI', 10);
6257
6258 /**
6259 * Indicates that the associated element did not have an explicit type
6260 * associated with it. If the element is an [ExecutableElement], then the
6261 * type being referred to is the return type.
6262 */
6263 static const Modifier IMPLICIT_TYPE = const Modifier('IMPLICIT_TYPE', 11);
6264
6265 /**
6266 * Indicates that a class is a mixin application.
6267 */
6268 static const Modifier MIXIN_APPLICATION =
6269 const Modifier('MIXIN_APPLICATION', 12);
6270
6271 /**
6272 * Indicates that a class contains an explicit reference to 'super'.
6273 */
6274 static const Modifier REFERENCES_SUPER =
6275 const Modifier('REFERENCES_SUPER', 13);
6276
6277 /**
6278 * Indicates that the pseudo-modifier 'set' was applied to the element.
6279 */
6280 static const Modifier SETTER = const Modifier('SETTER', 14);
6281
6282 /**
6283 * Indicates that the modifier 'static' was applied to the element.
6284 */
6285 static const Modifier STATIC = const Modifier('STATIC', 15);
6286
6287 /**
6288 * Indicates that the element does not appear in the source code but was
6289 * implicitly created. For example, if a class does not define any
6290 * constructors, an implicit zero-argument constructor will be created and it
6291 * will be marked as being synthetic.
6292 */
6293 static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 16);
6294
6295 static const List<Modifier> values = const [
6296 ABSTRACT,
6297 ASYNCHRONOUS,
6298 CONST,
6299 DEFERRED,
6300 ENUM,
6301 EXTERNAL,
6302 FACTORY,
6303 FINAL,
6304 GENERATOR,
6305 GETTER,
6306 HAS_EXT_URI,
6307 IMPLICIT_TYPE,
6308 MIXIN_APPLICATION,
6309 REFERENCES_SUPER,
6310 SETTER,
6311 STATIC,
6312 SYNTHETIC
6313 ];
6314
6315 /**
6316 * The name of this modifier.
6317 */
6318 final String name;
6319
6320 /**
6321 * The ordinal value of the modifier.
6322 */
6323 final int ordinal;
6324
6325 const Modifier(this.name, this.ordinal);
6326
6327 @override
6328 int get hashCode => ordinal;
6329
6330 @override
6331 int compareTo(Modifier other) => ordinal - other.ordinal;
6332
6333 @override
6334 String toString() => name;
6335 }
6336
6337 /**
6338 * A concrete implementation of a [MultiplyDefinedElement].
6339 */
6340 class MultiplyDefinedElementImpl implements MultiplyDefinedElement {
6341 /**
6342 * The unique integer identifier of this element.
6343 */
6344 final int id = ElementImpl._NEXT_ID++;
6345
6346 /**
6347 * The analysis context in which the multiply defined elements are defined.
6348 */
6349 final AnalysisContext context;
6350
6351 /**
6352 * The name of the conflicting elements.
6353 */
6354 String _name;
6355
6356 /**
6357 * A list containing all of the elements defined in SDK libraries that
6358 * conflict.
6359 */
6360 final List<Element> sdkElements;
6361
6362 /**
6363 * A list containing all of the elements defined in non-SDK libraries that
6364 * conflict.
6365 */
6366 final List<Element> nonSdkElements;
6367
6368 /**
6369 * Initialize a newly created element in the given [context] to represent a
6370 * list of conflicting [sdkElements] and [nonSdkElements]. At least one of the
6371 * lists must contain more than one element.
6372 */
6373 MultiplyDefinedElementImpl(
6374 this.context, this.sdkElements, this.nonSdkElements) {
6375 if (nonSdkElements.length > 0) {
6376 _name = nonSdkElements[0].name;
6377 } else {
6378 _name = sdkElements[0].name;
6379 }
6380 }
6381
6382 @override
6383 List<Element> get conflictingElements {
6384 if (sdkElements.isEmpty) {
6385 return nonSdkElements;
6386 } else if (nonSdkElements.isEmpty) {
6387 return sdkElements;
6388 }
6389 List<Element> elements = nonSdkElements.toList();
6390 elements.addAll(sdkElements);
6391 return elements;
6392 }
6393
6394 @override
6395 String get displayName => _name;
6396
6397 @override
6398 String get documentationComment => null;
6399
6400 @override
6401 Element get enclosingElement => null;
6402
6403 @override
6404 bool get isDeprecated => false;
6405
6406 @override
6407 bool get isFactory => false;
6408
6409 @override
6410 bool get isJS => false;
6411
6412 @override
6413 bool get isOverride => false;
6414
6415 @override
6416 bool get isPrivate {
6417 String name = displayName;
6418 if (name == null) {
6419 return false;
6420 }
6421 return Identifier.isPrivateName(name);
6422 }
6423
6424 @override
6425 bool get isProtected => false;
6426
6427 @override
6428 bool get isPublic => !isPrivate;
6429
6430 @override
6431 bool get isRequired => false;
6432
6433 @override
6434 bool get isSynthetic => true;
6435
6436 @override
6437 ElementKind get kind => ElementKind.ERROR;
6438
6439 @override
6440 LibraryElement get library => null;
6441
6442 @override
6443 Source get librarySource => null;
6444
6445 @override
6446 ElementLocation get location => null;
6447
6448 @override
6449 List<ElementAnnotation> get metadata => const <ElementAnnotation>[];
6450
6451 @override
6452 String get name => _name;
6453
6454 @override
6455 int get nameLength => displayName != null ? displayName.length : 0;
6456
6457 @override
6458 int get nameOffset => -1;
6459
6460 @override
6461 Source get source => null;
6462
6463 @override
6464 DartType get type => DynamicTypeImpl.instance;
6465
6466 @override
6467 CompilationUnit get unit => null;
6468
6469 @override
6470 accept(ElementVisitor visitor) => visitor.visitMultiplyDefinedElement(this);
6471
6472 @override
6473 String computeDocumentationComment() => null;
6474
6475 @override
6476 AstNode computeNode() => null;
6477
6478 @override
6479 Element/*=E*/ getAncestor/*<E extends Element >*/(
6480 Predicate<Element> predicate) =>
6481 null;
6482
6483 @override
6484 String getExtendedDisplayName(String shortName) {
6485 if (shortName != null) {
6486 return shortName;
6487 }
6488 return displayName;
6489 }
6490
6491 @override
6492 bool isAccessibleIn(LibraryElement library) {
6493 for (Element element in conflictingElements) {
6494 if (element.isAccessibleIn(library)) {
6495 return true;
6496 }
6497 }
6498 return false;
6499 }
6500
6501 @override
6502 String toString() {
6503 StringBuffer buffer = new StringBuffer();
6504 bool needsSeparator = false;
6505 void writeList(List<Element> elements) {
6506 for (Element element in elements) {
6507 if (needsSeparator) {
6508 buffer.write(", ");
6509 } else {
6510 needsSeparator = true;
6511 }
6512 if (element is ElementImpl) {
6513 element.appendTo(buffer);
6514 } else {
6515 buffer.write(element);
6516 }
6517 }
6518 }
6519
6520 buffer.write("[");
6521 writeList(nonSdkElements);
6522 writeList(sdkElements);
6523 buffer.write("]");
6524 return buffer.toString();
6525 }
6526
6527 @override
6528 void visitChildren(ElementVisitor visitor) {
6529 // There are no children to visit
6530 }
6531
6532 /**
6533 * Return an element in the given [context] that represents the fact that the
6534 * [firstElement] and [secondElement] conflict. (If the elements are the same,
6535 * then one of the two will be returned directly.)
6536 */
6537 static Element fromElements(
6538 AnalysisContext context, Element firstElement, Element secondElement) {
6539 Set<Element> sdkElements = new HashSet<Element>.identity();
6540 Set<Element> nonSdkElements = new HashSet<Element>.identity();
6541 void add(Element element) {
6542 if (element != null) {
6543 if (element is MultiplyDefinedElementImpl) {
6544 sdkElements.addAll(element.sdkElements);
6545 nonSdkElements.addAll(element.nonSdkElements);
6546 } else if (element.library.isInSdk) {
6547 sdkElements.add(element);
6548 } else {
6549 nonSdkElements.add(element);
6550 }
6551 }
6552 }
6553
6554 add(firstElement);
6555 add(secondElement);
6556 int nonSdkCount = nonSdkElements.length;
6557 if (nonSdkCount == 0) {
6558 int sdkCount = sdkElements.length;
6559 if (sdkCount == 0) {
6560 return null;
6561 } else if (sdkCount == 1) {
6562 return sdkElements.first;
6563 }
6564 } else if (nonSdkCount == 1) {
6565 return nonSdkElements.first;
6566 }
6567 return new MultiplyDefinedElementImpl(
6568 context,
6569 sdkElements.toList(growable: false),
6570 nonSdkElements.toList(growable: false));
6571 }
6572 }
6573
6574 /**
6575 * A [MethodElementImpl], with the additional information of a list of
6576 * [ExecutableElement]s from which this element was composed.
6577 */
6578 class MultiplyInheritedMethodElementImpl extends MethodElementImpl
6579 implements MultiplyInheritedExecutableElement {
6580 /**
6581 * A list the array of executable elements that were used to compose this
6582 * element.
6583 */
6584 List<ExecutableElement> _elements = MethodElement.EMPTY_LIST;
6585
6586 MultiplyInheritedMethodElementImpl(Identifier name) : super.forNode(name) {
6587 synthetic = true;
6588 }
6589
6590 @override
6591 List<ExecutableElement> get inheritedElements => _elements;
6592
6593 void set inheritedElements(List<ExecutableElement> elements) {
6594 this._elements = elements;
6595 }
6596 }
6597
6598 /**
6599 * A [PropertyAccessorElementImpl], with the additional information of a list of
6600 * [ExecutableElement]s from which this element was composed.
6601 */
6602 class MultiplyInheritedPropertyAccessorElementImpl
6603 extends PropertyAccessorElementImpl
6604 implements MultiplyInheritedExecutableElement {
6605 /**
6606 * A list the array of executable elements that were used to compose this
6607 * element.
6608 */
6609 List<ExecutableElement> _elements = PropertyAccessorElement.EMPTY_LIST;
6610
6611 MultiplyInheritedPropertyAccessorElementImpl(Identifier name)
6612 : super.forNode(name) {
6613 synthetic = true;
6614 }
6615
6616 @override
6617 TypeParameterizedElementMixin get enclosingTypeParameterContext => null;
6618
6619 @override
6620 List<ExecutableElement> get inheritedElements => _elements;
6621
6622 void set inheritedElements(List<ExecutableElement> elements) {
6623 this._elements = elements;
6624 }
6625 }
6626
6627 /**
6628 * A [VariableElementImpl], which is not a parameter.
6629 */
6630 abstract class NonParameterVariableElementImpl extends VariableElementImpl {
6631 /**
6632 * The unlinked representation of the variable in the summary.
6633 */
6634 final UnlinkedVariable _unlinkedVariable;
6635
6636 /**
6637 * Initialize a newly created variable element to have the given [name] and
6638 * [offset].
6639 */
6640 NonParameterVariableElementImpl(String name, int offset)
6641 : _unlinkedVariable = null,
6642 super(name, offset);
6643
6644 /**
6645 * Initialize a newly created variable element to have the given [name].
6646 */
6647 NonParameterVariableElementImpl.forNode(Identifier name)
6648 : _unlinkedVariable = null,
6649 super.forNode(name);
6650
6651 /**
6652 * Initialize using the given serialized information.
6653 */
6654 NonParameterVariableElementImpl.forSerialized(
6655 this._unlinkedVariable, ElementImpl enclosingElement)
6656 : super.forSerialized(enclosingElement);
6657
6658 @override
6659 int get codeLength {
6660 if (_unlinkedVariable != null) {
6661 return _unlinkedVariable.codeRange?.length;
6662 }
6663 return super.codeLength;
6664 }
6665
6666 @override
6667 int get codeOffset {
6668 if (_unlinkedVariable != null) {
6669 return _unlinkedVariable.codeRange?.offset;
6670 }
6671 return super.codeOffset;
6672 }
6673
6674 @override
6675 void set const3(bool isConst) {
6676 assert(_unlinkedVariable == null);
6677 super.const3 = isConst;
6678 }
6679
6680 @override
6681 String get documentationComment {
6682 if (_unlinkedVariable != null) {
6683 return _unlinkedVariable?.documentationComment?.text;
6684 }
6685 return super.documentationComment;
6686 }
6687
6688 @override
6689 void set final2(bool isFinal) {
6690 assert(_unlinkedVariable == null);
6691 super.final2 = isFinal;
6692 }
6693
6694 @override
6695 bool get hasImplicitType {
6696 if (_unlinkedVariable != null) {
6697 return _unlinkedVariable.type == null;
6698 }
6699 return super.hasImplicitType;
6700 }
6701
6702 @override
6703 void set hasImplicitType(bool hasImplicitType) {
6704 assert(_unlinkedVariable == null);
6705 super.hasImplicitType = hasImplicitType;
6706 }
6707
6708 @override
6709 FunctionElement get initializer {
6710 if (_unlinkedVariable != null && _initializer == null) {
6711 UnlinkedExecutable unlinkedInitializer = _unlinkedVariable.initializer;
6712 if (unlinkedInitializer != null) {
6713 _initializer = new FunctionElementImpl.forSerialized(
6714 unlinkedInitializer, this)..synthetic = true;
6715 } else {
6716 return null;
6717 }
6718 }
6719 return super.initializer;
6720 }
6721
6722 /**
6723 * Set the function representing this variable's initializer to the given
6724 * [function].
6725 */
6726 void set initializer(FunctionElement function) {
6727 assert(_unlinkedVariable == null);
6728 super.initializer = function;
6729 }
6730
6731 @override
6732 bool get isConst {
6733 if (_unlinkedVariable != null) {
6734 return _unlinkedVariable.isConst;
6735 }
6736 return super.isConst;
6737 }
6738
6739 @override
6740 bool get isFinal {
6741 if (_unlinkedVariable != null) {
6742 return _unlinkedVariable.isFinal;
6743 }
6744 return super.isFinal;
6745 }
6746
6747 @override
6748 List<ElementAnnotation> get metadata {
6749 if (_unlinkedVariable != null) {
6750 return _metadata ??=
6751 _buildAnnotations(enclosingUnit, _unlinkedVariable.annotations);
6752 }
6753 return super.metadata;
6754 }
6755
6756 @override
6757 String get name {
6758 if (_unlinkedVariable != null) {
6759 return _unlinkedVariable.name;
6760 }
6761 return super.name;
6762 }
6763
6764 @override
6765 int get nameOffset {
6766 if (_unlinkedVariable != null) {
6767 return _unlinkedVariable.nameOffset;
6768 }
6769 return super.nameOffset;
6770 }
6771
6772 @override
6773 DartType get type {
6774 if (_unlinkedVariable != null && _type == null) {
6775 _type = enclosingUnit.resynthesizerContext.resolveLinkedType(
6776 _unlinkedVariable.inferredTypeSlot, typeParameterContext) ??
6777 enclosingUnit.resynthesizerContext
6778 .resolveTypeRef(_unlinkedVariable.type, typeParameterContext);
6779 }
6780 return super.type;
6781 }
6782
6783 void set type(DartType type) {
6784 assert(_unlinkedVariable == null);
6785 _type = type;
6786 }
6787
6788 /**
6789 * Subclasses need this getter, see [ConstVariableElement._unlinkedConst].
6790 */
6791 UnlinkedConst get _unlinkedConst => _unlinkedVariable?.initializer?.bodyExpr;
6792 }
6793
6794 /**
6795 * A concrete implementation of a [ParameterElement].
6796 */
6797 class ParameterElementImpl extends VariableElementImpl
6798 with ParameterElementMixin
6799 implements ParameterElement {
6800 /**
6801 * The unlinked representation of the parameter in the summary.
6802 */
6803 final UnlinkedParam _unlinkedParam;
6804
6805 /**
6806 * A list containing all of the parameters defined by this parameter element.
6807 * There will only be parameters if this parameter is a function typed
6808 * parameter.
6809 */
6810 List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
6811
6812 /**
6813 * A list containing all of the type parameters defined for this parameter
6814 * element. There will only be parameters if this parameter is a function
6815 * typed parameter.
6816 */
6817 List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
6818
6819 /**
6820 * The kind of this parameter.
6821 */
6822 ParameterKind _parameterKind;
6823
6824 /**
6825 * The Dart code of the default value.
6826 */
6827 String _defaultValueCode;
6828
6829 /**
6830 * The offset to the beginning of the visible range for this element.
6831 */
6832 int _visibleRangeOffset = 0;
6833
6834 /**
6835 * The length of the visible range for this element, or `-1` if this element
6836 * does not have a visible range.
6837 */
6838 int _visibleRangeLength = -1;
6839
6840 bool _inheritsCovariant = false;
6841
6842 /**
6843 * Initialize a newly created parameter element to have the given [name] and
6844 * [nameOffset].
6845 */
6846 ParameterElementImpl(String name, int nameOffset)
6847 : _unlinkedParam = null,
6848 super(name, nameOffset);
6849
6850 /**
6851 * Initialize a newly created parameter element to have the given [name].
6852 */
6853 ParameterElementImpl.forNode(Identifier name)
6854 : _unlinkedParam = null,
6855 super.forNode(name);
6856
6857 /**
6858 * Initialize using the given serialized information.
6859 */
6860 ParameterElementImpl.forSerialized(
6861 this._unlinkedParam, ElementImpl enclosingElement)
6862 : super.forSerialized(enclosingElement);
6863
6864 /**
6865 * Initialize using the given serialized information.
6866 */
6867 factory ParameterElementImpl.forSerializedFactory(
6868 UnlinkedParam unlinkedParameter, ElementImpl enclosingElement,
6869 {bool synthetic: false}) {
6870 ParameterElementImpl element;
6871 if (unlinkedParameter.isInitializingFormal) {
6872 if (unlinkedParameter.kind == UnlinkedParamKind.required) {
6873 element = new FieldFormalParameterElementImpl.forSerialized(
6874 unlinkedParameter, enclosingElement);
6875 } else {
6876 element = new DefaultFieldFormalParameterElementImpl.forSerialized(
6877 unlinkedParameter, enclosingElement);
6878 }
6879 } else {
6880 if (unlinkedParameter.kind == UnlinkedParamKind.required) {
6881 element = new ParameterElementImpl.forSerialized(
6882 unlinkedParameter, enclosingElement);
6883 } else {
6884 element = new DefaultParameterElementImpl.forSerialized(
6885 unlinkedParameter, enclosingElement);
6886 }
6887 }
6888 element.synthetic = synthetic;
6889 return element;
6890 }
6891
6892 /**
6893 * Creates a synthetic parameter with [name], [type] and [kind].
6894 */
6895 factory ParameterElementImpl.synthetic(
6896 String name, DartType type, ParameterKind kind) {
6897 ParameterElementImpl element = new ParameterElementImpl(name, -1);
6898 element.type = type;
6899 element.synthetic = true;
6900 element.parameterKind = kind;
6901 return element;
6902 }
6903
6904 @override
6905 int get codeLength {
6906 if (_unlinkedParam != null) {
6907 return _unlinkedParam.codeRange?.length;
6908 }
6909 return super.codeLength;
6910 }
6911
6912 @override
6913 int get codeOffset {
6914 if (_unlinkedParam != null) {
6915 return _unlinkedParam.codeRange?.offset;
6916 }
6917 return super.codeOffset;
6918 }
6919
6920 @override
6921 void set const3(bool isConst) {
6922 assert(_unlinkedParam == null);
6923 super.const3 = isConst;
6924 }
6925
6926 @override
6927 String get defaultValueCode {
6928 if (_unlinkedParam != null) {
6929 if (_unlinkedParam.initializer?.bodyExpr == null) {
6930 return null;
6931 }
6932 return _unlinkedParam.defaultValueCode;
6933 }
6934 return _defaultValueCode;
6935 }
6936
6937 /**
6938 * Set Dart code of the default value.
6939 */
6940 void set defaultValueCode(String defaultValueCode) {
6941 assert(_unlinkedParam == null);
6942 this._defaultValueCode = StringUtilities.intern(defaultValueCode);
6943 }
6944
6945 @override
6946 void set final2(bool isFinal) {
6947 assert(_unlinkedParam == null);
6948 super.final2 = isFinal;
6949 }
6950
6951 @override
6952 bool get hasImplicitType {
6953 if (_unlinkedParam != null) {
6954 return _unlinkedParam.type == null;
6955 }
6956 return super.hasImplicitType;
6957 }
6958
6959 @override
6960 void set hasImplicitType(bool hasImplicitType) {
6961 assert(_unlinkedParam == null);
6962 super.hasImplicitType = hasImplicitType;
6963 }
6964
6965 /**
6966 * True if this parameter inherits from a covariant parameter. This happens
6967 * when it overrides a method in a supertype that has a corresponding
6968 * covariant parameter.
6969 */
6970 bool get inheritsCovariant {
6971 if (_unlinkedParam != null) {
6972 return enclosingUnit.resynthesizerContext
6973 .inheritsCovariant(_unlinkedParam.inheritsCovariantSlot);
6974 } else {
6975 return _inheritsCovariant;
6976 }
6977 }
6978
6979 /**
6980 * Record whether or not this parameter inherits from a covariant parameter.
6981 */
6982 void set inheritsCovariant(bool value) {
6983 assert(_unlinkedParam == null);
6984 _inheritsCovariant = value;
6985 }
6986
6987 @override
6988 FunctionElement get initializer {
6989 if (_unlinkedParam != null && _initializer == null) {
6990 UnlinkedExecutable unlinkedInitializer = _unlinkedParam.initializer;
6991 if (unlinkedInitializer != null) {
6992 _initializer = new FunctionElementImpl.forSerialized(
6993 unlinkedInitializer, this)..synthetic = true;
6994 } else {
6995 return null;
6996 }
6997 }
6998 return super.initializer;
6999 }
7000
7001 /**
7002 * Set the function representing this variable's initializer to the given
7003 * [function].
7004 */
7005 void set initializer(FunctionElement function) {
7006 assert(_unlinkedParam == null);
7007 super.initializer = function;
7008 }
7009
7010 @override
7011 bool get isConst {
7012 if (_unlinkedParam != null) {
7013 return false;
7014 }
7015 return super.isConst;
7016 }
7017
7018 @override
7019 bool get isCovariant {
7020 if (inheritsCovariant) {
7021 return true;
7022 }
7023 for (ElementAnnotationImpl annotation in metadata) {
7024 if (annotation.isCovariant) {
7025 return true;
7026 }
7027 }
7028 return false;
7029 }
7030
7031 @override
7032 bool get isFinal {
7033 if (_unlinkedParam != null) {
7034 return false;
7035 }
7036 return super.isFinal;
7037 }
7038
7039 @override
7040 bool get isInitializingFormal => false;
7041
7042 @override
7043 bool get isPotentiallyMutatedInClosure => true;
7044
7045 @override
7046 bool get isPotentiallyMutatedInScope => true;
7047
7048 @override
7049 ElementKind get kind => ElementKind.PARAMETER;
7050
7051 @override
7052 List<ElementAnnotation> get metadata {
7053 if (_unlinkedParam != null) {
7054 return _metadata ??=
7055 _buildAnnotations(enclosingUnit, _unlinkedParam.annotations);
7056 }
7057 return super.metadata;
7058 }
7059
7060 @override
7061 String get name {
7062 if (_unlinkedParam != null) {
7063 return _unlinkedParam.name;
7064 }
7065 return super.name;
7066 }
7067
7068 @override
7069 int get nameOffset {
7070 if (_unlinkedParam != null) {
7071 if (isSynthetic) {
7072 return -1;
7073 }
7074 return _unlinkedParam.nameOffset;
7075 }
7076 return super.nameOffset;
7077 }
7078
7079 @override
7080 ParameterKind get parameterKind {
7081 if (_unlinkedParam != null && _parameterKind == null) {
7082 switch (_unlinkedParam.kind) {
7083 case UnlinkedParamKind.named:
7084 _parameterKind = ParameterKind.NAMED;
7085 break;
7086 case UnlinkedParamKind.positional:
7087 _parameterKind = ParameterKind.POSITIONAL;
7088 break;
7089 case UnlinkedParamKind.required:
7090 _parameterKind = ParameterKind.REQUIRED;
7091 break;
7092 }
7093 }
7094 return _parameterKind;
7095 }
7096
7097 void set parameterKind(ParameterKind parameterKind) {
7098 assert(_unlinkedParam == null);
7099 _parameterKind = parameterKind;
7100 }
7101
7102 @override
7103 List<ParameterElement> get parameters {
7104 _resynthesizeTypeAndParameters();
7105 return _parameters;
7106 }
7107
7108 /**
7109 * Set the parameters defined by this executable element to the given
7110 * [parameters].
7111 */
7112 void set parameters(List<ParameterElement> parameters) {
7113 for (ParameterElement parameter in parameters) {
7114 (parameter as ParameterElementImpl).enclosingElement = this;
7115 }
7116 this._parameters = parameters;
7117 }
7118
7119 @override
7120 DartType get type {
7121 _resynthesizeTypeAndParameters();
7122 return super.type;
7123 }
7124
7125 @override
7126 List<TypeParameterElement> get typeParameters => _typeParameters;
7127
7128 /**
7129 * Set the type parameters defined by this parameter element to the given
7130 * [typeParameters].
7131 */
7132 void set typeParameters(List<TypeParameterElement> typeParameters) {
7133 for (TypeParameterElement parameter in typeParameters) {
7134 (parameter as TypeParameterElementImpl).enclosingElement = this;
7135 }
7136 this._typeParameters = typeParameters;
7137 }
7138
7139 @override
7140 SourceRange get visibleRange {
7141 if (_unlinkedParam != null) {
7142 if (_unlinkedParam.visibleLength == 0) {
7143 return null;
7144 }
7145 return new SourceRange(
7146 _unlinkedParam.visibleOffset, _unlinkedParam.visibleLength);
7147 }
7148 if (_visibleRangeLength < 0) {
7149 return null;
7150 }
7151 return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
7152 }
7153
7154 /**
7155 * Subclasses need this getter, see [ConstVariableElement._unlinkedConst].
7156 */
7157 UnlinkedConst get _unlinkedConst => _unlinkedParam?.initializer?.bodyExpr;
7158
7159 @override
7160 accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
7161
7162 @override
7163 void appendTo(StringBuffer buffer) {
7164 String left = "";
7165 String right = "";
7166 while (true) {
7167 if (parameterKind == ParameterKind.NAMED) {
7168 left = "{";
7169 right = "}";
7170 } else if (parameterKind == ParameterKind.POSITIONAL) {
7171 left = "[";
7172 right = "]";
7173 } else if (parameterKind == ParameterKind.REQUIRED) {}
7174 break;
7175 }
7176 buffer.write(left);
7177 appendToWithoutDelimiters(buffer);
7178 buffer.write(right);
7179 }
7180
7181 @override
7182 FormalParameter computeNode() =>
7183 getNodeMatching((node) => node is FormalParameter);
7184
7185 @override
7186 ElementImpl getChild(String identifier) {
7187 for (ParameterElement parameter in _parameters) {
7188 ParameterElementImpl parameterImpl = parameter;
7189 if (parameterImpl.identifier == identifier) {
7190 return parameterImpl;
7191 }
7192 }
7193 return null;
7194 }
7195
7196 /**
7197 * Set the visible range for this element to the range starting at the given
7198 * [offset] with the given [length].
7199 */
7200 void setVisibleRange(int offset, int length) {
7201 assert(_unlinkedParam == null);
7202 _visibleRangeOffset = offset;
7203 _visibleRangeLength = length;
7204 }
7205
7206 @override
7207 void visitChildren(ElementVisitor visitor) {
7208 super.visitChildren(visitor);
7209 safelyVisitChildren(parameters, visitor);
7210 }
7211
7212 /**
7213 * If this element is resynthesized, and its type and parameters have not
7214 * been build yet, build them and remember in the corresponding fields.
7215 */
7216 void _resynthesizeTypeAndParameters() {
7217 if (_unlinkedParam != null && _type == null) {
7218 if (_unlinkedParam.isFunctionTyped) {
7219 CompilationUnitElementImpl enclosingUnit = this.enclosingUnit;
7220 FunctionElementImpl parameterTypeElement =
7221 new FunctionElementImpl_forFunctionTypedParameter(
7222 enclosingUnit, this);
7223 if (!isSynthetic) {
7224 parameterTypeElement.enclosingElement = this;
7225 }
7226 List<ParameterElement> subParameters = ParameterElementImpl
7227 .resynthesizeList(_unlinkedParam.parameters, this,
7228 synthetic: isSynthetic);
7229 if (isSynthetic) {
7230 parameterTypeElement.parameters = subParameters;
7231 } else {
7232 _parameters = subParameters;
7233 parameterTypeElement.shareParameters(subParameters);
7234 }
7235 parameterTypeElement.returnType = enclosingUnit.resynthesizerContext
7236 .resolveTypeRef(_unlinkedParam.type, typeParameterContext);
7237 FunctionTypeImpl parameterType =
7238 new FunctionTypeImpl.elementWithNameAndArgs(parameterTypeElement,
7239 null, typeParameterContext.allTypeParameterTypes, false);
7240 parameterTypeElement.type = parameterType;
7241 _type = parameterType;
7242 } else {
7243 _type = enclosingUnit.resynthesizerContext.resolveLinkedType(
7244 _unlinkedParam.inferredTypeSlot, typeParameterContext) ??
7245 enclosingUnit.resynthesizerContext
7246 .resolveTypeRef(_unlinkedParam.type, typeParameterContext);
7247 }
7248 }
7249 }
7250
7251 /**
7252 * Create and return [ParameterElement]s for the given [unlinkedParameters].
7253 */
7254 static List<ParameterElement> resynthesizeList(
7255 List<UnlinkedParam> unlinkedParameters, ElementImpl enclosingElement,
7256 {bool synthetic: false}) {
7257 int length = unlinkedParameters.length;
7258 if (length != 0) {
7259 List<ParameterElement> parameters = new List<ParameterElement>(length);
7260 for (int i = 0; i < length; i++) {
7261 parameters[i] = new ParameterElementImpl.forSerializedFactory(
7262 unlinkedParameters[i], enclosingElement,
7263 synthetic: synthetic);
7264 }
7265 return parameters;
7266 } else {
7267 return const <ParameterElement>[];
7268 }
7269 }
7270 }
7271
7272 /**
7273 * The parameter of an implicit setter.
7274 */
7275 class ParameterElementImpl_ofImplicitSetter extends ParameterElementImpl {
7276 final PropertyAccessorElementImpl_ImplicitSetter setter;
7277
7278 ParameterElementImpl_ofImplicitSetter(
7279 PropertyAccessorElementImpl_ImplicitSetter setter)
7280 : setter = setter,
7281 super('_${setter.variable.name}', setter.variable.nameOffset) {
7282 enclosingElement = setter;
7283 synthetic = true;
7284 parameterKind = ParameterKind.REQUIRED;
7285 }
7286
7287 @override
7288 bool get isCovariant {
7289 if (inheritsCovariant) {
7290 return true;
7291 }
7292 for (ElementAnnotationImpl annotation in setter.variable.metadata) {
7293 if (annotation.isCovariant) {
7294 return true;
7295 }
7296 }
7297 return false;
7298 }
7299
7300 @override
7301 DartType get type => setter.variable.type;
7302
7303 @override
7304 void set type(DartType type) {
7305 assert(false); // Should never be called.
7306 }
7307 }
7308
7309 /**
7310 * A mixin that provides a common implementation for methods defined in
7311 * [ParameterElement].
7312 */
7313 abstract class ParameterElementMixin implements ParameterElement {
7314 @override
7315 void appendToWithoutDelimiters(StringBuffer buffer) {
7316 buffer.write(type);
7317 buffer.write(" ");
7318 buffer.write(displayName);
7319 if (defaultValueCode != null) {
7320 if (parameterKind == ParameterKind.NAMED) {
7321 buffer.write(": ");
7322 }
7323 if (parameterKind == ParameterKind.POSITIONAL) {
7324 buffer.write(" = ");
7325 }
7326 buffer.write(defaultValueCode);
7327 }
7328 }
7329 }
7330
7331 /**
7332 * A concrete implementation of a [PrefixElement].
7333 */
7334 class PrefixElementImpl extends ElementImpl implements PrefixElement {
7335 /**
7336 * The unlinked representation of the import in the summary.
7337 */
7338 final UnlinkedImport _unlinkedImport;
7339
7340 /**
7341 * Initialize a newly created method element to have the given [name] and
7342 * [nameOffset].
7343 */
7344 PrefixElementImpl(String name, int nameOffset)
7345 : _unlinkedImport = null,
7346 super(name, nameOffset);
7347
7348 /**
7349 * Initialize a newly created prefix element to have the given [name].
7350 */
7351 PrefixElementImpl.forNode(Identifier name)
7352 : _unlinkedImport = null,
7353 super.forNode(name);
7354
7355 /**
7356 * Initialize using the given serialized information.
7357 */
7358 PrefixElementImpl.forSerialized(
7359 this._unlinkedImport, LibraryElementImpl enclosingLibrary)
7360 : super.forSerialized(enclosingLibrary);
7361
7362 @override
7363 String get displayName => name;
7364
7365 @override
7366 LibraryElement get enclosingElement =>
7367 super.enclosingElement as LibraryElement;
7368
7369 @override
7370 String get identifier => "_${super.identifier}";
7371
7372 @override
7373 List<LibraryElement> get importedLibraries => LibraryElement.EMPTY_LIST;
7374
7375 @override
7376 ElementKind get kind => ElementKind.PREFIX;
7377
7378 @override
7379 String get name {
7380 if (_unlinkedImport != null) {
7381 if (_name == null) {
7382 LibraryElementImpl library = enclosingElement as LibraryElementImpl;
7383 int prefixId = _unlinkedImport.prefixReference;
7384 return _name = library._unlinkedDefiningUnit.references[prefixId].name;
7385 }
7386 }
7387 return super.name;
7388 }
7389
7390 @override
7391 int get nameOffset {
7392 if (_unlinkedImport != null) {
7393 return _unlinkedImport.prefixOffset;
7394 }
7395 return super.nameOffset;
7396 }
7397
7398 @override
7399 accept(ElementVisitor visitor) => visitor.visitPrefixElement(this);
7400
7401 @override
7402 void appendTo(StringBuffer buffer) {
7403 buffer.write("as ");
7404 super.appendTo(buffer);
7405 }
7406 }
7407
7408 /**
7409 * A concrete implementation of a [PropertyAccessorElement].
7410 */
7411 class PropertyAccessorElementImpl extends ExecutableElementImpl
7412 implements PropertyAccessorElement {
7413 /**
7414 * The variable associated with this accessor.
7415 */
7416 PropertyInducingElement variable;
7417
7418 /**
7419 * Initialize a newly created property accessor element to have the given
7420 * [name] and [offset].
7421 */
7422 PropertyAccessorElementImpl(String name, int offset) : super(name, offset);
7423
7424 /**
7425 * Initialize a newly created property accessor element to have the given
7426 * [name].
7427 */
7428 PropertyAccessorElementImpl.forNode(Identifier name) : super.forNode(name);
7429
7430 /**
7431 * Initialize using the given serialized information.
7432 */
7433 PropertyAccessorElementImpl.forSerialized(
7434 UnlinkedExecutable serializedExecutable, ElementImpl enclosingElement)
7435 : super.forSerialized(serializedExecutable, enclosingElement);
7436
7437 /**
7438 * Initialize a newly created synthetic property accessor element to be
7439 * associated with the given [variable].
7440 */
7441 PropertyAccessorElementImpl.forVariable(PropertyInducingElementImpl variable)
7442 : super(variable.name, variable.nameOffset) {
7443 this.variable = variable;
7444 static = variable.isStatic;
7445 synthetic = true;
7446 }
7447
7448 /**
7449 * Set whether this accessor is abstract.
7450 */
7451 void set abstract(bool isAbstract) {
7452 assert(serializedExecutable == null);
7453 setModifier(Modifier.ABSTRACT, isAbstract);
7454 }
7455
7456 @override
7457 List<TypeParameterType> get allEnclosingTypeParameterTypes {
7458 if (isStatic) {
7459 return const <TypeParameterType>[];
7460 }
7461 return super.allEnclosingTypeParameterTypes;
7462 }
7463
7464 @override
7465 PropertyAccessorElement get correspondingGetter {
7466 if (isGetter || variable == null) {
7467 return null;
7468 }
7469 return variable.getter;
7470 }
7471
7472 @override
7473 PropertyAccessorElement get correspondingSetter {
7474 if (isSetter || variable == null) {
7475 return null;
7476 }
7477 return variable.setter;
7478 }
7479
7480 @override
7481 String get displayName {
7482 if (serializedExecutable != null && isSetter) {
7483 String name = serializedExecutable.name;
7484 assert(name.endsWith('='));
7485 return name.substring(0, name.length - 1);
7486 }
7487 return super.displayName;
7488 }
7489
7490 @override
7491 TypeParameterizedElementMixin get enclosingTypeParameterContext {
7492 return (enclosingElement as ElementImpl).typeParameterContext;
7493 }
7494
7495 /**
7496 * Set whether this accessor is a getter.
7497 */
7498 void set getter(bool isGetter) {
7499 assert(serializedExecutable == null);
7500 setModifier(Modifier.GETTER, isGetter);
7501 }
7502
7503 @override
7504 String get identifier {
7505 String name = displayName;
7506 String suffix = isGetter ? "?" : "=";
7507 return "$name$suffix";
7508 }
7509
7510 @override
7511 bool get isGetter {
7512 if (serializedExecutable != null) {
7513 return serializedExecutable.kind == UnlinkedExecutableKind.getter;
7514 }
7515 return hasModifier(Modifier.GETTER);
7516 }
7517
7518 @override
7519 bool get isSetter {
7520 if (serializedExecutable != null) {
7521 return serializedExecutable.kind == UnlinkedExecutableKind.setter;
7522 }
7523 return hasModifier(Modifier.SETTER);
7524 }
7525
7526 @override
7527 bool get isStatic {
7528 if (serializedExecutable != null) {
7529 return serializedExecutable.isStatic ||
7530 variable is TopLevelVariableElement;
7531 }
7532 return hasModifier(Modifier.STATIC);
7533 }
7534
7535 @override
7536 ElementKind get kind {
7537 if (isGetter) {
7538 return ElementKind.GETTER;
7539 }
7540 return ElementKind.SETTER;
7541 }
7542
7543 @override
7544 String get name {
7545 if (serializedExecutable != null) {
7546 return serializedExecutable.name;
7547 }
7548 if (isSetter) {
7549 return "${super.name}=";
7550 }
7551 return super.name;
7552 }
7553
7554 /**
7555 * Set whether this accessor is a setter.
7556 */
7557 void set setter(bool isSetter) {
7558 assert(serializedExecutable == null);
7559 setModifier(Modifier.SETTER, isSetter);
7560 }
7561
7562 /**
7563 * Set whether this accessor is static.
7564 */
7565 void set static(bool isStatic) {
7566 assert(serializedExecutable == null);
7567 setModifier(Modifier.STATIC, isStatic);
7568 }
7569
7570 @override
7571 accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
7572
7573 @override
7574 void appendTo(StringBuffer buffer) {
7575 buffer.write(isGetter ? "get " : "set ");
7576 buffer.write(variable.displayName);
7577 super.appendTo(buffer);
7578 }
7579
7580 @override
7581 AstNode computeNode() {
7582 if (isSynthetic) {
7583 return null;
7584 }
7585 if (enclosingElement is ClassElement) {
7586 return getNodeMatching((node) => node is MethodDeclaration);
7587 } else if (enclosingElement is CompilationUnitElement) {
7588 return getNodeMatching((node) => node is FunctionDeclaration);
7589 }
7590 return null;
7591 }
7592 }
7593
7594 /**
7595 * Implicit getter for a [PropertyInducingElementImpl].
7596 */
7597 class PropertyAccessorElementImpl_ImplicitGetter
7598 extends PropertyAccessorElementImpl {
7599 /**
7600 * Create the implicit getter and bind it to the [property].
7601 */
7602 PropertyAccessorElementImpl_ImplicitGetter(
7603 PropertyInducingElementImpl property)
7604 : super.forVariable(property) {
7605 property.getter = this;
7606 enclosingElement = property.enclosingElement;
7607 }
7608
7609 @override
7610 bool get hasImplicitReturnType => variable.hasImplicitType;
7611
7612 @override
7613 bool get isGetter => true;
7614
7615 @override
7616 DartType get returnType => variable.type;
7617
7618 @override
7619 void set returnType(DartType returnType) {
7620 assert(false); // Should never be called.
7621 }
7622
7623 @override
7624 FunctionType get type {
7625 return _type ??= new FunctionTypeImpl(this);
7626 }
7627
7628 @override
7629 void set type(FunctionType type) {
7630 assert(false); // Should never be called.
7631 }
7632 }
7633
7634 /**
7635 * Implicit setter for a [PropertyInducingElementImpl].
7636 */
7637 class PropertyAccessorElementImpl_ImplicitSetter
7638 extends PropertyAccessorElementImpl {
7639 /**
7640 * Create the implicit setter and bind it to the [property].
7641 */
7642 PropertyAccessorElementImpl_ImplicitSetter(
7643 PropertyInducingElementImpl property)
7644 : super.forVariable(property) {
7645 property.setter = this;
7646 }
7647
7648 @override
7649 bool get isSetter => true;
7650
7651 @override
7652 List<ParameterElement> get parameters {
7653 return _parameters ??= <ParameterElement>[
7654 new ParameterElementImpl_ofImplicitSetter(this)
7655 ];
7656 }
7657
7658 @override
7659 DartType get returnType => VoidTypeImpl.instance;
7660
7661 @override
7662 void set returnType(DartType returnType) {
7663 assert(false); // Should never be called.
7664 }
7665
7666 @override
7667 FunctionType get type {
7668 return _type ??= new FunctionTypeImpl(this);
7669 }
7670
7671 @override
7672 void set type(FunctionType type) {
7673 assert(false); // Should never be called.
7674 }
7675 }
7676
7677 /**
7678 * A concrete implementation of a [PropertyInducingElement].
7679 */
7680 abstract class PropertyInducingElementImpl
7681 extends NonParameterVariableElementImpl implements PropertyInducingElement {
7682 /**
7683 * The getter associated with this element.
7684 */
7685 PropertyAccessorElement getter;
7686
7687 /**
7688 * The setter associated with this element, or `null` if the element is
7689 * effectively `final` and therefore does not have a setter associated with
7690 * it.
7691 */
7692 PropertyAccessorElement setter;
7693
7694 /**
7695 * The propagated type of this variable, or `null` if type propagation has not
7696 * been performed.
7697 */
7698 DartType _propagatedType;
7699
7700 /**
7701 * Initialize a newly created synthetic element to have the given [name] and
7702 * [offset].
7703 */
7704 PropertyInducingElementImpl(String name, int offset) : super(name, offset);
7705
7706 /**
7707 * Initialize a newly created element to have the given [name].
7708 */
7709 PropertyInducingElementImpl.forNode(Identifier name) : super.forNode(name);
7710
7711 /**
7712 * Initialize using the given serialized information.
7713 */
7714 PropertyInducingElementImpl.forSerialized(
7715 UnlinkedVariable unlinkedVariable, ElementImpl enclosingElement)
7716 : super.forSerialized(unlinkedVariable, enclosingElement);
7717
7718 @override
7719 DartType get propagatedType {
7720 if (_unlinkedVariable != null && _propagatedType == null) {
7721 _propagatedType = enclosingUnit.resynthesizerContext.resolveLinkedType(
7722 _unlinkedVariable.propagatedTypeSlot, typeParameterContext);
7723 }
7724 return _propagatedType;
7725 }
7726
7727 void set propagatedType(DartType propagatedType) {
7728 assert(_unlinkedVariable == null);
7729 _propagatedType = propagatedType;
7730 }
7731 }
7732
7733 /**
7734 * The context in which elements are resynthesized.
7735 */
7736 abstract class ResynthesizerContext {
7737 /**
7738 * Build [ElementAnnotationImpl] for the given [UnlinkedConst].
7739 */
7740 ElementAnnotationImpl buildAnnotation(ElementImpl context, UnlinkedConst uc);
7741
7742 /**
7743 * Build [Expression] for the given [UnlinkedConst].
7744 */
7745 Expression buildExpression(ElementImpl context, UnlinkedConst uc);
7746
7747 /**
7748 * Build explicit top-level property accessors.
7749 */
7750 UnitExplicitTopLevelAccessors buildTopLevelAccessors();
7751
7752 /**
7753 * Build explicit top-level variables.
7754 */
7755 UnitExplicitTopLevelVariables buildTopLevelVariables();
7756
7757 /**
7758 * Return `true` if the given parameter [slot] inherits `@covariant` behavior.
7759 */
7760 bool inheritsCovariant(int slot);
7761
7762 /**
7763 * Return `true` if the given const constructor [slot] is a part of a cycle.
7764 */
7765 bool isInConstCycle(int slot);
7766
7767 /**
7768 * Resolve an [EntityRef] into a constructor. If the reference is
7769 * unresolved, return `null`.
7770 */
7771 ConstructorElement resolveConstructorRef(
7772 TypeParameterizedElementMixin typeParameterContext, EntityRef entry);
7773
7774 /**
7775 * Build the appropriate [DartType] object corresponding to a slot id in the
7776 * [LinkedUnit.types] table.
7777 */
7778 DartType resolveLinkedType(
7779 int slot, TypeParameterizedElementMixin typeParameterContext);
7780
7781 /**
7782 * Resolve an [EntityRef] into a type. If the reference is
7783 * unresolved, return [DynamicTypeImpl.instance].
7784 *
7785 * TODO(paulberry): or should we have a class representing an
7786 * unresolved type, for consistency with the full element model?
7787 */
7788 DartType resolveTypeRef(
7789 EntityRef type, TypeParameterizedElementMixin typeParameterContext,
7790 {bool defaultVoid: false, bool instantiateToBoundsAllowed: true});
7791 }
7792
7793 /**
7794 * A concrete implementation of a [ShowElementCombinator].
7795 */
7796 class ShowElementCombinatorImpl implements ShowElementCombinator {
7797 /**
7798 * The unlinked representation of the combinator in the summary.
7799 */
7800 final UnlinkedCombinator _unlinkedCombinator;
7801
7802 /**
7803 * The names that are to be made visible in the importing library if they are
7804 * defined in the imported library.
7805 */
7806 List<String> _shownNames;
7807
7808 /**
7809 * The offset of the character immediately following the last character of
7810 * this node.
7811 */
7812 int _end = -1;
7813
7814 /**
7815 * The offset of the 'show' keyword of this element.
7816 */
7817 int _offset = 0;
7818
7819 ShowElementCombinatorImpl() : _unlinkedCombinator = null;
7820
7821 /**
7822 * Initialize using the given serialized information.
7823 */
7824 ShowElementCombinatorImpl.forSerialized(this._unlinkedCombinator);
7825
7826 @override
7827 int get end {
7828 if (_unlinkedCombinator != null) {
7829 return _unlinkedCombinator.end;
7830 }
7831 return _end;
7832 }
7833
7834 void set end(int end) {
7835 assert(_unlinkedCombinator == null);
7836 _end = end;
7837 }
7838
7839 @override
7840 int get offset {
7841 if (_unlinkedCombinator != null) {
7842 return _unlinkedCombinator.offset;
7843 }
7844 return _offset;
7845 }
7846
7847 void set offset(int offset) {
7848 assert(_unlinkedCombinator == null);
7849 _offset = offset;
7850 }
7851
7852 @override
7853 List<String> get shownNames {
7854 if (_unlinkedCombinator != null) {
7855 _shownNames ??= _unlinkedCombinator.shows.toList(growable: false);
7856 }
7857 return _shownNames ?? const <String>[];
7858 }
7859
7860 void set shownNames(List<String> shownNames) {
7861 assert(_unlinkedCombinator == null);
7862 _shownNames = shownNames;
7863 }
7864
7865 @override
7866 String toString() {
7867 StringBuffer buffer = new StringBuffer();
7868 buffer.write("show ");
7869 int count = shownNames.length;
7870 for (int i = 0; i < count; i++) {
7871 if (i > 0) {
7872 buffer.write(", ");
7873 }
7874 buffer.write(shownNames[i]);
7875 }
7876 return buffer.toString();
7877 }
7878 }
7879
7880 /**
7881 * A concrete implementation of a [TopLevelVariableElement].
7882 */
7883 class TopLevelVariableElementImpl extends PropertyInducingElementImpl
7884 implements TopLevelVariableElement {
7885 /**
7886 * Initialize a newly created synthetic top-level variable element to have the
7887 * given [name] and [offset].
7888 */
7889 TopLevelVariableElementImpl(String name, int offset) : super(name, offset);
7890
7891 /**
7892 * Initialize a newly created top-level variable element to have the given
7893 * [name].
7894 */
7895 TopLevelVariableElementImpl.forNode(Identifier name) : super.forNode(name);
7896
7897 /**
7898 * Initialize using the given serialized information.
7899 */
7900 TopLevelVariableElementImpl.forSerialized(
7901 UnlinkedVariable unlinkedVariable, ElementImpl enclosingElement)
7902 : super.forSerialized(unlinkedVariable, enclosingElement);
7903
7904 @override
7905 bool get isStatic => true;
7906
7907 @override
7908 ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
7909
7910 @override
7911 accept(ElementVisitor visitor) => visitor.visitTopLevelVariableElement(this);
7912
7913 @override
7914 VariableDeclaration computeNode() =>
7915 getNodeMatching((node) => node is VariableDeclaration);
7916 }
7917
7918 /**
7919 * A concrete implementation of a [TypeParameterElement].
7920 */
7921 class TypeParameterElementImpl extends ElementImpl
7922 implements TypeParameterElement {
7923 /**
7924 * The unlinked representation of the type parameter in the summary.
7925 */
7926 final UnlinkedTypeParam _unlinkedTypeParam;
7927
7928 /**
7929 * The number of type parameters whose scope overlaps this one, and which are
7930 * declared earlier in the file.
7931 *
7932 * TODO(scheglov) make private?
7933 */
7934 final int nestingLevel;
7935
7936 /**
7937 * The type defined by this type parameter.
7938 */
7939 TypeParameterType _type;
7940
7941 /**
7942 * The type representing the bound associated with this parameter, or `null`
7943 * if this parameter does not have an explicit bound.
7944 */
7945 DartType _bound;
7946
7947 /**
7948 * Initialize a newly created method element to have the given [name] and
7949 * [offset].
7950 */
7951 TypeParameterElementImpl(String name, int offset)
7952 : _unlinkedTypeParam = null,
7953 nestingLevel = null,
7954 super(name, offset);
7955
7956 /**
7957 * Initialize a newly created type parameter element to have the given [name].
7958 */
7959 TypeParameterElementImpl.forNode(Identifier name)
7960 : _unlinkedTypeParam = null,
7961 nestingLevel = null,
7962 super.forNode(name);
7963
7964 /**
7965 * Initialize using the given serialized information.
7966 */
7967 TypeParameterElementImpl.forSerialized(this._unlinkedTypeParam,
7968 TypeParameterizedElementMixin enclosingElement, this.nestingLevel)
7969 : super.forSerialized(enclosingElement);
7970
7971 /**
7972 * Initialize a newly created synthetic type parameter element to have the
7973 * given [name], and with [synthetic] set to true.
7974 */
7975 TypeParameterElementImpl.synthetic(String name)
7976 : _unlinkedTypeParam = null,
7977 nestingLevel = null,
7978 super(name, -1) {
7979 synthetic = true;
7980 }
7981
7982 DartType get bound {
7983 if (_unlinkedTypeParam != null) {
7984 if (_unlinkedTypeParam.bound == null) {
7985 return null;
7986 }
7987 return _bound ??= enclosingUnit.resynthesizerContext.resolveTypeRef(
7988 _unlinkedTypeParam.bound, enclosingElement,
7989 instantiateToBoundsAllowed: false);
7990 }
7991 return _bound;
7992 }
7993
7994 void set bound(DartType bound) {
7995 assert(_unlinkedTypeParam == null);
7996 _bound = bound;
7997 }
7998
7999 @override
8000 int get codeLength {
8001 if (_unlinkedTypeParam != null) {
8002 return _unlinkedTypeParam.codeRange?.length;
8003 }
8004 return super.codeLength;
8005 }
8006
8007 @override
8008 int get codeOffset {
8009 if (_unlinkedTypeParam != null) {
8010 return _unlinkedTypeParam.codeRange?.offset;
8011 }
8012 return super.codeOffset;
8013 }
8014
8015 @override
8016 String get displayName => name;
8017
8018 @override
8019 ElementKind get kind => ElementKind.TYPE_PARAMETER;
8020
8021 @override
8022 List<ElementAnnotation> get metadata {
8023 if (_unlinkedTypeParam != null) {
8024 return _metadata ??=
8025 _buildAnnotations(enclosingUnit, _unlinkedTypeParam.annotations);
8026 }
8027 return super.metadata;
8028 }
8029
8030 @override
8031 String get name {
8032 if (_unlinkedTypeParam != null) {
8033 return _unlinkedTypeParam.name;
8034 }
8035 return super.name;
8036 }
8037
8038 @override
8039 int get nameOffset {
8040 if (_unlinkedTypeParam != null) {
8041 return _unlinkedTypeParam.nameOffset;
8042 }
8043 return super.nameOffset;
8044 }
8045
8046 TypeParameterType get type {
8047 if (_unlinkedTypeParam != null) {
8048 _type ??= new TypeParameterTypeImpl(this);
8049 }
8050 return _type;
8051 }
8052
8053 void set type(TypeParameterType type) {
8054 _type = type;
8055 }
8056
8057 @override
8058 accept(ElementVisitor visitor) => visitor.visitTypeParameterElement(this);
8059
8060 @override
8061 void appendTo(StringBuffer buffer) {
8062 buffer.write(displayName);
8063 if (bound != null) {
8064 buffer.write(" extends ");
8065 buffer.write(bound);
8066 }
8067 }
8068 }
8069
8070 /**
8071 * Mixin representing an element which can have type parameters.
8072 */
8073 abstract class TypeParameterizedElementMixin
8074 implements TypeParameterizedElement, ElementImpl {
8075 int _nestingLevel;
8076 List<TypeParameterElement> _typeParameterElements;
8077 List<TypeParameterType> _typeParameterTypes;
8078 List<TypeParameterType> _allTypeParameterTypes;
8079
8080 /**
8081 * Return all type parameter types of the element that encloses element.
8082 * Not `null`, but might be empty for top-level and static class members.
8083 */
8084 List<TypeParameterType> get allEnclosingTypeParameterTypes {
8085 return enclosingTypeParameterContext?.allTypeParameterTypes ??
8086 const <TypeParameterType>[];
8087 }
8088
8089 /**
8090 * Return all type parameter types of this element.
8091 */
8092 List<TypeParameterType> get allTypeParameterTypes {
8093 if (_allTypeParameterTypes == null) {
8094 _allTypeParameterTypes = <TypeParameterType>[];
8095 // The most logical order would be (enclosing, this).
8096 // But we have to have it like this to be consistent with (inconsistent
8097 // by itself) element builder for generic functions.
8098 _allTypeParameterTypes.addAll(typeParameterTypes);
8099 _allTypeParameterTypes.addAll(allEnclosingTypeParameterTypes);
8100 }
8101 return _allTypeParameterTypes;
8102 }
8103
8104 /**
8105 * Get the type parameter context enclosing this one, if any.
8106 */
8107 TypeParameterizedElementMixin get enclosingTypeParameterContext;
8108
8109 /**
8110 * The unit in which this element is resynthesized.
8111 */
8112 CompilationUnitElementImpl get enclosingUnit;
8113
8114 /**
8115 * Find out how many type parameters are in scope in this context.
8116 */
8117 int get typeParameterNestingLevel =>
8118 _nestingLevel ??= unlinkedTypeParams.length +
8119 (enclosingTypeParameterContext?.typeParameterNestingLevel ?? 0);
8120
8121 List<TypeParameterElement> get typeParameters {
8122 if (_typeParameterElements == null) {
8123 int enclosingNestingLevel =
8124 enclosingTypeParameterContext?.typeParameterNestingLevel ?? 0;
8125 int numTypeParameters = unlinkedTypeParams.length;
8126 _typeParameterElements =
8127 new List<TypeParameterElement>(numTypeParameters);
8128 for (int i = 0; i < numTypeParameters; i++) {
8129 _typeParameterElements[i] = new TypeParameterElementImpl.forSerialized(
8130 unlinkedTypeParams[i], this, enclosingNestingLevel + i);
8131 }
8132 }
8133 return _typeParameterElements;
8134 }
8135
8136 /**
8137 * Get a list of [TypeParameterType] objects corresponding to the
8138 * element's type parameters.
8139 */
8140 List<TypeParameterType> get typeParameterTypes {
8141 return _typeParameterTypes ??= typeParameters
8142 .map((TypeParameterElement e) => e.type)
8143 .toList(growable: false);
8144 }
8145
8146 /**
8147 * Get the [UnlinkedTypeParam]s representing the type parameters declared by
8148 * this element.
8149 *
8150 * TODO(scheglov) make private after switching linker to Impl
8151 */
8152 List<UnlinkedTypeParam> get unlinkedTypeParams;
8153
8154 /**
8155 * Convert the given [index] into a type parameter type.
8156 */
8157 TypeParameterType getTypeParameterType(int index) {
8158 List<TypeParameterType> types = typeParameterTypes;
8159 if (index <= types.length) {
8160 return types[types.length - index];
8161 } else if (enclosingTypeParameterContext != null) {
8162 return enclosingTypeParameterContext
8163 .getTypeParameterType(index - types.length);
8164 } else {
8165 // If we get here, it means that a summary contained a type parameter inde x
8166 // that was out of range.
8167 throw new RangeError('Invalid type parameter index');
8168 }
8169 }
8170
8171 /**
8172 * Find out if the given [typeParameter] is in scope in this context.
8173 */
8174 bool isTypeParameterInScope(TypeParameterElement typeParameter) {
8175 if (typeParameter.enclosingElement == this) {
8176 return true;
8177 } else if (enclosingTypeParameterContext != null) {
8178 return enclosingTypeParameterContext
8179 .isTypeParameterInScope(typeParameter);
8180 } else {
8181 return false;
8182 }
8183 }
8184 }
8185
8186 /**
8187 * Container with information about explicit top-level property accessors and
8188 * corresponding implicit top-level variables.
8189 */
8190 class UnitExplicitTopLevelAccessors {
8191 final List<PropertyAccessorElementImpl> accessors =
8192 <PropertyAccessorElementImpl>[];
8193 final List<TopLevelVariableElementImpl> implicitVariables =
8194 <TopLevelVariableElementImpl>[];
8195 }
8196
8197 /**
8198 * Container with information about explicit top-level variables and
8199 * corresponding implicit top-level property accessors.
8200 */
8201 class UnitExplicitTopLevelVariables {
8202 final List<TopLevelVariableElementImpl> variables;
8203 final List<PropertyAccessorElementImpl> implicitAccessors =
8204 <PropertyAccessorElementImpl>[];
8205
8206 UnitExplicitTopLevelVariables(int numberOfVariables)
8207 : variables = numberOfVariables != 0
8208 ? new List<TopLevelVariableElementImpl>(numberOfVariables)
8209 : const <TopLevelVariableElementImpl>[];
8210 }
8211
8212 /**
8213 * A concrete implementation of a [UriReferencedElement].
8214 */
8215 abstract class UriReferencedElementImpl extends ElementImpl
8216 implements UriReferencedElement {
8217 /**
8218 * The offset of the URI in the file, or `-1` if this node is synthetic.
8219 */
8220 int _uriOffset = -1;
8221
8222 /**
8223 * The offset of the character immediately following the last character of
8224 * this node's URI, or `-1` if this node is synthetic.
8225 */
8226 int _uriEnd = -1;
8227
8228 /**
8229 * The URI that is specified by this directive.
8230 */
8231 String _uri;
8232
8233 /**
8234 * Initialize a newly created import element to have the given [name] and
8235 * [offset]. The offset may be `-1` if the element is synthetic.
8236 */
8237 UriReferencedElementImpl(String name, int offset) : super(name, offset);
8238
8239 /**
8240 * Initialize using the given serialized information.
8241 */
8242 UriReferencedElementImpl.forSerialized(ElementImpl enclosingElement)
8243 : super.forSerialized(enclosingElement);
8244
8245 /**
8246 * Return the URI that is specified by this directive.
8247 */
8248 String get uri => _uri;
8249
8250 /**
8251 * Set the URI that is specified by this directive to be the given [uri].
8252 */
8253 void set uri(String uri) {
8254 _uri = uri;
8255 }
8256
8257 /**
8258 * Return the offset of the character immediately following the last character
8259 * of this node's URI, or `-1` if this node is synthetic.
8260 */
8261 int get uriEnd => _uriEnd;
8262
8263 /**
8264 * Set the offset of the character immediately following the last character of
8265 * this node's URI to the given [offset].
8266 */
8267 void set uriEnd(int offset) {
8268 _uriEnd = offset;
8269 }
8270
8271 /**
8272 * Return the offset of the URI in the file, or `-1` if this node is synthetic .
8273 */
8274 int get uriOffset => _uriOffset;
8275
8276 /**
8277 * Set the offset of the URI in the file to the given [offset].
8278 */
8279 void set uriOffset(int offset) {
8280 _uriOffset = offset;
8281 }
8282
8283 String _selectUri(
8284 String defaultUri, List<UnlinkedConfiguration> configurations) {
8285 for (UnlinkedConfiguration configuration in configurations) {
8286 if (context.declaredVariables.get(configuration.name) ==
8287 configuration.value) {
8288 return configuration.uri;
8289 }
8290 }
8291 return defaultUri;
8292 }
8293 }
8294
8295 /**
8296 * A concrete implementation of a [VariableElement].
8297 */
8298 abstract class VariableElementImpl extends ElementImpl
8299 implements VariableElement {
8300 /**
8301 * The declared type of this variable.
8302 */
8303 DartType _type;
8304
8305 /**
8306 * A synthetic function representing this variable's initializer, or `null` if
8307 * this variable does not have an initializer.
8308 */
8309 FunctionElement _initializer;
8310
8311 /**
8312 * Initialize a newly created variable element to have the given [name] and
8313 * [offset].
8314 */
8315 VariableElementImpl(String name, int offset) : super(name, offset);
8316
8317 /**
8318 * Initialize a newly created variable element to have the given [name].
8319 */
8320 VariableElementImpl.forNode(Identifier name) : super.forNode(name);
8321
8322 /**
8323 * Initialize using the given serialized information.
8324 */
8325 VariableElementImpl.forSerialized(ElementImpl enclosingElement)
8326 : super.forSerialized(enclosingElement);
8327
8328 /**
8329 * Set whether this variable is const.
8330 */
8331 void set const3(bool isConst) {
8332 setModifier(Modifier.CONST, isConst);
8333 }
8334
8335 /**
8336 * If this element represents a constant variable, and it has an initializer,
8337 * a copy of the initializer for the constant. Otherwise `null`.
8338 *
8339 * Note that in correct Dart code, all constant variables must have
8340 * initializers. However, analyzer also needs to handle incorrect Dart code,
8341 * in which case there might be some constant variables that lack
8342 * initializers.
8343 */
8344 Expression get constantInitializer => null;
8345
8346 @override
8347 DartObject get constantValue => evaluationResult?.value;
8348
8349 @override
8350 String get displayName => name;
8351
8352 /**
8353 * Return the result of evaluating this variable's initializer as a
8354 * compile-time constant expression, or `null` if this variable is not a
8355 * 'const' variable, if it does not have an initializer, or if the compilation
8356 * unit containing the variable has not been resolved.
8357 */
8358 EvaluationResultImpl get evaluationResult => null;
8359
8360 /**
8361 * Set the result of evaluating this variable's initializer as a compile-time
8362 * constant expression to the given [result].
8363 */
8364 void set evaluationResult(EvaluationResultImpl result) {
8365 throw new StateError(
8366 "Invalid attempt to set a compile-time constant result");
8367 }
8368
8369 /**
8370 * Set whether this variable is final.
8371 */
8372 void set final2(bool isFinal) {
8373 setModifier(Modifier.FINAL, isFinal);
8374 }
8375
8376 @override
8377 bool get hasImplicitType {
8378 return hasModifier(Modifier.IMPLICIT_TYPE);
8379 }
8380
8381 /**
8382 * Set whether this variable element has an implicit type.
8383 */
8384 void set hasImplicitType(bool hasImplicitType) {
8385 setModifier(Modifier.IMPLICIT_TYPE, hasImplicitType);
8386 }
8387
8388 @override
8389 FunctionElement get initializer => _initializer;
8390
8391 /**
8392 * Set the function representing this variable's initializer to the given
8393 * [function].
8394 */
8395 void set initializer(FunctionElement function) {
8396 if (function != null) {
8397 (function as FunctionElementImpl).enclosingElement = this;
8398 }
8399 this._initializer = function;
8400 }
8401
8402 @override
8403 bool get isConst {
8404 return hasModifier(Modifier.CONST);
8405 }
8406
8407 @override
8408 bool get isFinal {
8409 return hasModifier(Modifier.FINAL);
8410 }
8411
8412 @override
8413 bool get isPotentiallyMutatedInClosure => false;
8414
8415 @override
8416 bool get isPotentiallyMutatedInScope => false;
8417
8418 @override
8419 bool get isStatic => hasModifier(Modifier.STATIC);
8420
8421 @override
8422 DartType get type => _type;
8423
8424 void set type(DartType type) {
8425 _type = type;
8426 }
8427
8428 @override
8429 void appendTo(StringBuffer buffer) {
8430 buffer.write(type);
8431 buffer.write(" ");
8432 buffer.write(displayName);
8433 }
8434
8435 @override
8436 DartObject computeConstantValue() => null;
8437
8438 @override
8439 void visitChildren(ElementVisitor visitor) {
8440 super.visitChildren(visitor);
8441 _initializer?.accept(visitor);
8442 }
8443 }
8444
8445 /**
8446 * A visitor that visit all the elements recursively and fill the given [map].
8447 */
8448 class _BuildOffsetToElementMap extends GeneralizingElementVisitor {
8449 final Map<int, Element> map;
8450
8451 _BuildOffsetToElementMap(this.map);
8452
8453 @override
8454 void visitElement(Element element) {
8455 int offset = element.nameOffset;
8456 if (offset != -1) {
8457 map[offset] = element;
8458 }
8459 super.visitElement(element);
8460 }
8461 }
OLDNEW
« no previous file with comments | « packages/analyzer/lib/src/dart/element/builder.dart ('k') | packages/analyzer/lib/src/dart/element/handle.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698