| 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 |