| Index: lib/compiler/implementation/compiler.dart
|
| diff --git a/lib/compiler/implementation/compiler.dart b/lib/compiler/implementation/compiler.dart
|
| index 17ed94fb5ebc701034c5630a3868c64cfddf7fc2..2a7a0df55f57b35ee89db14945dd962833e78b2a 100644
|
| --- a/lib/compiler/implementation/compiler.dart
|
| +++ b/lib/compiler/implementation/compiler.dart
|
| @@ -29,7 +29,6 @@ const bool DUMP_INFERRED_TYPES = false;
|
| */
|
| const String BUILD_ID = 'build number could not be determined';
|
|
|
| -
|
| /**
|
| * Contains backend-specific data that is used throughout the compilation of
|
| * one work item.
|
| @@ -39,12 +38,19 @@ class ItemCompilationContext {
|
|
|
| class WorkItem {
|
| final ItemCompilationContext compilationContext;
|
| + /**
|
| + * Documentation wanted -- johnniwinther
|
| + *
|
| + * Invariant: [element] must be a declaration element.
|
| + */
|
| final Element element;
|
| TreeElements resolutionTree;
|
| bool allowSpeculativeOptimization = true;
|
| List<HTypeGuard> guards = const <HTypeGuard>[];
|
|
|
| - WorkItem(this.element, this.resolutionTree, this.compilationContext);
|
| + WorkItem(this.element, this.resolutionTree, this.compilationContext) {
|
| + assert(invariant(element, element.isDeclaration));
|
| + }
|
|
|
| bool isAnalyzed() => resolutionTree !== null;
|
|
|
| @@ -608,11 +614,12 @@ class Compiler implements DiagnosticListener {
|
| assert(phase == PHASE_RECOMPILING);
|
| while (!world.recompilationCandidates.isEmpty()) {
|
| WorkItem work = world.recompilationCandidates.next();
|
| - CodeBuffer oldCode = world.universe.generatedCode[work.element];
|
| - world.universe.generatedCode.remove(work.element);
|
| - world.universe.generatedBailoutCode.remove(work.element);
|
| - withCurrentElement(work.element, () => work.run(this, world));
|
| - CodeBuffer newCode = world.universe.generatedCode[work.element];
|
| + Element element = work.element;
|
| + CodeBuffer oldCode = world.universe.generatedCode[element];
|
| + world.universe.generatedCode.remove(element);
|
| + world.universe.generatedBailoutCode.remove(element);
|
| + withCurrentElement(element, () => work.run(this, world));
|
| + CodeBuffer newCode = world.universe.generatedCode[element];
|
| if (REPORT_PASS2_OPTIMIZATIONS && newCode != oldCode) {
|
| log("Pass 2 optimization:");
|
| log("Before:\n$oldCode");
|
| @@ -670,6 +677,7 @@ class Compiler implements DiagnosticListener {
|
| }
|
|
|
| TreeElements analyzeElement(Element element) {
|
| + assert(invariant(element, element.isDeclaration));
|
| TreeElements elements = enqueuer.resolution.getCachedElements(element);
|
| if (elements !== null) return elements;
|
| final int allowed = ElementCategory.VARIABLE | ElementCategory.FUNCTION
|
| @@ -713,6 +721,7 @@ class Compiler implements DiagnosticListener {
|
| 'Internal error: unresolved element: $element.');
|
| }
|
| result = analyzeElement(element);
|
| + assert(invariant(element, element.isDeclaration));
|
| enqueuer.resolution.resolvedElements[element] = result;
|
| return result;
|
| }
|
| @@ -950,3 +959,24 @@ class SourceSpan {
|
|
|
| String toString() => 'SourceSpan($uri, $begin, $end)';
|
| }
|
| +
|
| +/**
|
| + * Throws an [InvariantException] if [condition] is [:false:]. [condition] must
|
| + * be either a [:bool:] or a no-arg function returning a [:bool:].
|
| + *
|
| + * Use this method to provide better information for assertion by calling
|
| + * [invariant] as the argument to an [:assert:] statement:
|
| + *
|
| + * assert(invariant(position, isValid));
|
| + *
|
| + * [spannable] must be non-null and will be used to provide positional
|
| + * information in the generated error message.
|
| + */
|
| +bool invariant(Spannable spannable, var condition, {String message: null}) {
|
| + // TODO(johnniwinther): Use [spannable] and [message] to provide better
|
| + // information on assertion errors.
|
| + if (condition is Function){
|
| + condition = condition();
|
| + }
|
| + return spannable != null && condition;
|
| +}
|
|
|