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

Side by Side Diff: dart/lib/compiler/implementation/elements/elements.dart

Issue 10855125: Ensure supertypes are loaded safely. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: More cleanup of ClassElement.cloneMembersTo Created 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #library('elements'); 5 #library('elements');
6 6
7 #import('../tree/tree.dart'); 7 #import('../tree/tree.dart');
8 #import('../scanner/scannerlib.dart'); 8 #import('../scanner/scannerlib.dart');
9 #import('../leg.dart'); // TODO(karlklose): we only need type. 9 #import('../leg.dart'); // TODO(karlklose): we only need type.
10 #import('../util/util.dart'); 10 #import('../util/util.dart');
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 476
477 class TypedefElement extends Element implements TypeDeclarationElement { 477 class TypedefElement extends Element implements TypeDeclarationElement {
478 Type cachedType; 478 Type cachedType;
479 Typedef cachedNode; 479 Typedef cachedNode;
480 480
481 TypedefElement(SourceString name, Element enclosing) 481 TypedefElement(SourceString name, Element enclosing)
482 : super(name, ElementKind.TYPEDEF, enclosing); 482 : super(name, ElementKind.TYPEDEF, enclosing);
483 483
484 Type computeType(Compiler compiler) { 484 Type computeType(Compiler compiler) {
485 if (cachedType !== null) return cachedType; 485 if (cachedType !== null) return cachedType;
486 cachedType = compiler.computeFunctionType( 486 cachedType = new FunctionType(null, null, this);
487 this, compiler.resolveTypedef(this)); 487 cachedType.initializeFrom(
488 compiler.computeFunctionType(this, compiler.resolveTypedef(this)));
488 return cachedType; 489 return cachedType;
489 } 490 }
490 491
491 Link<Type> get typeVariables() => const EmptyLink<Type>(); 492 Link<Type> get typeVariables() => const EmptyLink<Type>();
492 493
493 Scope buildScope() => 494 Scope buildScope() =>
494 new TypeDeclarationScope(enclosingElement.buildScope(), this); 495 new TypeDeclarationScope(enclosingElement.buildScope(), this);
495 496
496 TypedefElement cloneTo(Element enclosing, DiagnosticListener listener) { 497 TypedefElement cloneTo(Element enclosing, DiagnosticListener listener) {
497 TypedefElement result = new TypedefElement(name, enclosing); 498 TypedefElement result = new TypedefElement(name, enclosing);
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 TypeVariableType variableType = new TypeVariableType(variableElement); 973 TypeVariableType variableType = new TypeVariableType(variableElement);
973 variableElement.type = variableType; 974 variableElement.type = variableType;
974 arguments.addLast(variableType); 975 arguments.addLast(variableType);
975 } 976 }
976 return arguments.toLink(); 977 return arguments.toLink();
977 } 978 }
978 } 979 }
979 980
980 class ClassElement extends ContainerElement 981 class ClassElement extends ContainerElement
981 implements TypeDeclarationElement { 982 implements TypeDeclarationElement {
983 static final int STATE_NOT_STARTED = 0;
984 static final int STATE_STARTED = 1;
985 static final int STATE_DONE = 2;
986
982 final int id; 987 final int id;
983 InterfaceType type; 988 InterfaceType type;
984 Type supertype; 989 Type supertype;
985 Type defaultClass; 990 Type defaultClass;
986 Link<Element> members = const EmptyLink<Element>(); 991 Link<Element> members = const EmptyLink<Element>();
987 Map<SourceString, Element> localMembers; 992 Map<SourceString, Element> localMembers;
988 Map<SourceString, Element> constructors; 993 Map<SourceString, Element> constructors;
989 Link<Type> interfaces = const EmptyLink<Type>(); 994 Link<Type> interfaces;
990
991 LinkedHashMap<SourceString, TypeVariableElement> typeParameters;
992 SourceString nativeName; 995 SourceString nativeName;
993 996
994 bool isResolved = false; 997 int _supertypeLoadState = STATE_NOT_STARTED;
995 bool isBeingResolved = false; 998 int get supertypeLoadState() => _supertypeLoadState;
999 void set supertypeLoadState(int state) {
1000 assert(state == _supertypeLoadState + 1);
1001 assert(state <= STATE_DONE);
1002 _supertypeLoadState = state;
1003 }
Lasse Reichstein Nielsen 2012/08/14 08:40:36 I'd prefer putting getters/setters after the const
ahe 2012/08/14 11:10:42 Agreed. In addition, I don't like Dart's privacy.
1004
1005 int _resolutionState = STATE_NOT_STARTED;
1006 int get resolutionState() => _resolutionState;
1007 void set resolutionState(int state) {
1008 assert(state == _resolutionState + 1);
1009 assert(state <= STATE_DONE);
1010 _resolutionState = state;
1011 }
1012
996 // backendMembers are members that have been added by the backend to simplify 1013 // backendMembers are members that have been added by the backend to simplify
997 // compilation. They don't have any user-side counter-part. 1014 // compilation. They don't have any user-side counter-part.
998 Link<Element> backendMembers = const EmptyLink<Element>(); 1015 Link<Element> backendMembers = const EmptyLink<Element>();
999 1016
1000 Link<Type> allSupertypes; 1017 Link<Type> allSupertypes;
1001 1018
1002 ClassElement(SourceString name, Element enclosing, this.id) 1019 ClassElement(SourceString name, Element enclosing, this.id)
1003 : localMembers = new Map<SourceString, Element>(), 1020 : localMembers = new Map<SourceString, Element>(),
1004 constructors = new Map<SourceString, Element>(), 1021 constructors = new Map<SourceString, Element>(),
1005 super(name, ElementKind.CLASS, enclosing); 1022 super(name, ElementKind.CLASS, enclosing);
(...skipping 17 matching lines...) Expand all
1023 Link<Type> parameters = 1040 Link<Type> parameters =
1024 TypeDeclarationElement.createTypeVariables(this, node.typeParameters); 1041 TypeDeclarationElement.createTypeVariables(this, node.typeParameters);
1025 type = new InterfaceType(this, parameters); 1042 type = new InterfaceType(this, parameters);
1026 } 1043 }
1027 return type; 1044 return type;
1028 } 1045 }
1029 1046
1030 Link<Type> get typeVariables() => type.arguments; 1047 Link<Type> get typeVariables() => type.arguments;
1031 1048
1032 ClassElement ensureResolved(Compiler compiler) { 1049 ClassElement ensureResolved(Compiler compiler) {
1033 compiler.resolveClass(this); 1050 if (resolutionState == STATE_NOT_STARTED) {
1051 compiler.resolver.resolveClass(this);
1052 }
1034 return this; 1053 return this;
1035 } 1054 }
1036 1055
1037 Element lookupLocalMember(SourceString memberName) { 1056 Element lookupLocalMember(SourceString memberName) {
1038 return localMembers[memberName]; 1057 return localMembers[memberName];
1039 } 1058 }
1040 1059
1041 Element lookupSuperMember(SourceString memberName) { 1060 Element lookupSuperMember(SourceString memberName) {
1042 bool isPrivate = memberName.isPrivate(); 1061 bool isPrivate = memberName.isPrivate();
1043 for (ClassElement s = superclass; s != null; s = s.superclass) { 1062 for (ClassElement s = superclass; s != null; s = s.superclass) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1110 } 1129 }
1111 return result; 1130 return result;
1112 } 1131 }
1113 1132
1114 /** 1133 /**
1115 * Returns the super class, if any. 1134 * Returns the super class, if any.
1116 * 1135 *
1117 * The returned element may not be resolved yet. 1136 * The returned element may not be resolved yet.
1118 */ 1137 */
1119 ClassElement get superclass() { 1138 ClassElement get superclass() {
1120 assert(isResolved); 1139 assert(supertypeLoadState == STATE_DONE);
1121 return supertype === null ? null : supertype.element; 1140 return supertype === null ? null : supertype.element;
1122 } 1141 }
1123 1142
1124 /** 1143 /**
1125 * Runs through all members of this class. 1144 * Runs through all members of this class.
1126 * 1145 *
1127 * The enclosing class is passed to the callback. This is useful when 1146 * The enclosing class is passed to the callback. This is useful when
1128 * [includeSuperMembers] is [:true:]. 1147 * [includeSuperMembers] is [:true:].
1129 */ 1148 */
1130 void forEachMember([void f(ClassElement enclosingClass, Element member), 1149 void forEachMember([void f(ClassElement enclosingClass, Element member),
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 return false; 1213 return false;
1195 } 1214 }
1196 1215
1197 bool isInterface() => false; 1216 bool isInterface() => false;
1198 bool isNative() => nativeName != null; 1217 bool isNative() => nativeName != null;
1199 int hashCode() => id; 1218 int hashCode() => id;
1200 1219
1201 Scope buildScope() => 1220 Scope buildScope() =>
1202 new ClassScope(enclosingElement.buildScope(), this); 1221 new ClassScope(enclosingElement.buildScope(), this);
1203 1222
1204 void cloneMembersTo(Element target, DiagnosticListener listener) {
1205 target.type = type;
1206 target.supertype = supertype;
1207 target.defaultClass = defaultClass;
1208 target.interfaces = interfaces;
1209 if (typeParameters !== null) {
1210 target.typeParameters =
1211 new LinkedHashMap<SourceString, TypeVariableElement>();
1212 typeParameters.forEach((SourceString name, TypeVariableElement type) {
1213 target.typeParameters[name] = type.cloneTo(target, listener);
1214 });
1215 }
1216 target.nativeName = nativeName;
1217 target.isResolved = isResolved;
1218 target.isBeingResolved = isBeingResolved;
1219 target.allSupertypes = allSupertypes;
1220 if (!backendMembers.isEmpty()) {
1221 listener.cancel("Cloning backend-modified class.", element: this);
1222 }
1223
1224 Link<Element> elementList = this.members;
1225 while (!elementList.isEmpty()) {
1226 target.addMember(elementList.head.cloneTo(target, listener), listener);
1227 elementList = elementList.tail;
1228 }
1229 }
1230
1231 ClassElement cloneTo(Element enclosing, DiagnosticListener listener) { 1223 ClassElement cloneTo(Element enclosing, DiagnosticListener listener) {
1232 // TODO(lrn): Is copying id acceptable? 1224 listener.internalErrorOnElement(this, 'unsupported operation');
1233 ClassElement result = new ClassElement(name, enclosing, id);
1234 cloneMembersTo(result, listener);
1235 return result;
1236 } 1225 }
1237 } 1226 }
1238 1227
1239 class Elements { 1228 class Elements {
1240 static bool isLocal(Element element) { 1229 static bool isLocal(Element element) {
1241 return ((element !== null) 1230 return ((element !== null)
1242 && !element.isInstanceMember() 1231 && !element.isInstanceMember()
1243 && !isStaticOrTopLevelField(element) 1232 && !isStaticOrTopLevelField(element)
1244 && !isStaticOrTopLevelFunction(element) 1233 && !isStaticOrTopLevelFunction(element)
1245 && (element.kind === ElementKind.VARIABLE || 1234 && (element.kind === ElementKind.VARIABLE ||
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1423 Node parseNode(compiler) => cachedNode; 1412 Node parseNode(compiler) => cachedNode;
1424 1413
1425 String toString() => "${enclosingElement.toString()}.${name.slowToString()}"; 1414 String toString() => "${enclosingElement.toString()}.${name.slowToString()}";
1426 1415
1427 TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) { 1416 TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) {
1428 TypeVariableElement result = 1417 TypeVariableElement result =
1429 new TypeVariableElement(name, enclosing, node, type, bound); 1418 new TypeVariableElement(name, enclosing, node, type, bound);
1430 return result; 1419 return result;
1431 } 1420 }
1432 } 1421 }
OLDNEW
« no previous file with comments | « dart/lib/compiler/implementation/compiler.dart ('k') | dart/lib/compiler/implementation/enqueue.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698