OLD | NEW |
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.enqueue; | 5 library dart2js.enqueue; |
6 | 6 |
7 import 'dart:collection' show Queue; | 7 import 'dart:collection' show Queue; |
8 | 8 |
9 import 'common/resolution.dart' show Resolution; | 9 import 'common/resolution.dart' show Resolution; |
10 import 'common/tasks.dart' show CompilerTask; | 10 import 'common/tasks.dart' show CompilerTask; |
(...skipping 16 matching lines...) Expand all Loading... |
27 import 'world.dart' show ClosedWorld; | 27 import 'world.dart' show ClosedWorld; |
28 | 28 |
29 class EnqueueTask extends CompilerTask { | 29 class EnqueueTask extends CompilerTask { |
30 ResolutionEnqueuer _resolution; | 30 ResolutionEnqueuer _resolution; |
31 final Compiler compiler; | 31 final Compiler compiler; |
32 | 32 |
33 String get name => 'Enqueue'; | 33 String get name => 'Enqueue'; |
34 | 34 |
35 EnqueueTask(Compiler compiler) | 35 EnqueueTask(Compiler compiler) |
36 : this.compiler = compiler, | 36 : this.compiler = compiler, |
37 super(compiler.measurer) { | 37 super(compiler.measurer); |
38 createResolutionEnqueuer(); | |
39 } | |
40 | 38 |
| 39 // TODO(johnniwinther): Remove the need for this. |
| 40 bool get hasResolution => _resolution != null; |
| 41 |
| 42 // TODO(johnniwinther): Remove the need for this. |
41 ResolutionEnqueuer get resolution { | 43 ResolutionEnqueuer get resolution { |
42 assert(invariant(NO_LOCATION_SPANNABLE, _resolution != null, | 44 assert(invariant(NO_LOCATION_SPANNABLE, _resolution != null, |
43 message: "ResolutionEnqueuer has not been created yet.")); | 45 message: "ResolutionEnqueuer has not been created yet.")); |
44 return _resolution; | 46 return _resolution; |
45 } | 47 } |
46 | 48 |
47 ResolutionEnqueuer createResolutionEnqueuer() { | 49 ResolutionEnqueuer createResolutionEnqueuer() { |
48 return _resolution ??= | 50 return _resolution ??= |
49 compiler.backend.createResolutionEnqueuer(this, compiler); | 51 compiler.backend.createResolutionEnqueuer(this, compiler); |
50 } | 52 } |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 | 187 |
186 WorldImpactVisitor _impactVisitor; | 188 WorldImpactVisitor _impactVisitor; |
187 | 189 |
188 /// All declaration elements that have been processed by the resolver. | 190 /// All declaration elements that have been processed by the resolver. |
189 final Set<Entity> _processedEntities = new Set<Entity>(); | 191 final Set<Entity> _processedEntities = new Set<Entity>(); |
190 | 192 |
191 final Queue<WorkItem> _queue = new Queue<WorkItem>(); | 193 final Queue<WorkItem> _queue = new Queue<WorkItem>(); |
192 | 194 |
193 /// Queue of deferred resolution actions to execute when the resolution queue | 195 /// Queue of deferred resolution actions to execute when the resolution queue |
194 /// has been emptied. | 196 /// has been emptied. |
195 final Queue<_DeferredAction> _deferredQueue = new Queue<_DeferredAction>(); | 197 final Queue<DeferredAction> _deferredQueue = new Queue<DeferredAction>(); |
196 | 198 |
197 ResolutionEnqueuer(this.task, this._options, this._reporter, this.strategy, | 199 ResolutionEnqueuer(this.task, this._options, this._reporter, this.strategy, |
198 this.listener, this._worldBuilder, this._workItemBuilder, | 200 this.listener, this._worldBuilder, this._workItemBuilder, |
199 [this.name = 'resolution enqueuer']) { | 201 [this.name = 'resolution enqueuer']) { |
200 _impactVisitor = new EnqueuerImplImpactVisitor(this); | 202 _impactVisitor = new EnqueuerImplImpactVisitor(this); |
201 } | 203 } |
202 | 204 |
203 ResolutionWorldBuilder get worldBuilder => _worldBuilder; | 205 ResolutionWorldBuilder get worldBuilder => _worldBuilder; |
204 | 206 |
205 bool get queueIsEmpty => _queue.isEmpty; | 207 bool get queueIsEmpty => _queue.isEmpty; |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 applyImpact(listener.registerUsedElement(entity)); | 410 applyImpact(listener.registerUsedElement(entity)); |
409 _worldBuilder.registerUsedElement(entity); | 411 _worldBuilder.registerUsedElement(entity); |
410 _queue.add(workItem); | 412 _queue.add(workItem); |
411 } | 413 } |
412 | 414 |
413 /// Adds an action to the deferred task queue. | 415 /// Adds an action to the deferred task queue. |
414 /// The action is performed the next time the resolution queue has been | 416 /// The action is performed the next time the resolution queue has been |
415 /// emptied. | 417 /// emptied. |
416 /// | 418 /// |
417 /// The queue is processed in FIFO order. | 419 /// The queue is processed in FIFO order. |
418 void addDeferredAction(Entity entity, void action()) { | 420 void addDeferredAction(DeferredAction deferredAction) { |
419 if (queueIsClosed) { | 421 if (queueIsClosed) { |
420 throw new SpannableAssertionFailure( | 422 throw new SpannableAssertionFailure( |
421 entity, | 423 deferredAction.element, |
422 "Resolution work list is closed. " | 424 "Resolution work list is closed. " |
423 "Trying to add deferred action for $entity"); | 425 "Trying to add deferred action for ${deferredAction.element}"); |
424 } | 426 } |
425 _deferredQueue.add(new _DeferredAction(entity, action)); | 427 _deferredQueue.add(deferredAction); |
| 428 } |
| 429 |
| 430 void addDeferredActions(Iterable<DeferredAction> deferredActions) { |
| 431 deferredActions.forEach(addDeferredAction); |
426 } | 432 } |
427 | 433 |
428 /// [_onQueueEmpty] is called whenever the queue is drained. [recentClasses] | 434 /// [_onQueueEmpty] is called whenever the queue is drained. [recentClasses] |
429 /// contains the set of all classes seen for the first time since | 435 /// contains the set of all classes seen for the first time since |
430 /// [_onQueueEmpty] was called last. A return value of [true] indicates that | 436 /// [_onQueueEmpty] was called last. A return value of [true] indicates that |
431 /// the [recentClasses] have been processed and may be cleared. If [false] is | 437 /// the [recentClasses] have been processed and may be cleared. If [false] is |
432 /// returned, [_onQueueEmpty] will be called once the queue is empty again (or | 438 /// returned, [_onQueueEmpty] will be called once the queue is empty again (or |
433 /// still empty) and [recentClasses] will be a superset of the current value. | 439 /// still empty) and [recentClasses] will be a superset of the current value. |
434 bool _onQueueEmpty(Iterable<ClassEntity> recentClasses) { | 440 bool _onQueueEmpty(Iterable<ClassEntity> recentClasses) { |
435 _emptyDeferredQueue(); | 441 _emptyDeferredQueue(); |
436 | 442 |
437 return listener.onQueueEmpty(this, recentClasses); | 443 return listener.onQueueEmpty(this, recentClasses); |
438 } | 444 } |
439 | 445 |
440 void emptyDeferredQueueForTesting() => _emptyDeferredQueue(); | 446 void emptyDeferredQueueForTesting() => _emptyDeferredQueue(); |
441 | 447 |
442 void _emptyDeferredQueue() { | 448 void _emptyDeferredQueue() { |
443 while (!_deferredQueue.isEmpty) { | 449 while (!_deferredQueue.isEmpty) { |
444 _DeferredAction task = _deferredQueue.removeFirst(); | 450 DeferredAction task = _deferredQueue.removeFirst(); |
445 _reporter.withCurrentElement(task.element, task.action); | 451 _reporter.withCurrentElement(task.element, task.action); |
446 } | 452 } |
447 } | 453 } |
448 } | 454 } |
449 | 455 |
450 /// Strategy used by the enqueuer to populate the world. | 456 /// Strategy used by the enqueuer to populate the world. |
451 class EnqueuerStrategy { | 457 class EnqueuerStrategy { |
452 const EnqueuerStrategy(); | 458 const EnqueuerStrategy(); |
453 | 459 |
454 /// Process a static use of and element in live code. | 460 /// Process a static use of and element in live code. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 void visitStaticUse(StaticUse staticUse) { | 535 void visitStaticUse(StaticUse staticUse) { |
530 enqueuer.strategy.processStaticUse(enqueuer, staticUse); | 536 enqueuer.strategy.processStaticUse(enqueuer, staticUse); |
531 } | 537 } |
532 | 538 |
533 @override | 539 @override |
534 void visitTypeUse(TypeUse typeUse) { | 540 void visitTypeUse(TypeUse typeUse) { |
535 enqueuer.strategy.processTypeUse(enqueuer, typeUse); | 541 enqueuer.strategy.processTypeUse(enqueuer, typeUse); |
536 } | 542 } |
537 } | 543 } |
538 | 544 |
539 typedef void _DeferredActionFunction(); | 545 typedef void DeferredActionFunction(); |
540 | 546 |
541 class _DeferredAction { | 547 class DeferredAction { |
542 final Entity element; | 548 final Entity element; |
543 final _DeferredActionFunction action; | 549 final DeferredActionFunction action; |
544 | 550 |
545 _DeferredAction(this.element, this.action); | 551 DeferredAction(this.element, this.action); |
546 } | 552 } |
547 | 553 |
548 /// Interface for creating work items for enqueued member entities. | 554 /// Interface for creating work items for enqueued member entities. |
549 abstract class WorkItemBuilder { | 555 abstract class WorkItemBuilder { |
550 WorkItem createWorkItem(MemberEntity entity); | 556 WorkItem createWorkItem(MemberEntity entity); |
551 } | 557 } |
552 | 558 |
553 /// Builder that creates work item necessary for the resolution of a | 559 /// Builder that creates work item necessary for the resolution of a |
554 /// [MemberElement]. | 560 /// [MemberElement]. |
555 class ResolutionWorkItemBuilder extends WorkItemBuilder { | 561 class ResolutionWorkItemBuilder extends WorkItemBuilder { |
556 final Resolution _resolution; | 562 final Resolution _resolution; |
557 | 563 |
558 ResolutionWorkItemBuilder(this._resolution); | 564 ResolutionWorkItemBuilder(this._resolution); |
559 | 565 |
560 @override | 566 @override |
561 WorkItem createWorkItem(MemberElement element) { | 567 WorkItem createWorkItem(MemberElement element) { |
562 assert(invariant(element, element.isDeclaration)); | 568 assert(invariant(element, element.isDeclaration)); |
563 if (element.isMalformed) return null; | 569 if (element.isMalformed) return null; |
564 | 570 |
565 assert(invariant(element, element is AnalyzableElement, | 571 assert(invariant(element, element is AnalyzableElement, |
566 message: 'Element $element is not analyzable.')); | 572 message: 'Element $element is not analyzable.')); |
567 return _resolution.createWorkItem(element); | 573 return _resolution.createWorkItem(element); |
568 } | 574 } |
569 } | 575 } |
OLD | NEW |