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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/world.dart

Issue 12210142: Implement is-checks against type variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Remove some obsolete code. Created 7 years, 9 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 part of dart2js; 5 part of dart2js;
6 6
7 class World { 7 class World {
8 final Compiler compiler; 8 final Compiler compiler;
9 final Map<ClassElement, Set<ClassElement>> subtypes; 9 final Map<ClassElement, Set<ClassElement>> subtypes;
10 final Map<ClassElement, Set<MixinApplicationElement>> mixinUses; 10 final Map<ClassElement, Set<MixinApplicationElement>> mixinUses;
11 final Map<ClassElement, Set<ClassElement>> typesImplementedBySubclasses; 11 final Map<ClassElement, Set<ClassElement>> typesImplementedBySubclasses;
12 final Set<ClassElement> classesNeedingRti; 12 final Set<ClassElement> classesNeedingRti;
13 final Set<ClassElement> instantiatedAbstractClasses;
ngeoffray 2013/02/26 14:11:37 This name makes it think like it's an error. Maybe
karlklose 2013/02/27 10:12:58 Done.
13 final Map<ClassElement, Set<ClassElement>> rtiDependencies; 14 final Map<ClassElement, Set<ClassElement>> rtiDependencies;
14 final FullFunctionSet allFunctions; 15 final FullFunctionSet allFunctions;
15 16
16 World(Compiler compiler) 17 World(Compiler compiler)
17 : subtypes = new Map<ClassElement, Set<ClassElement>>(), 18 : subtypes = new Map<ClassElement, Set<ClassElement>>(),
18 mixinUses = new Map<ClassElement, Set<MixinApplicationElement>>(), 19 mixinUses = new Map<ClassElement, Set<MixinApplicationElement>>(),
19 typesImplementedBySubclasses = 20 typesImplementedBySubclasses =
20 new Map<ClassElement, Set<ClassElement>>(), 21 new Map<ClassElement, Set<ClassElement>>(),
21 classesNeedingRti = new Set<ClassElement>(), 22 classesNeedingRti = new Set<ClassElement>(),
23 instantiatedAbstractClasses = new Set<ClassElement>(),
22 rtiDependencies = new Map<ClassElement, Set<ClassElement>>(), 24 rtiDependencies = new Map<ClassElement, Set<ClassElement>>(),
23 allFunctions = new FullFunctionSet(compiler), 25 allFunctions = new FullFunctionSet(compiler),
24 this.compiler = compiler; 26 this.compiler = compiler;
25 27
26 void populate() { 28 void populate() {
27 void addSubtypes(ClassElement cls) { 29 void addSubtypes(ClassElement cls) {
28 if (cls.resolutionState != STATE_DONE) { 30 if (cls.resolutionState != STATE_DONE) {
29 compiler.internalErrorOnElement( 31 compiler.internalErrorOnElement(
30 cls, 'Class "${cls.name.slowToString()}" is not resolved.'); 32 cls, 'Class "${cls.name.slowToString()}" is not resolved.');
31 } 33 }
(...skipping 21 matching lines...) Expand all
53 55
54 compiler.resolverWorld.instantiatedClasses.forEach(addSubtypes); 56 compiler.resolverWorld.instantiatedClasses.forEach(addSubtypes);
55 57
56 // Find the classes that need runtime type information. Such 58 // Find the classes that need runtime type information. Such
57 // classes are: 59 // classes are:
58 // (1) used in a is check with type variables, 60 // (1) used in a is check with type variables,
59 // (2) dependencies of classes in (1), 61 // (2) dependencies of classes in (1),
60 // (3) subclasses of (2) and (3). 62 // (3) subclasses of (2) and (3).
61 63
62 void potentiallyAddForRti(ClassElement cls) { 64 void potentiallyAddForRti(ClassElement cls) {
63 if (cls.typeVariables.isEmpty) return;
ngeoffray 2013/02/26 14:11:37 Why are you removing this check?
karlklose 2013/02/27 10:12:58 That was an error. Restored.
64 if (classesNeedingRti.contains(cls)) return; 65 if (classesNeedingRti.contains(cls)) return;
65 classesNeedingRti.add(cls); 66 classesNeedingRti.add(cls);
66 67
67 Set<ClassElement> classes = subtypes[cls]; 68 Set<ClassElement> classes = subtypes[cls];
68 if (classes != null) { 69 if (classes != null) {
69 classes.forEach((ClassElement sub) { 70 classes.forEach((ClassElement sub) {
70 potentiallyAddForRti(sub); 71 potentiallyAddForRti(sub);
71 }); 72 });
72 } 73 }
73 74
74 Set<ClassElement> dependencies = rtiDependencies[cls]; 75 Set<ClassElement> dependencies = rtiDependencies[cls];
75 if (dependencies != null) { 76 if (dependencies != null) {
76 dependencies.forEach((ClassElement other) { 77 dependencies.forEach((ClassElement other) {
77 potentiallyAddForRti(other); 78 potentiallyAddForRti(other);
78 }); 79 });
79 } 80 }
80 } 81 }
81 82
83 Set<ClassElement> classesUsingTypeVariableTests = new Set<ClassElement>();
84 compiler.resolverWorld.isChecks.forEach((DartType type) {
85 if (type is TypeVariableType) {
ngeoffray 2013/02/26 14:11:37 Use the kind?
karlklose 2013/02/27 10:12:58 Done.
86 TypeVariableElement variable = type.element;
87 classesUsingTypeVariableTests.add(variable.enclosingElement);
88 }
89 });
90 compiler.resolverWorld.addImplicitChecks(classesUsingTypeVariableTests);
82 compiler.resolverWorld.isChecks.forEach((DartType type) { 91 compiler.resolverWorld.isChecks.forEach((DartType type) {
83 if (type is InterfaceType) { 92 if (type is InterfaceType) {
ngeoffray 2013/02/26 14:11:37 Use the kind?
karlklose 2013/02/27 10:12:58 Done.
84 InterfaceType itf = type; 93 InterfaceType itf = type;
85 if (!itf.isRaw) { 94 if (!itf.isRaw) {
86 potentiallyAddForRti(itf.element); 95 potentiallyAddForRti(itf.element);
87 } 96 }
97 } else if (type is TypeVariableType) {
ngeoffray 2013/02/26 14:11:37 USe the kind?
karlklose 2013/02/27 10:12:58 Done.
98 TypeVariableElement variable = type.element;
99 potentiallyAddForRti(variable.enclosingElement);
88 } 100 }
89 }); 101 });
102
103 // TODO(karlklose): if we know all targets of factories for the abstract
104 // class, we should check whether one of these targets needs runtime type
105 // information before adding the class.
ngeoffray 2013/02/26 14:11:37 Isn't that in the rtiDependencies map? Thinking ab
karlklose 2013/02/27 10:12:58 How do we know the instantiated class (in general)
106 instantiatedAbstractClasses.forEach((ClassElement cls) {
107 potentiallyAddForRti(cls);
108 });
90 } 109 }
91 110
92 void registerMixinUse(MixinApplicationElement mixinApplication, 111 void registerMixinUse(MixinApplicationElement mixinApplication,
93 ClassElement mixin) { 112 ClassElement mixin) {
94 Set<MixinApplicationElement> users = 113 Set<MixinApplicationElement> users =
95 mixinUses.putIfAbsent(mixin, () => 114 mixinUses.putIfAbsent(mixin, () =>
96 new Set<MixinApplicationElement>()); 115 new Set<MixinApplicationElement>());
97 users.add(mixinApplication); 116 users.add(mixinApplication);
98 } 117 }
99 118
100 bool isUsedAsMixin(ClassElement cls) { 119 bool isUsedAsMixin(ClassElement cls) {
101 Set<MixinApplicationElement> uses = mixinUses[cls]; 120 Set<MixinApplicationElement> uses = mixinUses[cls];
102 return uses != null && !uses.isEmpty; 121 return uses != null && !uses.isEmpty;
103 } 122 }
104 123
105 124
106 void registerRtiDependency(Element element, Element dependency) { 125 void registerRtiDependency(Element element, Element dependency) {
107 // We're not dealing with typedef for now. 126 // We're not dealing with typedef for now.
108 if (!element.isClass() || !dependency.isClass()) return; 127 if (!element.isClass() || !dependency.isClass()) return;
109 Set<ClassElement> classes = 128 Set<ClassElement> classes =
110 rtiDependencies.putIfAbsent(element, () => new Set<ClassElement>()); 129 rtiDependencies.putIfAbsent(element, () => new Set<ClassElement>());
111 classes.add(dependency); 130 classes.add(dependency);
112 } 131 }
113 132
114 bool needsRti(ClassElement cls) { 133 bool needsRti(ClassElement cls) {
115 return classesNeedingRti.contains(cls) || compiler.enabledRuntimeType; 134 return classesNeedingRti.contains(cls) ||
135 compiler.enabledRuntimeType;
ngeoffray 2013/02/26 14:11:37 Fits in one line.
karlklose 2013/02/27 10:12:58 Done.
116 } 136 }
117 137
118 bool hasAnyUserDefinedGetter(Selector selector) { 138 bool hasAnyUserDefinedGetter(Selector selector) {
119 return allFunctions.filter(selector).any((each) => each.isGetter()); 139 return allFunctions.filter(selector).any((each) => each.isGetter());
120 } 140 }
121 141
122 bool hasAnyUserDefinedSetter(Selector selector) { 142 bool hasAnyUserDefinedSetter(Selector selector) {
123 return allFunctions.filter(selector).any((each) => each.isSetter()); 143 return allFunctions.filter(selector).any((each) => each.isSetter());
124 } 144 }
125 145
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 if (receiverType != null) { 183 if (receiverType != null) {
164 noSuchMethodSelector = new TypedSelector( 184 noSuchMethodSelector = new TypedSelector(
165 receiverType, selector.typeKind, noSuchMethodSelector); 185 receiverType, selector.typeKind, noSuchMethodSelector);
166 } 186 }
167 ClassElement objectClass = compiler.objectClass; 187 ClassElement objectClass = compiler.objectClass;
168 return allFunctions 188 return allFunctions
169 .filter(noSuchMethodSelector) 189 .filter(noSuchMethodSelector)
170 .map((Element member) => member.getEnclosingClass()) 190 .map((Element member) => member.getEnclosingClass())
171 .where((ClassElement holder) => !identical(holder, objectClass)); 191 .where((ClassElement holder) => !identical(holder, objectClass));
172 } 192 }
193
194 void registerInstantiatedAbstractClass(ClassElement cls) {
195 instantiatedAbstractClasses.add(cls);
196 }
173 } 197 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698