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

Side by Side Diff: pkg/analyzer/lib/src/generated/element.dart

Issue 1215053003: Compute mixin application constructors in the ClassElement.constructors getter. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 5 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
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 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 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 // This code was auto-generated, is not intended to be edited, and is subject to 5 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information. 6 // significant change. Please see the README file for more information.
7 7
8 library engine.element; 8 library engine.element;
9 9
10 import 'dart:collection'; 10 import 'dart:collection';
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 @deprecated // Use ClassElement.EMPTY_LIST 494 @deprecated // Use ClassElement.EMPTY_LIST
495 static const List<ClassElement> EMPTY_ARRAY = const <ClassElement>[]; 495 static const List<ClassElement> EMPTY_ARRAY = const <ClassElement>[];
496 496
497 /** 497 /**
498 * A list containing all of the accessors (getters and setters) contained in 498 * A list containing all of the accessors (getters and setters) contained in
499 * this class. 499 * this class.
500 */ 500 */
501 List<PropertyAccessorElement> _accessors = PropertyAccessorElement.EMPTY_LIST; 501 List<PropertyAccessorElement> _accessors = PropertyAccessorElement.EMPTY_LIST;
502 502
503 /** 503 /**
504 * A list containing all of the constructors contained in this class. 504 * For classes which are not mixin applications, a list containing all of the
505 * constructors contained in this class, or `null` if the list of
506 * constructors has not yet been built.
507 *
508 * For classes which are mixin applications, the list of constructors is
509 * computed on the fly by the [constructors] getter, and this field is
510 * `null`.
505 */ 511 */
506 List<ConstructorElement> _constructors = ConstructorElement.EMPTY_LIST; 512 List<ConstructorElement> _constructors;
507 513
508 /** 514 /**
509 * A list containing all of the fields contained in this class. 515 * A list containing all of the fields contained in this class.
510 */ 516 */
511 List<FieldElement> _fields = FieldElement.EMPTY_LIST; 517 List<FieldElement> _fields = FieldElement.EMPTY_LIST;
512 518
513 /** 519 /**
514 * A list containing all of the mixins that are applied to the class being 520 * A list containing all of the mixins that are applied to the class being
515 * extended in order to derive the superclass of this class. 521 * extended in order to derive the superclass of this class.
516 */ 522 */
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 } 585 }
580 586
581 @override 587 @override
582 List<InterfaceType> get allSupertypes { 588 List<InterfaceType> get allSupertypes {
583 List<InterfaceType> list = new List<InterfaceType>(); 589 List<InterfaceType> list = new List<InterfaceType>();
584 _collectAllSupertypes(list); 590 _collectAllSupertypes(list);
585 return list; 591 return list;
586 } 592 }
587 593
588 @override 594 @override
589 List<ConstructorElement> get constructors => _constructors; 595 List<ConstructorElement> get constructors {
596 if (!isMixinApplication) {
597 assert(_constructors != null);
598 return _constructors == null
599 ? ConstructorElement.EMPTY_LIST
600 : _constructors;
601 }
602
603 return _computeMixinAppConstructors();
604 }
590 605
591 /** 606 /**
592 * Set the constructors contained in this class to the given [constructors]. 607 * Set the constructors contained in this class to the given [constructors].
608 *
609 * Should only be used for class elements that are not mixin applications.
593 */ 610 */
594 void set constructors(List<ConstructorElement> constructors) { 611 void set constructors(List<ConstructorElement> constructors) {
612 assert(!isMixinApplication);
595 for (ConstructorElement constructor in constructors) { 613 for (ConstructorElement constructor in constructors) {
596 (constructor as ConstructorElementImpl).enclosingElement = this; 614 (constructor as ConstructorElementImpl).enclosingElement = this;
597 } 615 }
598 this._constructors = constructors; 616 this._constructors = constructors;
599 } 617 }
600 618
601 /** 619 /**
620 * Return `true` if [CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS] should
621 * be reported for this class.
622 */
623 bool get doesMixinLackConstructors {
624 if (!isMixinApplication && mixins.isEmpty) {
625 // This class is not a mixin application and it doesn't have a "with"
626 // clause, so CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS is
627 // inapplicable.
628 return false;
629 }
630 if (supertype == null) {
631 // Should never happen, since Object is the only class that has no
632 // supertype, and it should have been caught by the test above.
633 assert(false);
634 return false;
635 }
636 // Find the nearest class in the supertype chain that is not a mixin
637 // application.
638 ClassElement nearestNonMixinClass = supertype.element;
639 if (nearestNonMixinClass.isMixinApplication) {
640 // Use a list to keep track of the classes we've seen, so that we won't
641 // go into an infinite loop in the event of a non-trivial loop in the
642 // class hierarchy.
643 List<ClassElementImpl> classesSeen = <ClassElementImpl>[this];
644 while (nearestNonMixinClass.isMixinApplication) {
645 if (classesSeen.contains(nearestNonMixinClass)) {
646 // Loop in the class hierarchy (which is reported elsewhere). Don't
647 // confuse the user with further errors.
648 return false;
649 }
650 classesSeen.add(nearestNonMixinClass);
651 if (nearestNonMixinClass.supertype == null) {
652 // Should never happen, since Object is the only class that has no
653 // supertype, and it is not a mixin application.
654 assert(false);
655 return false;
656 }
657 nearestNonMixinClass = nearestNonMixinClass.supertype.element;
658 }
659 }
660 return !nearestNonMixinClass.constructors.any(isSuperConstructorAccessible);
661 }
662
663 /**
602 * Set whether this class is defined by an enum declaration. 664 * Set whether this class is defined by an enum declaration.
603 */ 665 */
604 void set enum2(bool isEnum) { 666 void set enum2(bool isEnum) {
605 setModifier(Modifier.ENUM, isEnum); 667 setModifier(Modifier.ENUM, isEnum);
606 } 668 }
607 669
608 @override 670 @override
609 List<FieldElement> get fields => _fields; 671 List<FieldElement> get fields => _fields;
610 672
611 /** 673 /**
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 this._methods = methods; 787 this._methods = methods;
726 } 788 }
727 789
728 /** 790 /**
729 * Set whether this class is a mixin application. 791 * Set whether this class is a mixin application.
730 */ 792 */
731 void set mixinApplication(bool isMixinApplication) { 793 void set mixinApplication(bool isMixinApplication) {
732 setModifier(Modifier.MIXIN_APPLICATION, isMixinApplication); 794 setModifier(Modifier.MIXIN_APPLICATION, isMixinApplication);
733 } 795 }
734 796
735 bool get mixinErrorsReported => hasModifier(Modifier.MIXIN_ERRORS_REPORTED);
736
737 /**
738 * Set whether an error has reported explaining why this class is an
739 * invalid mixin application.
740 */
741 void set mixinErrorsReported(bool value) {
742 setModifier(Modifier.MIXIN_ERRORS_REPORTED, value);
743 }
744
745 @override 797 @override
746 List<TypeParameterElement> get typeParameters => _typeParameters; 798 List<TypeParameterElement> get typeParameters => _typeParameters;
747 799
748 /** 800 /**
749 * Set the type parameters defined for this class to the given 801 * Set the type parameters defined for this class to the given
750 * [typeParameters]. 802 * [typeParameters].
751 */ 803 */
752 void set typeParameters(List<TypeParameterElement> typeParameters) { 804 void set typeParameters(List<TypeParameterElement> typeParameters) {
753 for (TypeParameterElement typeParameter in typeParameters) { 805 for (TypeParameterElement typeParameter in typeParameters) {
754 (typeParameter as TypeParameterElementImpl).enclosingElement = this; 806 (typeParameter as TypeParameterElementImpl).enclosingElement = this;
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 for (InterfaceType type in currentElement.mixins) { 1041 for (InterfaceType type in currentElement.mixins) {
990 ClassElement element = type.element; 1042 ClassElement element = type.element;
991 if (!visitedClasses.contains(element)) { 1043 if (!visitedClasses.contains(element)) {
992 supertypes.add(type); 1044 supertypes.add(type);
993 } 1045 }
994 } 1046 }
995 } 1047 }
996 } 1048 }
997 } 1049 }
998 1050
1051 /**
1052 * Compute a list of constructors for this class, which is a mixin
1053 * application. If specified, [visitedClasses] is a list of the other mixin
1054 * application classes which have been visited on the way to reaching this
1055 * one (this is used to detect circularities).
1056 */
1057 List<ConstructorElement> _computeMixinAppConstructors(
1058 [List<ClassElementImpl> visitedClasses = null]) {
1059 // First get the list of constructors of the superclass which need to be
1060 // forwarded to this class.
1061 Iterable<ConstructorElement> constructorsToForward;
1062 if (supertype == null) {
1063 // Shouldn't ever happen, since the only class with no supertype is
1064 // Object, and it isn't a mixin application. But for safety's sake just
1065 // assume an empty list.
1066 assert(false);
1067 constructorsToForward = <ConstructorElement>[];
1068 } else if (!supertype.element.isMixinApplication) {
1069 List<ConstructorElement> superclassConstructors =
1070 supertype.element.constructors;
1071 // Filter out any constructors with optional parameters (see
1072 // dartbug.com/15101).
1073 constructorsToForward =
1074 superclassConstructors.where(isSuperConstructorAccessible);
1075 } else {
1076 if (visitedClasses == null) {
1077 visitedClasses = <ClassElementImpl>[this];
1078 } else {
1079 if (visitedClasses.contains(this)) {
1080 // Loop in the class hierarchy. Don't try to forward any
1081 // constructors.
1082 return <ConstructorElement>[];
1083 }
1084 visitedClasses.add(this);
1085 }
1086 try {
1087 ClassElementImpl superclass = supertype.element;
1088 constructorsToForward =
1089 superclass._computeMixinAppConstructors(visitedClasses);
1090 } finally {
1091 visitedClasses.removeLast();
1092 }
1093 }
1094
1095 // Figure out the type parameter substitution we need to perform in order
1096 // to produce constructors for this class. We want to be robust in the
1097 // face of errors, so drop any extra type arguments and fill in any missing
1098 // ones with `dynamic`.
1099 List<DartType> parameterTypes =
1100 TypeParameterTypeImpl.getTypes(supertype.typeParameters);
1101 List<DartType> argumentTypes = new List<DartType>.filled(
1102 parameterTypes.length, DynamicTypeImpl.instance);
1103 for (int i = 0; i < supertype.typeArguments.length; i++) {
1104 if (i >= argumentTypes.length) {
1105 break;
1106 }
1107 argumentTypes[i] = supertype.typeArguments[i];
1108 }
1109
1110 // Now create an implicit constructor for every constructor found above,
1111 // substituting type parameters as appropriate.
1112 return constructorsToForward
1113 .map((ConstructorElement superclassConstructor) {
1114 ConstructorElementImpl implicitConstructor =
1115 new ConstructorElementImpl(superclassConstructor.name, -1);
1116 implicitConstructor.synthetic = true;
1117 implicitConstructor.redirectedConstructor = superclassConstructor;
1118 implicitConstructor.const2 = superclassConstructor.isConst;
1119 implicitConstructor.returnType = type;
1120 List<ParameterElement> superParameters = superclassConstructor.parameters;
1121 int count = superParameters.length;
1122 if (count > 0) {
1123 List<ParameterElement> implicitParameters =
1124 new List<ParameterElement>(count);
1125 for (int i = 0; i < count; i++) {
1126 ParameterElement superParameter = superParameters[i];
1127 ParameterElementImpl implicitParameter =
1128 new ParameterElementImpl(superParameter.name, -1);
1129 implicitParameter.const3 = superParameter.isConst;
1130 implicitParameter.final2 = superParameter.isFinal;
1131 implicitParameter.parameterKind = superParameter.parameterKind;
1132 implicitParameter.synthetic = true;
1133 implicitParameter.type =
1134 superParameter.type.substitute2(argumentTypes, parameterTypes);
1135 implicitParameters[i] = implicitParameter;
1136 }
1137 implicitConstructor.parameters = implicitParameters;
1138 }
1139 FunctionTypeImpl constructorType =
1140 new FunctionTypeImpl(implicitConstructor);
1141 constructorType.typeArguments = type.typeArguments;
1142 implicitConstructor.type = constructorType;
1143 implicitConstructor.enclosingElement = this;
1144 return implicitConstructor;
1145 }).toList();
1146 }
1147
999 PropertyAccessorElement _internalLookUpConcreteGetter( 1148 PropertyAccessorElement _internalLookUpConcreteGetter(
1000 String getterName, LibraryElement library, bool includeThisClass) { 1149 String getterName, LibraryElement library, bool includeThisClass) {
1001 PropertyAccessorElement getter = 1150 PropertyAccessorElement getter =
1002 _internalLookUpGetter(getterName, library, includeThisClass); 1151 _internalLookUpGetter(getterName, library, includeThisClass);
1003 while (getter != null && getter.isAbstract) { 1152 while (getter != null && getter.isAbstract) {
1004 Element definingClass = getter.enclosingElement; 1153 Element definingClass = getter.enclosingElement;
1005 if (definingClass is! ClassElementImpl) { 1154 if (definingClass is! ClassElementImpl) {
1006 return null; 1155 return null;
1007 } 1156 }
1008 getter = (definingClass as ClassElementImpl)._internalLookUpGetter( 1157 getter = (definingClass as ClassElementImpl)._internalLookUpGetter(
(...skipping 7057 matching lines...) Expand 10 before | Expand all | Expand 10 after
8066 */ 8215 */
8067 static const Modifier MIXIN = const Modifier('MIXIN', 11); 8216 static const Modifier MIXIN = const Modifier('MIXIN', 11);
8068 8217
8069 /** 8218 /**
8070 * Indicates that a class is a mixin application. 8219 * Indicates that a class is a mixin application.
8071 */ 8220 */
8072 static const Modifier MIXIN_APPLICATION = 8221 static const Modifier MIXIN_APPLICATION =
8073 const Modifier('MIXIN_APPLICATION', 12); 8222 const Modifier('MIXIN_APPLICATION', 12);
8074 8223
8075 /** 8224 /**
8076 * Indicates that an error has reported explaining why this class is an
8077 * invalid mixin application.
8078 */
8079 static const Modifier MIXIN_ERRORS_REPORTED =
8080 const Modifier('MIXIN_ERRORS_REPORTED', 13);
8081
8082 /**
8083 * Indicates that the value of a parameter or local variable might be mutated 8225 * Indicates that the value of a parameter or local variable might be mutated
8084 * within the context. 8226 * within the context.
8085 */ 8227 */
8086 static const Modifier POTENTIALLY_MUTATED_IN_CONTEXT = 8228 static const Modifier POTENTIALLY_MUTATED_IN_CONTEXT =
8087 const Modifier('POTENTIALLY_MUTATED_IN_CONTEXT', 14); 8229 const Modifier('POTENTIALLY_MUTATED_IN_CONTEXT', 13);
8088 8230
8089 /** 8231 /**
8090 * Indicates that the value of a parameter or local variable might be mutated 8232 * Indicates that the value of a parameter or local variable might be mutated
8091 * within the scope. 8233 * within the scope.
8092 */ 8234 */
8093 static const Modifier POTENTIALLY_MUTATED_IN_SCOPE = 8235 static const Modifier POTENTIALLY_MUTATED_IN_SCOPE =
8094 const Modifier('POTENTIALLY_MUTATED_IN_SCOPE', 15); 8236 const Modifier('POTENTIALLY_MUTATED_IN_SCOPE', 14);
8095 8237
8096 /** 8238 /**
8097 * Indicates that a class contains an explicit reference to 'super'. 8239 * Indicates that a class contains an explicit reference to 'super'.
8098 */ 8240 */
8099 static const Modifier REFERENCES_SUPER = 8241 static const Modifier REFERENCES_SUPER =
8100 const Modifier('REFERENCES_SUPER', 16); 8242 const Modifier('REFERENCES_SUPER', 15);
8101 8243
8102 /** 8244 /**
8103 * Indicates that the pseudo-modifier 'set' was applied to the element. 8245 * Indicates that the pseudo-modifier 'set' was applied to the element.
8104 */ 8246 */
8105 static const Modifier SETTER = const Modifier('SETTER', 17); 8247 static const Modifier SETTER = const Modifier('SETTER', 16);
8106 8248
8107 /** 8249 /**
8108 * Indicates that the modifier 'static' was applied to the element. 8250 * Indicates that the modifier 'static' was applied to the element.
8109 */ 8251 */
8110 static const Modifier STATIC = const Modifier('STATIC', 18); 8252 static const Modifier STATIC = const Modifier('STATIC', 17);
8111 8253
8112 /** 8254 /**
8113 * Indicates that the element does not appear in the source code but was 8255 * Indicates that the element does not appear in the source code but was
8114 * implicitly created. For example, if a class does not define any 8256 * implicitly created. For example, if a class does not define any
8115 * constructors, an implicit zero-argument constructor will be created and it 8257 * constructors, an implicit zero-argument constructor will be created and it
8116 * will be marked as being synthetic. 8258 * will be marked as being synthetic.
8117 */ 8259 */
8118 static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 19); 8260 static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 18);
8119 8261
8120 static const List<Modifier> values = const [ 8262 static const List<Modifier> values = const [
8121 ABSTRACT, 8263 ABSTRACT,
8122 ASYNCHRONOUS, 8264 ASYNCHRONOUS,
8123 CONST, 8265 CONST,
8124 DEFERRED, 8266 DEFERRED,
8125 ENUM, 8267 ENUM,
8126 EXTERNAL, 8268 EXTERNAL,
8127 FACTORY, 8269 FACTORY,
8128 FINAL, 8270 FINAL,
8129 GENERATOR, 8271 GENERATOR,
8130 GETTER, 8272 GETTER,
8131 HAS_EXT_URI, 8273 HAS_EXT_URI,
8132 MIXIN, 8274 MIXIN,
8133 MIXIN_APPLICATION, 8275 MIXIN_APPLICATION,
8134 MIXIN_ERRORS_REPORTED,
8135 POTENTIALLY_MUTATED_IN_CONTEXT, 8276 POTENTIALLY_MUTATED_IN_CONTEXT,
8136 POTENTIALLY_MUTATED_IN_SCOPE, 8277 POTENTIALLY_MUTATED_IN_SCOPE,
8137 REFERENCES_SUPER, 8278 REFERENCES_SUPER,
8138 SETTER, 8279 SETTER,
8139 STATIC, 8280 STATIC,
8140 SYNTHETIC 8281 SYNTHETIC
8141 ]; 8282 ];
8142 8283
8143 const Modifier(String name, int ordinal) : super(name, ordinal); 8284 const Modifier(String name, int ordinal) : super(name, ordinal);
8144 } 8285 }
(...skipping 2352 matching lines...) Expand 10 before | Expand all | Expand 10 after
10497 10638
10498 @override 10639 @override
10499 void visitElement(Element element) { 10640 void visitElement(Element element) {
10500 int offset = element.nameOffset; 10641 int offset = element.nameOffset;
10501 if (offset != -1) { 10642 if (offset != -1) {
10502 map[offset] = element; 10643 map[offset] = element;
10503 } 10644 }
10504 super.visitElement(element); 10645 super.visitElement(element);
10505 } 10646 }
10506 } 10647 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/context/context.dart ('k') | pkg/analyzer/lib/src/generated/element_resolver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698