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

Side by Side Diff: pkg/compiler/lib/src/js_backend/enqueuer.dart

Issue 2587913004: Move class/member computation from CodegenEnqueuer to CodegenWorldBuilder. (Closed)
Patch Set: Updated cf. comments Created 4 years 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) 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 dart2js.js.enqueue; 5 library dart2js.js.enqueue;
6 6
7 import 'dart:collection' show Queue; 7 import 'dart:collection' show Queue;
8 8
9 import '../cache_strategy.dart' show CacheStrategy; 9 import '../cache_strategy.dart' show CacheStrategy;
10 import '../common/backend_api.dart' show Backend; 10 import '../common/backend_api.dart' show Backend;
11 import '../common/codegen.dart' show CodegenWorkItem; 11 import '../common/codegen.dart' show CodegenWorkItem;
12 import '../common/names.dart' show Identifiers;
13 import '../common/tasks.dart' show CompilerTask; 12 import '../common/tasks.dart' show CompilerTask;
14 import '../common/work.dart' show WorkItem; 13 import '../common/work.dart' show WorkItem;
15 import '../common.dart'; 14 import '../common.dart';
16 import '../compiler.dart' show Compiler; 15 import '../compiler.dart' show Compiler;
17 import '../dart_types.dart' show DartType, InterfaceType; 16 import '../dart_types.dart' show DartType, InterfaceType;
18 import '../dump_info.dart';
19 import '../elements/elements.dart' 17 import '../elements/elements.dart'
20 show 18 show ClassElement, Element, Entity, MemberElement, TypedElement;
21 ClassElement,
22 Element,
23 Entity,
24 FunctionElement,
25 MemberElement,
26 MethodElement,
27 TypedElement;
28 import '../elements/entities.dart'; 19 import '../elements/entities.dart';
29 import '../enqueue.dart'; 20 import '../enqueue.dart';
30 import '../js/js.dart' as js; 21 import '../js/js.dart' as js;
31 import '../native/native.dart' as native; 22 import '../native/native.dart' as native;
32 import '../options.dart'; 23 import '../options.dart';
33 import '../types/types.dart' show TypeMaskStrategy; 24 import '../types/types.dart' show TypeMaskStrategy;
34 import '../universe/selector.dart' show Selector;
35 import '../universe/world_builder.dart'; 25 import '../universe/world_builder.dart';
36 import '../universe/use.dart' 26 import '../universe/use.dart'
37 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; 27 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind;
38 import '../universe/world_impact.dart' 28 import '../universe/world_impact.dart'
39 show ImpactUseCase, WorldImpact, WorldImpactVisitor; 29 show ImpactUseCase, WorldImpact, WorldImpactVisitor;
30 import '../util/enumset.dart';
40 import '../util/util.dart' show Setlet; 31 import '../util/util.dart' show Setlet;
41 import '../world.dart';
42 32
43 /// [Enqueuer] which is specific to code generation. 33 /// [Enqueuer] which is specific to code generation.
44 class CodegenEnqueuer extends EnqueuerImpl { 34 class CodegenEnqueuer extends EnqueuerImpl {
45 final String name; 35 final String name;
46 final EnqueuerStrategy strategy; 36 final EnqueuerStrategy strategy;
47 final Map<String, Set<Element>> _instanceMembersByName = 37
48 new Map<String, Set<Element>>();
49 final Map<String, Set<Element>> _instanceFunctionsByName =
50 new Map<String, Set<Element>>();
51 final Set<ClassElement> _processedClasses = new Set<ClassElement>();
52 Set<ClassElement> _recentClasses = new Setlet<ClassElement>(); 38 Set<ClassElement> _recentClasses = new Setlet<ClassElement>();
53 final CodegenWorldBuilderImpl _universe = 39 final CodegenWorldBuilderImpl _universe;
54 new CodegenWorldBuilderImpl(const TypeMaskStrategy());
55 40
56 bool queueIsClosed = false; 41 bool queueIsClosed = false;
57 final CompilerTask task; 42 final CompilerTask task;
58 final native.NativeEnqueuer nativeEnqueuer; 43 final native.NativeEnqueuer nativeEnqueuer;
59 final Backend _backend; 44 final Backend _backend;
60 final CompilerOptions _options; 45 final CompilerOptions _options;
61 46
62 WorldImpactVisitor _impactVisitor; 47 WorldImpactVisitor _impactVisitor;
63 48
64 final Queue<WorkItem> _queue = new Queue<WorkItem>(); 49 final Queue<WorkItem> _queue = new Queue<WorkItem>();
65 final Map<Element, js.Expression> generatedCode = <Element, js.Expression>{}; 50 final Map<Element, js.Expression> generatedCode = <Element, js.Expression>{};
66 51
67 final Set<Element> newlyEnqueuedElements; 52 final Set<Element> newlyEnqueuedElements;
68 53
69 final Set<DynamicUse> newlySeenSelectors; 54 final Set<DynamicUse> newlySeenSelectors;
70 55
71 bool _enabledNoSuchMethod = false;
72
73 static const ImpactUseCase IMPACT_USE = 56 static const ImpactUseCase IMPACT_USE =
74 const ImpactUseCase('CodegenEnqueuer'); 57 const ImpactUseCase('CodegenEnqueuer');
75 58
76 CodegenEnqueuer(this.task, CacheStrategy cacheStrategy, Backend backend, 59 CodegenEnqueuer(this.task, CacheStrategy cacheStrategy, Backend backend,
77 this._options, this.strategy) 60 this._options, this.strategy)
78 : newlyEnqueuedElements = cacheStrategy.newSet(), 61 : _universe =
62 new CodegenWorldBuilderImpl(backend, const TypeMaskStrategy()),
63 newlyEnqueuedElements = cacheStrategy.newSet(),
79 newlySeenSelectors = cacheStrategy.newSet(), 64 newlySeenSelectors = cacheStrategy.newSet(),
80 nativeEnqueuer = backend.nativeCodegenEnqueuer(), 65 nativeEnqueuer = backend.nativeCodegenEnqueuer(),
81 this._backend = backend, 66 this._backend = backend,
82 this.name = 'codegen enqueuer' { 67 this.name = 'codegen enqueuer' {
83 _impactVisitor = new EnqueuerImplImpactVisitor(this); 68 _impactVisitor = new EnqueuerImplImpactVisitor(this);
84 } 69 }
85 70
86 CodegenWorldBuilder get universe => _universe; 71 CodegenWorldBuilder get universe => _universe;
87 72
88 // TODO(johnniwinther): Remove these hacks:
89 ClosedWorld get _world => _backend.compiler.closedWorld;
90 DumpInfoTask get _dumpInfoTask => _backend.compiler.dumpInfoTask;
91
92 bool get queueIsEmpty => _queue.isEmpty; 73 bool get queueIsEmpty => _queue.isEmpty;
93 74
94 /// Returns [:true:] if this enqueuer is the resolution enqueuer. 75 /// Returns [:true:] if this enqueuer is the resolution enqueuer.
95 bool get isResolutionQueue => false; 76 bool get isResolutionQueue => false;
96 77
97 /** 78 /**
98 * Documentation wanted -- johnniwinther 79 * Documentation wanted -- johnniwinther
99 * 80 *
100 * Invariant: [element] must be a declaration element. 81 * Invariant: [element] must be a declaration element.
101 */ 82 */
(...skipping 13 matching lines...) Expand all
115 96
116 if (_options.hasIncrementalSupport && !isProcessed(element)) { 97 if (_options.hasIncrementalSupport && !isProcessed(element)) {
117 newlyEnqueuedElements.add(element); 98 newlyEnqueuedElements.add(element);
118 } 99 }
119 100
120 if (queueIsClosed) { 101 if (queueIsClosed) {
121 throw new SpannableAssertionFailure( 102 throw new SpannableAssertionFailure(
122 element, "Codegen work list is closed. Trying to add $element"); 103 element, "Codegen work list is closed. Trying to add $element");
123 } 104 }
124 _queue.add(new CodegenWorkItem(_backend, element)); 105 _queue.add(new CodegenWorkItem(_backend, element));
125 // TODO(sigmund): add other missing dependencies (internals, selectors 106 applyImpact(_backend.registerUsedElement(element, forResolution: false));
126 // enqueued after allocations).
127 _dumpInfoTask.registerDependency(element);
128 } 107 }
129 108
130 void applyImpact(WorldImpact worldImpact, {Element impactSource}) { 109 void applyImpact(WorldImpact worldImpact, {Element impactSource}) {
131 if (worldImpact.isEmpty) return; 110 if (worldImpact.isEmpty) return;
132 impactStrategy.visitImpact( 111 impactStrategy.visitImpact(
133 impactSource, worldImpact, _impactVisitor, impactUse); 112 impactSource, worldImpact, _impactVisitor, impactUse);
134 } 113 }
135 114
136 void _registerInstantiatedType(InterfaceType type, 115 void _registerInstantiatedType(InterfaceType type,
137 {bool mirrorUsage: false, bool nativeUsage: false}) { 116 {bool mirrorUsage: false, bool nativeUsage: false}) {
138 task.measure(() { 117 task.measure(() {
139 ClassElement cls = type.element; 118 _universe.registerTypeInstantiation(type, _applyClassUse,
140 bool isNative = _backend.isNative(cls); 119 byMirrors: mirrorUsage);
141 _universe.registerTypeInstantiation(type,
142 isNative: isNative,
143 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) {
144 applyImpact(
145 _backend.registerImplementedClass(cls, forResolution: false));
146 });
147 if (nativeUsage) { 120 if (nativeUsage) {
148 nativeEnqueuer.onInstantiatedType(type); 121 nativeEnqueuer.onInstantiatedType(type);
149 } 122 }
150 _backend.registerInstantiatedType(type); 123 _backend.registerInstantiatedType(type);
151 // TODO(johnniwinther): Share this reasoning with [Universe].
152 if (!cls.isAbstract || isNative || mirrorUsage) {
153 _processInstantiatedClass(cls);
154 }
155 }); 124 });
156 } 125 }
157 126
158 bool checkNoEnqueuedInvokedInstanceMethods() { 127 bool checkNoEnqueuedInvokedInstanceMethods() {
159 return strategy.checkEnqueuerConsistency(this); 128 return strategy.checkEnqueuerConsistency(this);
160 } 129 }
161 130
162 void checkClass(ClassElement cls) { 131 void checkClass(ClassElement cls) {
163 cls.implementation.forEachMember(processInstantiatedClassMember); 132 _universe.processClassMembers(cls, (MemberElement member, useSet) {
164 } 133 if (useSet.isNotEmpty) {
165 134 _backend.compiler.reporter.internalError(member,
166 void processInstantiatedClassMember(ClassElement cls, Element member) { 135 'Unenqueued use of $member: ${useSet.iterable(MemberUse.values)}');
167 assert(invariant(member, member.isDeclaration));
168 if (isProcessed(member)) return;
169 if (!member.isInstanceMember) return;
170 String memberName = member.name;
171
172 if (member.isField) {
173 // The obvious thing to test here would be "member.isNative",
174 // however, that only works after metadata has been parsed/analyzed,
175 // and that may not have happened yet.
176 // So instead we use the enclosing class, which we know have had
177 // its metadata parsed and analyzed.
178 // Note: this assumes that there are no non-native fields on native
179 // classes, which may not be the case when a native class is subclassed.
180 if (_backend.isNative(cls)) {
181 if (_universe.hasInvokedGetter(member, _world) ||
182 _universe.hasInvocation(member, _world)) {
183 _addToWorkList(member);
184 return;
185 } else if (universe.hasInvokedSetter(member, _world)) {
186 _addToWorkList(member);
187 return;
188 }
189 // Native fields need to go into instanceMembersByName as they
190 // are virtual instantiation points and escape points.
191 } else {
192 // All field initializers must be resolved as they could
193 // have an observable side-effect (and cannot be tree-shaken
194 // away).
195 _addToWorkList(member);
196 return;
197 }
198 } else if (member.isFunction) {
199 FunctionElement function = member;
200 if (function.name == Identifiers.noSuchMethod_) {
201 _registerNoSuchMethod(function);
202 }
203 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) {
204 _registerCallMethodWithFreeTypeVariables(function);
205 }
206 // If there is a property access with the same name as a method we
207 // need to emit the method.
208 if (_universe.hasInvokedGetter(function, _world)) {
209 _registerClosurizedMember(function);
210 _addToWorkList(function);
211 return;
212 }
213 _registerInstanceMethod(function);
214 if (_universe.hasInvocation(function, _world)) {
215 _addToWorkList(function);
216 return;
217 }
218 } else if (member.isGetter) {
219 FunctionElement getter = member;
220 if (_universe.hasInvokedGetter(getter, _world)) {
221 _addToWorkList(getter);
222 return;
223 }
224 // We don't know what selectors the returned closure accepts. If
225 // the set contains any selector we have to assume that it matches.
226 if (_universe.hasInvocation(getter, _world)) {
227 _addToWorkList(getter);
228 return;
229 }
230 } else if (member.isSetter) {
231 FunctionElement setter = member;
232 if (_universe.hasInvokedSetter(setter, _world)) {
233 _addToWorkList(setter);
234 return;
235 }
236 }
237
238 // The element is not yet used. Add it to the list of instance
239 // members to still be processed.
240 _instanceMembersByName
241 .putIfAbsent(memberName, () => new Set<Element>())
242 .add(member);
243 }
244
245 // Store the member in [instanceFunctionsByName] to catch
246 // getters on the function.
247 void _registerInstanceMethod(MethodElement element) {
248 _instanceFunctionsByName
249 .putIfAbsent(element.name, () => new Set<Element>())
250 .add(element);
251 }
252
253 void _processInstantiatedClass(ClassElement cls) {
254 task.measure(() {
255 if (_processedClasses.contains(cls)) return;
256
257 void processClass(ClassElement superclass) {
258 if (_processedClasses.contains(superclass)) return;
259 // TODO(johnniwinther): Re-insert this invariant when unittests don't
260 // fail. There is already a similar invariant on the members.
261 /*assert(invariant(superclass,
262 superclass.isClosure ||
263 _compiler.enqueuer.resolution.isClassProcessed(superclass),
264 message: "Class $superclass has not been "
265 "processed in resolution."));
266 */
267
268 _processedClasses.add(superclass);
269 _recentClasses.add(superclass);
270 superclass.implementation.forEachMember(processInstantiatedClassMember);
271 // We only tell the backend once that [superclass] was instantiated, so
272 // any additional dependencies must be treated as global
273 // dependencies.
274 applyImpact(_backend.registerInstantiatedClass(superclass,
275 forResolution: false));
276 }
277
278 ClassElement superclass = cls;
279 while (superclass != null) {
280 processClass(superclass);
281 superclass = superclass.superclass;
282 } 136 }
283 }); 137 });
284 } 138 }
285 139
140 /// Callback for applying the use of a [cls].
141 void _applyClassUse(ClassEntity cls, EnumSet<ClassUse> useSet) {
142 if (useSet.contains(ClassUse.INSTANTIATED)) {
143 _recentClasses.add(cls);
144 _universe.processClassMembers(cls, _applyMemberUse);
145 // We only tell the backend once that [cls] was instantiated, so
146 // any additional dependencies must be treated as global
147 // dependencies.
148 applyImpact(
149 _backend.registerInstantiatedClass(cls, forResolution: false));
150 }
151 if (useSet.contains(ClassUse.IMPLEMENTED)) {
152 applyImpact(_backend.registerImplementedClass(cls, forResolution: false));
153 }
154 }
155
156 /// Callback for applying the use of a [member].
157 void _applyMemberUse(Entity member, EnumSet<MemberUse> useSet) {
158 if (useSet.contains(MemberUse.NORMAL)) {
159 _addToWorkList(member);
160 }
161 if (useSet.contains(MemberUse.CLOSURIZE_INSTANCE)) {
162 _registerClosurizedMember(member);
163 }
164 if (useSet.contains(MemberUse.CLOSURIZE_STATIC)) {
165 applyImpact(_backend.registerGetOfStaticFunction());
166 }
167 }
168
286 void processDynamicUse(DynamicUse dynamicUse) { 169 void processDynamicUse(DynamicUse dynamicUse) {
287 task.measure(() { 170 task.measure(() {
288 if (_universe.registerDynamicUse(dynamicUse)) { 171 if (_universe.registerDynamicUse(dynamicUse, _applyMemberUse)) {
289 _handleUnseenSelector(dynamicUse); 172 if (_options.hasIncrementalSupport) {
173 newlySeenSelectors.add(dynamicUse);
174 }
290 } 175 }
291 }); 176 });
292 } 177 }
293 178
294 void _processSet(
295 Map<String, Set<Element>> map, String memberName, bool f(Element e)) {
296 Set<Element> members = map[memberName];
297 if (members == null) return;
298 // [f] might add elements to [: map[memberName] :] during the loop below
299 // so we create a new list for [: map[memberName] :] and prepend the
300 // [remaining] members after the loop.
301 map[memberName] = new Set<Element>();
302 Set<Element> remaining = new Set<Element>();
303 for (Element member in members) {
304 if (!f(member)) remaining.add(member);
305 }
306 map[memberName].addAll(remaining);
307 }
308
309 void _processInstanceMembers(String n, bool f(Element e)) {
310 _processSet(_instanceMembersByName, n, f);
311 }
312
313 void _processInstanceFunctions(String n, bool f(Element e)) {
314 _processSet(_instanceFunctionsByName, n, f);
315 }
316
317 void _handleUnseenSelector(DynamicUse dynamicUse) {
318 if (_options.hasIncrementalSupport) {
319 newlySeenSelectors.add(dynamicUse);
320 }
321 Selector selector = dynamicUse.selector;
322 String methodName = selector.name;
323 _processInstanceMembers(methodName, (Element member) {
324 if (dynamicUse.appliesUnnamed(member, _world)) {
325 if (member.isFunction && selector.isGetter) {
326 _registerClosurizedMember(member);
327 }
328 _addToWorkList(member);
329 return true;
330 }
331 return false;
332 });
333 if (selector.isGetter) {
334 _processInstanceFunctions(methodName, (Element member) {
335 if (dynamicUse.appliesUnnamed(member, _world)) {
336 _registerClosurizedMember(member);
337 return true;
338 }
339 return false;
340 });
341 }
342 }
343
344 void processStaticUse(StaticUse staticUse) { 179 void processStaticUse(StaticUse staticUse) {
345 Element element = staticUse.element; 180 Element element = staticUse.element;
346 assert(invariant(element, element.isDeclaration, 181 assert(invariant(element, element.isDeclaration,
347 message: "Element ${element} is not the declaration.")); 182 message: "Element ${element} is not the declaration."));
348 _universe.registerStaticUse(staticUse); 183 _universe.registerStaticUse(staticUse, _applyMemberUse);
349 applyImpact(_backend.registerUsedElement(element, forResolution: false));
350 bool addElement = true;
351 switch (staticUse.kind) { 184 switch (staticUse.kind) {
352 case StaticUseKind.STATIC_TEAR_OFF:
353 applyImpact(_backend.registerGetOfStaticFunction());
354 break;
355 case StaticUseKind.FIELD_GET:
356 case StaticUseKind.FIELD_SET:
357 case StaticUseKind.CLOSURE:
358 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and
359 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue.
360 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot
361 // enqueue.
362 addElement = false;
363 break;
364 case StaticUseKind.SUPER_FIELD_SET:
365 case StaticUseKind.SUPER_TEAR_OFF:
366 case StaticUseKind.GENERAL:
367 case StaticUseKind.DIRECT_USE:
368 break;
369 case StaticUseKind.CONSTRUCTOR_INVOKE: 185 case StaticUseKind.CONSTRUCTOR_INVOKE:
370 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: 186 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
371 case StaticUseKind.REDIRECTION: 187 case StaticUseKind.REDIRECTION:
372 processTypeUse(new TypeUse.instantiation(staticUse.type)); 188 processTypeUse(new TypeUse.instantiation(staticUse.type));
373 break; 189 break;
374 case StaticUseKind.DIRECT_INVOKE: 190 default:
375 _registerInstanceMethod(staticUse.element);
376 break; 191 break;
377 } 192 }
378 if (addElement) {
379 _addToWorkList(element);
380 }
381 } 193 }
382 194
383 void processTypeUse(TypeUse typeUse) { 195 void processTypeUse(TypeUse typeUse) {
384 DartType type = typeUse.type; 196 DartType type = typeUse.type;
385 switch (typeUse.kind) { 197 switch (typeUse.kind) {
386 case TypeUseKind.INSTANTIATION: 198 case TypeUseKind.INSTANTIATION:
387 _registerInstantiatedType(type); 199 _registerInstantiatedType(type);
388 break; 200 break;
389 case TypeUseKind.MIRROR_INSTANTIATION: 201 case TypeUseKind.MIRROR_INSTANTIATION:
390 _registerInstantiatedType(type, mirrorUsage: true); 202 _registerInstantiatedType(type, mirrorUsage: true);
(...skipping 17 matching lines...) Expand all
408 } 220 }
409 221
410 void _registerIsCheck(DartType type) { 222 void _registerIsCheck(DartType type) {
411 type = _universe.registerIsCheck(type); 223 type = _universe.registerIsCheck(type);
412 // Even in checked mode, type annotations for return type and argument 224 // Even in checked mode, type annotations for return type and argument
413 // types do not imply type checks, so there should never be a check 225 // types do not imply type checks, so there should never be a check
414 // against the type variable of a typedef. 226 // against the type variable of a typedef.
415 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); 227 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef);
416 } 228 }
417 229
418 void _registerCallMethodWithFreeTypeVariables(Element element) {
419 applyImpact(_backend.registerCallMethodWithFreeTypeVariables(element,
420 forResolution: false));
421 }
422
423 void _registerClosurizedMember(TypedElement element) { 230 void _registerClosurizedMember(TypedElement element) {
424 assert(element.isInstanceMember); 231 assert(element.isInstanceMember);
425 if (element.type.containsTypeVariables) { 232 if (element.type.containsTypeVariables) {
426 applyImpact(_backend.registerClosureWithFreeTypeVariables(element, 233 applyImpact(_backend.registerClosureWithFreeTypeVariables(element,
427 forResolution: false)); 234 forResolution: false));
428 } 235 }
429 applyImpact(_backend.registerBoundClosure()); 236 applyImpact(_backend.registerBoundClosure());
430 } 237 }
431 238
432 void forEach(void f(WorkItem work)) { 239 void forEach(void f(WorkItem work)) {
(...skipping 28 matching lines...) Expand all
461 nativeEnqueuer.logSummary(log); 268 nativeEnqueuer.logSummary(log);
462 } 269 }
463 270
464 String toString() => 'Enqueuer($name)'; 271 String toString() => 'Enqueuer($name)';
465 272
466 ImpactUseCase get impactUse => IMPACT_USE; 273 ImpactUseCase get impactUse => IMPACT_USE;
467 274
468 bool isProcessed(Element member) => 275 bool isProcessed(Element member) =>
469 member.isAbstract || generatedCode.containsKey(member); 276 member.isAbstract || generatedCode.containsKey(member);
470 277
471 void _registerNoSuchMethod(Element element) {
472 if (!_enabledNoSuchMethod && _backend.enabledNoSuchMethod) {
473 applyImpact(_backend.enableNoSuchMethod());
474 _enabledNoSuchMethod = true;
475 }
476 }
477
478 void forgetEntity(Element element, Compiler compiler) { 278 void forgetEntity(Element element, Compiler compiler) {
479 _universe.forgetElement(element, compiler); 279 _universe.forgetElement(element, compiler);
480 _processedClasses.remove(element);
481 _instanceMembersByName[element.name]?.remove(element);
482 _instanceFunctionsByName[element.name]?.remove(element);
483 generatedCode.remove(element); 280 generatedCode.remove(element);
484 if (element is MemberElement) { 281 if (element is MemberElement) {
485 for (Element closure in element.nestedClosures) { 282 for (Element closure in element.nestedClosures) {
486 generatedCode.remove(closure); 283 generatedCode.remove(closure);
487 removeFromSet(_instanceMembersByName, closure);
488 removeFromSet(_instanceFunctionsByName, closure);
489 } 284 }
490 } 285 }
491 } 286 }
492 287
493 @override 288 @override
494 Iterable<Entity> get processedEntities => generatedCode.keys; 289 Iterable<Entity> get processedEntities => generatedCode.keys;
495 290
496 @override 291 @override
497 Iterable<ClassEntity> get processedClasses => _processedClasses; 292 Iterable<ClassEntity> get processedClasses => _universe.processedClasses;
498 } 293 }
499
500 void removeFromSet(Map<String, Set<Element>> map, Element element) {
501 Set<Element> set = map[element.name];
502 if (set == null) return;
503 set.remove(element);
504 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/backend.dart ('k') | pkg/compiler/lib/src/universe/world_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698