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

Side by Side Diff: pkg/compiler/lib/src/universe/element_world_builder.dart

Issue 2829223003: Check equivalence of closed world based on kernel elements. (Closed)
Patch Set: Updated cf. comments. Created 3 years, 8 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) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 world_builder; 5 part of world_builder;
6 6
7 /// [ResolutionEnqueuerWorldBuilder] based on the [Element] model. 7 /// [ResolutionEnqueuerWorldBuilder] based on the [Element] model.
8 class ElementResolutionWorldBuilder extends ResolutionWorldBuilderBase { 8 class ElementResolutionWorldBuilder extends ResolutionWorldBuilderBase {
9 /// Used for testing the new more precise computation of instantiated types 9 /// Used for testing the new more precise computation of instantiated types
10 /// and classes. 10 /// and classes.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 _ClassUsage _createClassUsage(ClassElement cls) { 99 _ClassUsage _createClassUsage(ClassElement cls) {
100 cls.ensureResolved(_resolution); 100 cls.ensureResolved(_resolution);
101 _resolution.ensureClassMembers(cls); 101 _resolution.ensureClassMembers(cls);
102 return super._createClassUsage(cls); 102 return super._createClassUsage(cls);
103 } 103 }
104 104
105 /// Called to add [cls] to the set of known classes. 105 /// Called to add [cls] to the set of known classes.
106 /// 106 ///
107 /// This ensures that class hierarchy queries can be performed on [cls] and 107 /// This ensures that class hierarchy queries can be performed on [cls] and
108 /// classes that extend or implement it. 108 /// classes that extend or implement it.
109 void registerClass(ClassEntity cls) => _registerClass(cls); 109 void registerClass(ClassElement cls) => _registerClass(cls.declaration);
110 110
111 void _registerClass(ClassEntity cls, {bool isDirectlyInstantiated: false}) { 111 void _registerClass(ClassEntity cls, {bool isDirectlyInstantiated: false}) {
112 _ensureClassSet(cls); 112 _ensureClassSet(cls);
113 if (isDirectlyInstantiated) { 113 if (isDirectlyInstantiated) {
114 _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true); 114 _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true);
115 } 115 }
116 } 116 }
117 117
118 void _processInstantiatedClassMember( 118 void _processInstantiatedClassMember(
119 ClassEntity cls, MemberElement member, MemberUsedCallback memberUsed) { 119 ClassEntity cls, MemberElement member, MemberUsedCallback memberUsed) {
120 assert(invariant(member, member.isDeclaration)); 120 assert(invariant(member, member.isDeclaration));
121 member.computeType(_resolution); 121 member.computeType(_resolution);
122 super._processInstantiatedClassMember(cls, member, memberUsed); 122 super._processInstantiatedClassMember(cls, member, memberUsed);
123 } 123 }
124 124
125 ClassHierarchyNode _ensureClassHierarchyNode(ClassElement cls) { 125 @override
126 cls = cls.declaration; 126 ClassEntity getAppliedMixin(ClassElement cls) {
127 return _classHierarchyNodes.putIfAbsent(cls, () { 127 if (cls.isMixinApplication) {
128 ClassHierarchyNode parentNode; 128 MixinApplicationElement mixinApplication = cls;
129 if (cls.superclass != null) { 129 // Note: If [mixinApplication] is malformed [mixin] is `null`.
130 parentNode = _ensureClassHierarchyNode(cls.superclass); 130 return mixinApplication.mixin;
131 } 131 }
132 return new ClassHierarchyNode(parentNode, cls, cls.hierarchyDepth); 132 return null;
133 });
134 } 133 }
135 134
136 ClassSet _ensureClassSet(ClassElement cls) { 135 @override
137 cls = cls.declaration; 136 int getHierarchyDepth(ClassElement cls) => cls.hierarchyDepth;
138 return _classSets.putIfAbsent(cls, () {
139 ClassHierarchyNode node = _ensureClassHierarchyNode(cls);
140 ClassSet classSet = new ClassSet(node);
141 137
142 for (ResolutionInterfaceType type in cls.allSupertypes) { 138 @override
143 // TODO(johnniwinther): Optimization: Avoid adding [cls] to 139 bool checkClass(ClassElement cls) => cls.isDeclaration;
144 // superclasses.
145 ClassSet subtypeSet = _ensureClassSet(type.element);
146 subtypeSet.addSubtype(node);
147 }
148 if (cls.isMixinApplication) {
149 // TODO(johnniwinther): Store this in the [ClassSet].
150 MixinApplicationElement mixinApplication = cls;
151 if (mixinApplication.mixin != null) {
152 // If [mixinApplication] is malformed [mixin] is `null`.
153 registerMixinUse(mixinApplication, mixinApplication.mixin);
154 }
155 }
156 140
157 return classSet; 141 @override
158 }); 142 bool validateClass(ClassElement cls) => cls.isResolved;
159 }
160 143
161 void _updateSuperClassHierarchyNodeForClass(ClassHierarchyNode node) { 144 @override
162 // Ensure that classes implicitly implementing `Function` are in its 145 bool implementsFunction(ClassElement cls) =>
163 // subtype set. 146 cls.implementsFunction(_commonElements);
164 ClassElement cls = node.cls;
165 if (cls != _commonElements.functionClass &&
166 cls.implementsFunction(_commonElements)) {
167 ClassSet subtypeSet = _ensureClassSet(_commonElements.functionClass);
168 subtypeSet.addSubtype(node);
169 }
170 if (!node.isInstantiated && node.parentNode != null) {
171 _updateSuperClassHierarchyNodeForClass(node.parentNode);
172 }
173 }
174 147
175 void _updateClassHierarchyNodeForClass(ClassElement cls, 148 @override
176 {bool directlyInstantiated: false, bool abstractlyInstantiated: false}) { 149 ClassEntity getSuperClass(ClassElement cls) => cls.superclass;
177 ClassHierarchyNode node = _ensureClassHierarchyNode(cls); 150
178 _updateSuperClassHierarchyNodeForClass(node); 151 @override
179 if (directlyInstantiated) { 152 Iterable<InterfaceType> getSupertypes(ClassElement cls) => cls.allSupertypes;
180 node.isDirectlyInstantiated = true;
181 }
182 if (abstractlyInstantiated) {
183 node.isAbstractlyInstantiated = true;
184 }
185 }
186 153
187 ClosedWorld closeWorld() { 154 ClosedWorld closeWorld() {
188 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses = 155 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses =
189 new Map<ClassEntity, Set<ClassEntity>>(); 156 populateHierarchyNodes();
190
191 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated`
192 /// properties of the [ClassHierarchyNode] for [cls].
193
194 void addSubtypes(ClassElement cls, InstantiationInfo info) {
195 if (!info.hasInstantiation) {
196 return;
197 }
198 assert(cls.isDeclaration);
199 if (!cls.isResolved) {
200 throw new SpannableAssertionFailure(
201 cls, 'Class "${cls.name}" is not resolved.');
202 }
203
204 _updateClassHierarchyNodeForClass(cls,
205 directlyInstantiated: info.isDirectlyInstantiated,
206 abstractlyInstantiated: info.isAbstractlyInstantiated);
207
208 // Walk through the superclasses, and record the types
209 // implemented by that type on the superclasses.
210 ClassElement superclass = cls.superclass;
211 while (superclass != null) {
212 Set<ClassEntity> typesImplementedBySubclassesOfCls =
213 typesImplementedBySubclasses.putIfAbsent(
214 superclass, () => new Set<ClassEntity>());
215 for (ResolutionInterfaceType current in cls.allSupertypes) {
216 typesImplementedBySubclassesOfCls.add(current.element);
217 }
218 superclass = superclass.superclass;
219 }
220 }
221
222 // Use the [:seenClasses:] set to include non-instantiated
223 // classes: if the superclass of these classes require RTI, then
224 // they also need RTI, so that a constructor passes the type
225 // variables to the super constructor.
226 forEachInstantiatedClass(addSubtypes);
227
228 _closed = true; 157 _closed = true;
229 return _closedWorldCache = new ClosedWorldImpl( 158 return _closedWorldCache = new ClosedWorldImpl(
230 commonElements: _commonElements, 159 commonElements: _commonElements,
231 constantSystem: _backend.constantSystem, 160 constantSystem: _backend.constantSystem,
232 nativeData: _backend.nativeData, 161 nativeData: _backend.nativeData,
233 interceptorData: _backend.interceptorData, 162 interceptorData: _backend.interceptorData,
234 backendUsage: _backend.backendUsage, 163 backendUsage: _backend.backendUsage,
235 resolutionWorldBuilder: this, 164 resolutionWorldBuilder: this,
236 functionSetBuilder: _allFunctions, 165 functionSetBuilder: _allFunctions,
237 allTypedefs: _allTypedefs, 166 allTypedefs: _allTypedefs,
238 mixinUses: _mixinUses, 167 mixinUses: _mixinUses,
239 typesImplementedBySubclasses: typesImplementedBySubclasses, 168 typesImplementedBySubclasses: typesImplementedBySubclasses,
240 classHierarchyNodes: _classHierarchyNodes, 169 classHierarchyNodes: _classHierarchyNodes,
241 classSets: _classSets); 170 classSets: _classSets);
242 } 171 }
243 172
244 @override 173 @override
245 void registerMixinUse( 174 void registerMixinUse(
246 MixinApplicationElement mixinApplication, ClassElement mixin) { 175 MixinApplicationElement mixinApplication, ClassElement mixin) {
247 assert(mixin.isDeclaration); 176 assert(mixin.isDeclaration);
248 super.registerMixinUse(mixinApplication, mixin); 177 super.registerMixinUse(mixinApplication, mixin);
249 } 178 }
250 } 179 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/kernel/world_builder.dart ('k') | pkg/compiler/lib/src/universe/resolution_world_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698