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

Side by Side Diff: packages/analyzer/lib/src/dart/element/member.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.member;
6
7 import 'package:analyzer/dart/ast/ast.dart';
8 import 'package:analyzer/dart/constant/value.dart';
9 import 'package:analyzer/dart/element/element.dart';
10 import 'package:analyzer/dart/element/type.dart';
11 import 'package:analyzer/src/dart/element/element.dart';
12 import 'package:analyzer/src/dart/element/type.dart';
13 import 'package:analyzer/src/generated/engine.dart'
14 show AnalysisContext, AnalysisEngine;
15 import 'package:analyzer/src/generated/java_engine.dart';
16 import 'package:analyzer/src/generated/source.dart';
17 import 'package:analyzer/src/generated/utilities_dart.dart';
18
19 /**
20 * A constructor element defined in a parameterized type where the values of the
21 * type parameters are known.
22 */
23 class ConstructorMember extends ExecutableMember implements ConstructorElement {
24 /**
25 * Initialize a newly created element to represent a constructor, based on the
26 * [baseElement], defined by the [definingType]. If [type] is passed, it
27 * represents the full type of the member, and will take precedence over
28 * the [definingType].
29 */
30 ConstructorMember(ConstructorElement baseElement, InterfaceType definingType,
31 [FunctionType type])
32 : super(baseElement, definingType, type);
33
34 @override
35 ConstructorElement get baseElement => super.baseElement as ConstructorElement;
36
37 @override
38 InterfaceType get definingType => super.definingType as InterfaceType;
39
40 @override
41 ClassElement get enclosingElement => baseElement.enclosingElement;
42
43 @override
44 bool get isConst => baseElement.isConst;
45
46 @override
47 bool get isDefaultConstructor => baseElement.isDefaultConstructor;
48
49 @override
50 bool get isFactory => baseElement.isFactory;
51
52 @override
53 int get nameEnd => baseElement.nameEnd;
54
55 @override
56 int get periodOffset => baseElement.periodOffset;
57
58 @override
59 ConstructorElement get redirectedConstructor =>
60 from(baseElement.redirectedConstructor, definingType);
61
62 @override
63 accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
64
65 @override
66 ConstructorDeclaration computeNode() => baseElement.computeNode();
67
68 @override
69 String toString() {
70 ConstructorElement baseElement = this.baseElement;
71 List<ParameterElement> parameters = this.parameters;
72 FunctionType type = this.type;
73 StringBuffer buffer = new StringBuffer();
74 buffer.write(baseElement.enclosingElement.displayName);
75 String name = displayName;
76 if (name != null && !name.isEmpty) {
77 buffer.write(".");
78 buffer.write(name);
79 }
80 buffer.write("(");
81 int parameterCount = parameters.length;
82 for (int i = 0; i < parameterCount; i++) {
83 if (i > 0) {
84 buffer.write(", ");
85 }
86 buffer.write(parameters[i]);
87 }
88 buffer.write(")");
89 if (type != null) {
90 buffer.write(ElementImpl.RIGHT_ARROW);
91 buffer.write(type.returnType);
92 }
93 return buffer.toString();
94 }
95
96 /**
97 * If the given [constructor]'s type is different when any type parameters
98 * from the defining type's declaration are replaced with the actual type
99 * arguments from the [definingType], create a constructor member representing
100 * the given constructor. Return the member that was created, or the original
101 * constructor if no member was created.
102 */
103 static ConstructorElement from(
104 ConstructorElement constructor, InterfaceType definingType) {
105 if (constructor == null || definingType.typeArguments.length == 0) {
106 return constructor;
107 }
108 FunctionType baseType = constructor.type;
109 if (baseType == null) {
110 // TODO(brianwilkerson) We need to understand when this can happen.
111 return constructor;
112 }
113 List<DartType> argumentTypes = definingType.typeArguments;
114 List<DartType> parameterTypes = definingType.element.type.typeArguments;
115 FunctionType substitutedType =
116 baseType.substitute2(argumentTypes, parameterTypes);
117 return new ConstructorMember(constructor, definingType, substitutedType);
118 }
119 }
120
121 /**
122 * An executable element defined in a parameterized type where the values of the
123 * type parameters are known.
124 */
125 abstract class ExecutableMember extends Member implements ExecutableElement {
126 FunctionType _type;
127
128 /**
129 * Initialize a newly created element to represent a callable element (like a
130 * method or function or property), based on the [baseElement], defined by the
131 * [definingType]. If [type] is passed, it represents the full type of the
132 * member, and will take precedence over the [definingType].
133 */
134 ExecutableMember(ExecutableElement baseElement, InterfaceType definingType,
135 [FunctionType type])
136 : _type = type,
137 super(baseElement, definingType);
138
139 @override
140 ExecutableElement get baseElement => super.baseElement as ExecutableElement;
141
142 @override
143 List<FunctionElement> get functions {
144 //
145 // Elements within this element should have type parameters substituted,
146 // just like this element.
147 //
148 throw new UnsupportedError('functions');
149 // return getBaseElement().getFunctions();
150 }
151
152 @override
153 bool get hasImplicitReturnType => baseElement.hasImplicitReturnType;
154
155 @override
156 bool get isAbstract => baseElement.isAbstract;
157
158 @override
159 bool get isAsynchronous => baseElement.isAsynchronous;
160
161 @override
162 bool get isExternal => baseElement.isExternal;
163
164 @override
165 bool get isGenerator => baseElement.isGenerator;
166
167 @override
168 bool get isOperator => baseElement.isOperator;
169
170 @override
171 bool get isStatic => baseElement.isStatic;
172
173 @override
174 bool get isSynchronous => baseElement.isSynchronous;
175
176 @override
177 List<LabelElement> get labels => baseElement.labels;
178
179 @override
180 List<LocalVariableElement> get localVariables {
181 //
182 // Elements within this element should have type parameters substituted,
183 // just like this element.
184 //
185 throw new UnsupportedError('localVariables');
186 // return getBaseElement().getLocalVariables();
187 }
188
189 @override
190 List<ParameterElement> get parameters => type.parameters;
191
192 @override
193 DartType get returnType => type.returnType;
194
195 @override
196 FunctionType get type {
197 return _type ??= baseElement.type.substitute2(definingType.typeArguments,
198 TypeParameterTypeImpl.getTypes(definingType.typeParameters));
199 }
200
201 @override
202 List<TypeParameterElement> get typeParameters => baseElement.typeParameters;
203
204 @override
205 void visitChildren(ElementVisitor visitor) {
206 // TODO(brianwilkerson) We need to finish implementing the accessors used
207 // below so that we can safely invoke them.
208 super.visitChildren(visitor);
209 safelyVisitChildren(baseElement.functions, visitor);
210 safelyVisitChildren(labels, visitor);
211 safelyVisitChildren(baseElement.localVariables, visitor);
212 safelyVisitChildren(parameters, visitor);
213 }
214 }
215
216 /**
217 * A parameter element defined in a parameterized type where the values of the
218 * type parameters are known.
219 */
220 class FieldFormalParameterMember extends ParameterMember
221 implements FieldFormalParameterElement {
222 /**
223 * Initialize a newly created element to represent a field formal parameter,
224 * based on the [baseElement], defined by the [definingType]. If [type]
225 * is passed it will be used as the substituted type for this member.
226 */
227 FieldFormalParameterMember(
228 FieldFormalParameterElement baseElement, ParameterizedType definingType,
229 [DartType type])
230 : super(baseElement, definingType, type);
231
232 @override
233 bool get isCovariant => baseElement.isCovariant;
234
235 @override
236 FieldElement get field {
237 FieldElement field = (baseElement as FieldFormalParameterElement).field;
238 if (field is FieldElement) {
239 return FieldMember.from(
240 field, substituteFor(field.enclosingElement.type));
241 }
242 return field;
243 }
244
245 @override
246 accept(ElementVisitor visitor) =>
247 visitor.visitFieldFormalParameterElement(this);
248 }
249
250 /**
251 * A field element defined in a parameterized type where the values of the type
252 * parameters are known.
253 */
254 class FieldMember extends VariableMember implements FieldElement {
255 /**
256 * Initialize a newly created element to represent a field, based on the
257 * [baseElement], defined by the [definingType].
258 */
259 FieldMember(FieldElement baseElement, InterfaceType definingType)
260 : super(baseElement, definingType);
261
262 @override
263 FieldElement get baseElement => super.baseElement as FieldElement;
264
265 @override
266 ClassElement get enclosingElement => baseElement.enclosingElement;
267
268 @override
269 PropertyAccessorElement get getter =>
270 PropertyAccessorMember.from(baseElement.getter, definingType);
271
272 @override
273 bool get isEnumConstant => baseElement.isEnumConstant;
274
275 @override
276 bool get isVirtual => baseElement.isVirtual;
277
278 @override
279 DartType get propagatedType => substituteFor(baseElement.propagatedType);
280
281 @override
282 PropertyAccessorElement get setter =>
283 PropertyAccessorMember.from(baseElement.setter, definingType);
284
285 @override
286 accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
287
288 @override
289 VariableDeclaration computeNode() => baseElement.computeNode();
290
291 @override
292 String toString() => '$type $displayName';
293
294 /**
295 * If the given [field]'s type is different when any type parameters from the
296 * defining type's declaration are replaced with the actual type arguments
297 * from the [definingType], create a field member representing the given
298 * field. Return the member that was created, or the base field if no member
299 * was created.
300 */
301 static FieldElement from(FieldElement field, ParameterizedType definingType) {
302 if (!_isChangedByTypeSubstitution(field, definingType)) {
303 return field;
304 }
305 // TODO(brianwilkerson) Consider caching the substituted type in the
306 // instance. It would use more memory but speed up some operations.
307 // We need to see how often the type is being re-computed.
308 return new FieldMember(field, definingType);
309 }
310
311 /**
312 * Determine whether the given [field]'s type is changed when type parameters
313 * from the [definingType]'s declaration are replaced with the actual type
314 * arguments from the defining type.
315 */
316 static bool _isChangedByTypeSubstitution(
317 FieldElement field, ParameterizedType definingType) {
318 List<DartType> argumentTypes = definingType.typeArguments;
319 if (field != null && argumentTypes.length != 0) {
320 DartType baseType = field.type;
321 List<DartType> parameterTypes =
322 TypeParameterTypeImpl.getTypes(definingType.typeParameters);
323 if (baseType != null) {
324 DartType substitutedType =
325 baseType.substitute2(argumentTypes, parameterTypes);
326 if (baseType != substitutedType) {
327 return true;
328 }
329 }
330 // If the field has a propagated type, then we need to check whether the
331 // propagated type needs substitution.
332 DartType basePropagatedType = field.propagatedType;
333 if (basePropagatedType != null) {
334 DartType substitutedPropagatedType =
335 basePropagatedType.substitute2(argumentTypes, parameterTypes);
336 if (basePropagatedType != substitutedPropagatedType) {
337 return true;
338 }
339 }
340 }
341 return false;
342 }
343 }
344
345 /**
346 * Deprecated: this type is no longer used. Use
347 * [MethodInvocation.staticInvokeType] to get the instantiated type of a generic
348 * method invocation.
349 *
350 * An element of a generic function, where the type parameters are known.
351 */
352 // TODO(jmesserly): the term "function member" is a bit weird, but it allows
353 // a certain consistency.
354 @deprecated
355 class FunctionMember extends ExecutableMember implements FunctionElement {
356 /**
357 * Initialize a newly created element to represent a function, based on the
358 * [baseElement], with the corresponding function [type].
359 */
360 @deprecated
361 FunctionMember(FunctionElement baseElement, [DartType type])
362 : super(baseElement, null, type);
363
364 @override
365 FunctionElement get baseElement => super.baseElement as FunctionElement;
366
367 @override
368 Element get enclosingElement => baseElement.enclosingElement;
369
370 @override
371 bool get isEntryPoint => baseElement.isEntryPoint;
372
373 @override
374 SourceRange get visibleRange => baseElement.visibleRange;
375
376 @override
377 accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
378
379 @override
380 FunctionDeclaration computeNode() => baseElement.computeNode();
381
382 @override
383 String toString() {
384 StringBuffer buffer = new StringBuffer();
385 buffer.write(baseElement.displayName);
386 (type as FunctionTypeImpl).appendTo(buffer);
387 return buffer.toString();
388 }
389
390 /**
391 * If the given [method]'s type is different when any type parameters from the
392 * defining type's declaration are replaced with the actual type arguments
393 * from the [definingType], create a method member representing the given
394 * method. Return the member that was created, or the base method if no member
395 * was created.
396 */
397 static MethodElement from(
398 MethodElement method, ParameterizedType definingType) {
399 if (method == null || definingType.typeArguments.length == 0) {
400 return method;
401 }
402 FunctionType baseType = method.type;
403 List<DartType> argumentTypes = definingType.typeArguments;
404 List<DartType> parameterTypes =
405 TypeParameterTypeImpl.getTypes(definingType.typeParameters);
406 FunctionType substitutedType =
407 baseType.substitute2(argumentTypes, parameterTypes);
408 return new MethodMember(method, definingType, substitutedType);
409 }
410 }
411
412 /**
413 * An element defined in a parameterized type where the values of the type
414 * parameters are known.
415 */
416 abstract class Member implements Element {
417 /**
418 * The element on which the parameterized element was created.
419 */
420 final Element _baseElement;
421
422 /**
423 * The type in which the element is defined.
424 */
425 final ParameterizedType _definingType;
426
427 /**
428 * Initialize a newly created element to represent a member, based on the
429 * [baseElement], defined by the [definingType].
430 */
431 Member(this._baseElement, this._definingType);
432
433 /**
434 * Return the element on which the parameterized element was created.
435 */
436 Element get baseElement => _baseElement;
437
438 @override
439 AnalysisContext get context => _baseElement.context;
440
441 /**
442 * Return the type in which the element is defined.
443 */
444 ParameterizedType get definingType => _definingType;
445
446 @override
447 String get displayName => _baseElement.displayName;
448
449 @override
450 String get documentationComment => _baseElement.documentationComment;
451
452 @override
453 int get id => _baseElement.id;
454
455 @override
456 bool get isDeprecated => _baseElement.isDeprecated;
457
458 @override
459 bool get isFactory => _baseElement.isFactory;
460
461 @override
462 bool get isJS => _baseElement.isJS;
463
464 @override
465 bool get isOverride => _baseElement.isOverride;
466
467 @override
468 bool get isPrivate => _baseElement.isPrivate;
469
470 @override
471 bool get isProtected => _baseElement.isProtected;
472
473 @override
474 bool get isPublic => _baseElement.isPublic;
475
476 @override
477 bool get isRequired => _baseElement.isRequired;
478
479 @override
480 bool get isSynthetic => _baseElement.isSynthetic;
481
482 @override
483 ElementKind get kind => _baseElement.kind;
484
485 @override
486 LibraryElement get library => _baseElement.library;
487
488 @override
489 Source get librarySource => _baseElement.librarySource;
490
491 @override
492 ElementLocation get location => _baseElement.location;
493
494 @override
495 List<ElementAnnotation> get metadata => _baseElement.metadata;
496
497 @override
498 String get name => _baseElement.name;
499
500 @override
501 int get nameLength => _baseElement.nameLength;
502
503 @override
504 int get nameOffset => _baseElement.nameOffset;
505
506 @override
507 Source get source => _baseElement.source;
508
509 @override
510 CompilationUnit get unit => _baseElement.unit;
511
512 @override
513 String computeDocumentationComment() => documentationComment;
514
515 @override
516 AstNode computeNode() => _baseElement.computeNode();
517
518 @override
519 Element/*=E*/ getAncestor/*<E extends Element >*/(
520 Predicate<Element> predicate) =>
521 baseElement.getAncestor(predicate);
522
523 @override
524 String getExtendedDisplayName(String shortName) =>
525 _baseElement.getExtendedDisplayName(shortName);
526
527 @override
528 bool isAccessibleIn(LibraryElement library) =>
529 _baseElement.isAccessibleIn(library);
530
531 /**
532 * If the given [child] is not `null`, use the given [visitor] to visit it.
533 */
534 @deprecated
535 void safelyVisitChild(Element child, ElementVisitor visitor) {
536 // TODO(brianwilkerson) Make this private
537 if (child != null) {
538 child.accept(visitor);
539 }
540 }
541
542 /**
543 * Use the given [visitor] to visit all of the [children].
544 */
545 void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
546 // TODO(brianwilkerson) Make this private
547 if (children != null) {
548 for (Element child in children) {
549 child.accept(visitor);
550 }
551 }
552 }
553
554 /**
555 * Return the type that results from replacing the type parameters in the
556 * given [type] with the type arguments associated with this member.
557 */
558 DartType substituteFor(DartType type) {
559 if (type == null) {
560 return null;
561 }
562 List<DartType> argumentTypes = _definingType.typeArguments;
563 List<DartType> parameterTypes =
564 TypeParameterTypeImpl.getTypes(_definingType.typeParameters);
565 return type.substitute2(argumentTypes, parameterTypes);
566 }
567
568 @override
569 void visitChildren(ElementVisitor visitor) {
570 // There are no children to visit
571 }
572 }
573
574 /**
575 * A method element defined in a parameterized type where the values of the type
576 * parameters are known.
577 */
578 class MethodMember extends ExecutableMember implements MethodElement {
579 /**
580 * Initialize a newly created element to represent a method, based on the
581 * [baseElement], defined by the [definingType]. If [type] is passed, it
582 * represents the full type of the member, and will take precedence over
583 * the [definingType].
584 */
585 MethodMember(MethodElement baseElement, InterfaceType definingType,
586 [DartType type])
587 : super(baseElement, definingType, type);
588
589 @override
590 MethodElement get baseElement => super.baseElement as MethodElement;
591
592 @override
593 ClassElement get enclosingElement => baseElement.enclosingElement;
594
595 @override
596 accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
597
598 @override
599 MethodDeclaration computeNode() => baseElement.computeNode();
600
601 @override
602 String toString() {
603 MethodElement baseElement = this.baseElement;
604 List<ParameterElement> parameters = this.parameters;
605 FunctionType type = this.type;
606 StringBuffer buffer = new StringBuffer();
607 buffer.write(baseElement.enclosingElement.displayName);
608 buffer.write(".");
609 buffer.write(baseElement.displayName);
610 buffer.write("(");
611 int parameterCount = parameters.length;
612 for (int i = 0; i < parameterCount; i++) {
613 if (i > 0) {
614 buffer.write(", ");
615 }
616 buffer.write(parameters[i]);
617 }
618 buffer.write(")");
619 if (type != null) {
620 buffer.write(ElementImpl.RIGHT_ARROW);
621 buffer.write(type.returnType);
622 }
623 return buffer.toString();
624 }
625
626 /**
627 * If the given [method]'s type is different when any type parameters from the
628 * defining type's declaration are replaced with the actual type arguments
629 * from the [definingType], create a method member representing the given
630 * method. Return the member that was created, or the base method if no member
631 * was created.
632 */
633 static MethodElement from(MethodElement method, InterfaceType definingType) {
634 if (method == null || definingType.typeArguments.length == 0) {
635 return method;
636 }
637 FunctionType baseType = method.type;
638 List<DartType> argumentTypes = definingType.typeArguments;
639 List<DartType> parameterTypes = definingType.element.type.typeArguments;
640 FunctionType substitutedType =
641 baseType.substitute2(argumentTypes, parameterTypes);
642 return new MethodMember(method, definingType, substitutedType);
643 }
644 }
645
646 /**
647 * A parameter element defined in a parameterized type where the values of the
648 * type parameters are known.
649 */
650 class ParameterMember extends VariableMember
651 with ParameterElementMixin
652 implements ParameterElement {
653 /**
654 * Initialize a newly created element to represent a parameter, based on the
655 * [baseElement], defined by the [definingType]. If [type] is passed it will
656 * represent the already substituted type.
657 */
658 ParameterMember(ParameterElement baseElement, ParameterizedType definingType,
659 [DartType type])
660 : super._(baseElement, definingType, type);
661
662 @override
663 ParameterElement get baseElement => super.baseElement as ParameterElement;
664
665 @override
666 String get defaultValueCode => baseElement.defaultValueCode;
667
668 @override
669 Element get enclosingElement => baseElement.enclosingElement;
670
671 @override
672 int get hashCode => baseElement.hashCode;
673
674 @override
675 bool get isCovariant => baseElement.isCovariant;
676
677 @override
678 bool get isInitializingFormal => baseElement.isInitializingFormal;
679
680 @override
681 ParameterKind get parameterKind => baseElement.parameterKind;
682
683 @override
684 List<ParameterElement> get parameters {
685 DartType type = this.type;
686 if (type is FunctionType) {
687 return type.parameters;
688 }
689 return ParameterElement.EMPTY_LIST;
690 }
691
692 @override
693 List<TypeParameterElement> get typeParameters => baseElement.typeParameters;
694
695 @override
696 SourceRange get visibleRange => baseElement.visibleRange;
697
698 @override
699 accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
700
701 @override
702 FormalParameter computeNode() => baseElement.computeNode();
703
704 @override
705 Element/*=E*/ getAncestor/*<E extends Element>*/(
706 Predicate<Element> predicate) {
707 Element element = baseElement.getAncestor(predicate);
708 ParameterizedType definingType = this.definingType;
709 if (definingType is InterfaceType) {
710 if (element is ConstructorElement) {
711 return ConstructorMember.from(element, definingType) as Element/*=E*/;
712 } else if (element is MethodElement) {
713 return MethodMember.from(element, definingType) as Element/*=E*/;
714 } else if (element is PropertyAccessorElement) {
715 return PropertyAccessorMember.from(element, definingType)
716 as Element/*=E*/;
717 }
718 }
719 return element as Element/*=E*/;
720 }
721
722 @override
723 String toString() {
724 ParameterElement baseElement = this.baseElement;
725 String left = "";
726 String right = "";
727 while (true) {
728 if (baseElement.parameterKind == ParameterKind.NAMED) {
729 left = "{";
730 right = "}";
731 } else if (baseElement.parameterKind == ParameterKind.POSITIONAL) {
732 left = "[";
733 right = "]";
734 } else if (baseElement.parameterKind == ParameterKind.REQUIRED) {}
735 break;
736 }
737 return '$left$type ${baseElement.displayName}$right';
738 }
739
740 @override
741 void visitChildren(ElementVisitor visitor) {
742 super.visitChildren(visitor);
743 safelyVisitChildren(parameters, visitor);
744 }
745 }
746
747 /**
748 * A property accessor element defined in a parameterized type where the values
749 * of the type parameters are known.
750 */
751 class PropertyAccessorMember extends ExecutableMember
752 implements PropertyAccessorElement {
753 /**
754 * Initialize a newly created element to represent a property, based on the
755 * [baseElement], defined by the [definingType].
756 */
757 PropertyAccessorMember(
758 PropertyAccessorElement baseElement, InterfaceType definingType)
759 : super(baseElement, definingType);
760
761 @override
762 PropertyAccessorElement get baseElement =>
763 super.baseElement as PropertyAccessorElement;
764
765 @override
766 PropertyAccessorElement get correspondingGetter =>
767 from(baseElement.correspondingGetter, definingType);
768
769 @override
770 PropertyAccessorElement get correspondingSetter =>
771 from(baseElement.correspondingSetter, definingType);
772
773 @override
774 InterfaceType get definingType => super.definingType as InterfaceType;
775
776 @override
777 Element get enclosingElement => baseElement.enclosingElement;
778
779 @override
780 bool get isGetter => baseElement.isGetter;
781
782 @override
783 bool get isSetter => baseElement.isSetter;
784
785 @override
786 PropertyInducingElement get variable {
787 PropertyInducingElement variable = baseElement.variable;
788 if (variable is FieldElement) {
789 return FieldMember.from(variable, definingType);
790 }
791 return variable;
792 }
793
794 @override
795 accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
796
797 @override
798 String toString() {
799 PropertyAccessorElement baseElement = this.baseElement;
800 List<ParameterElement> parameters = this.parameters;
801 FunctionType type = this.type;
802 StringBuffer builder = new StringBuffer();
803 if (isGetter) {
804 builder.write("get ");
805 } else {
806 builder.write("set ");
807 }
808 builder.write(baseElement.enclosingElement.displayName);
809 builder.write(".");
810 builder.write(baseElement.displayName);
811 builder.write("(");
812 int parameterCount = parameters.length;
813 for (int i = 0; i < parameterCount; i++) {
814 if (i > 0) {
815 builder.write(", ");
816 }
817 builder.write(parameters[i]);
818 }
819 builder.write(")");
820 if (type != null) {
821 builder.write(ElementImpl.RIGHT_ARROW);
822 builder.write(type.returnType);
823 }
824 return builder.toString();
825 }
826
827 /**
828 * If the given [accessor]'s type is different when any type parameters from
829 * the defining type's declaration are replaced with the actual type
830 * arguments from the [definingType], create an accessor member representing
831 * the given accessor. Return the member that was created, or the base
832 * accessor if no member was created.
833 */
834 static PropertyAccessorElement from(
835 PropertyAccessorElement accessor, InterfaceType definingType) {
836 if (!_isChangedByTypeSubstitution(accessor, definingType)) {
837 return accessor;
838 }
839 // TODO(brianwilkerson) Consider caching the substituted type in the
840 // instance. It would use more memory but speed up some operations.
841 // We need to see how often the type is being re-computed.
842 return new PropertyAccessorMember(accessor, definingType);
843 }
844
845 /**
846 * Determine whether the given property [accessor]'s type is changed when type
847 * parameters from the defining type's declaration are replaced with the
848 * actual type arguments from the [definingType].
849 */
850 static bool _isChangedByTypeSubstitution(
851 PropertyAccessorElement accessor, InterfaceType definingType) {
852 List<DartType> argumentTypes = definingType.typeArguments;
853 if (accessor != null && argumentTypes.length != 0) {
854 FunctionType baseType = accessor.type;
855 if (baseType == null) {
856 AnalysisEngine.instance.logger.logInformation(
857 'Type of $accessor is null in PropertyAccessorMember._isChangedByTyp eSubstitution');
858 return false;
859 }
860 List<DartType> parameterTypes = definingType.element.type.typeArguments;
861 FunctionType substitutedType =
862 baseType.substitute2(argumentTypes, parameterTypes);
863 if (baseType != substitutedType) {
864 return true;
865 }
866 // If this property accessor is based on a field, that field might have a
867 // propagated type. In which case we need to check whether the propagated
868 // type of the field needs substitution.
869 PropertyInducingElement field = accessor.variable;
870 if (!field.isSynthetic) {
871 DartType baseFieldType = field.propagatedType;
872 if (baseFieldType != null) {
873 DartType substitutedFieldType =
874 baseFieldType.substitute2(argumentTypes, parameterTypes);
875 if (baseFieldType != substitutedFieldType) {
876 return true;
877 }
878 }
879 }
880 }
881 return false;
882 }
883 }
884
885 /**
886 * A type parameter defined inside of another parameterized type, where the
887 * values of the enclosing type parameters are known.
888 *
889 * For example:
890 *
891 * class C<T> {
892 * S m<S extends T>(S s);
893 * }
894 *
895 * If we have `C<num>.m` and we ask for the type parameter "S", we should get
896 * `<S extends num>` instead of `<S extends T>`. This is how the parameter
897 * and return types work, see: [FunctionType.parameters],
898 * [FunctionType.returnType], and [ParameterMember].
899 */
900 class TypeParameterMember extends Member implements TypeParameterElement {
901 @override
902 final DartType bound;
903
904 DartType _type;
905
906 TypeParameterMember(
907 TypeParameterElement baseElement, DartType definingType, this.bound)
908 : super(baseElement, definingType) {
909 _type = new TypeParameterTypeImpl(this);
910 }
911
912 @override
913 TypeParameterElement get baseElement =>
914 super.baseElement as TypeParameterElement;
915
916 @override
917 Element get enclosingElement => baseElement.enclosingElement;
918
919 @override
920 int get hashCode => baseElement.hashCode;
921
922 @override
923 TypeParameterType get type => _type;
924
925 @override
926 bool operator ==(obj) =>
927 // TODO(jmesserly): this equality should consider the bound, see:
928 // https://github.com/dart-lang/sdk/issues/27210
929 obj is TypeParameterMember && obj.baseElement == baseElement;
930
931 @override
932 accept(ElementVisitor visitor) => visitor.visitTypeParameterElement(this);
933
934 /**
935 * If the given [parameter]'s type is different when any type parameters from
936 * the defining type's declaration are replaced with the actual type
937 * arguments from the [definingType], create a parameter member representing
938 * the given parameter. Return the member that was created, or the base
939 * parameter if no member was created.
940 */
941 static TypeParameterElement from(
942 TypeParameterElement parameter, ParameterizedType definingType) {
943 if (parameter?.bound == null || definingType.typeArguments.isEmpty) {
944 return parameter;
945 }
946
947 DartType bound = parameter.bound;
948 List<DartType> argumentTypes = definingType.typeArguments;
949 List<DartType> parameterTypes =
950 TypeParameterTypeImpl.getTypes(definingType.typeParameters);
951 DartType substitutedBound =
952 bound.substitute2(argumentTypes, parameterTypes);
953 return new TypeParameterMember(parameter, definingType, substitutedBound);
954 }
955 }
956
957 /**
958 * A variable element defined in a parameterized type where the values of the
959 * type parameters are known.
960 */
961 abstract class VariableMember extends Member implements VariableElement {
962 @override
963 final DartType type;
964
965 /**
966 * Initialize a newly created element to represent a variable, based on the
967 * [baseElement], defined by the [definingType].
968 */
969 VariableMember(VariableElement baseElement, ParameterizedType definingType,
970 [DartType type])
971 : type = type ??
972 baseElement.type.substitute2(definingType.typeArguments,
973 TypeParameterTypeImpl.getTypes(definingType.typeParameters)),
974 super(baseElement, definingType);
975
976 // TODO(jmesserly): this is temporary to allow the ParameterMember subclass.
977 // Apparently mixins don't work with optional params.
978 VariableMember._(VariableElement baseElement, ParameterizedType definingType,
979 DartType type)
980 : this(baseElement, definingType, type);
981
982 @override
983 VariableElement get baseElement => super.baseElement as VariableElement;
984
985 @override
986 DartObject get constantValue => baseElement.constantValue;
987
988 @override
989 bool get hasImplicitType => baseElement.hasImplicitType;
990
991 @override
992 FunctionElement get initializer {
993 //
994 // Elements within this element should have type parameters substituted,
995 // just like this element.
996 //
997 throw new UnsupportedError('initializer');
998 // return getBaseElement().getInitializer();
999 }
1000
1001 @override
1002 bool get isConst => baseElement.isConst;
1003
1004 @override
1005 bool get isFinal => baseElement.isFinal;
1006
1007 @override
1008 @deprecated
1009 bool get isPotentiallyMutatedInClosure =>
1010 baseElement.isPotentiallyMutatedInClosure;
1011
1012 @override
1013 @deprecated
1014 bool get isPotentiallyMutatedInScope =>
1015 baseElement.isPotentiallyMutatedInScope;
1016
1017 @override
1018 bool get isStatic => baseElement.isStatic;
1019
1020 @override
1021 DartObject computeConstantValue() => baseElement.computeConstantValue();
1022
1023 @override
1024 void visitChildren(ElementVisitor visitor) {
1025 // TODO(brianwilkerson) We need to finish implementing the accessors used
1026 // below so that we can safely invoke them.
1027 super.visitChildren(visitor);
1028 baseElement.initializer?.accept(visitor);
1029 }
1030 }
OLDNEW
« no previous file with comments | « packages/analyzer/lib/src/dart/element/handle.dart ('k') | packages/analyzer/lib/src/dart/element/type.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698