Index: dart/pkg/dart2js_incremental/lib/library_updater.dart |
diff --git a/dart/pkg/dart2js_incremental/lib/library_updater.dart b/dart/pkg/dart2js_incremental/lib/library_updater.dart |
index eab16f330bc981f3075c73d3f0a43c666703f991..2331ffbfb2554dd4b895202ba22ba54f877a5ed7 100644 |
--- a/dart/pkg/dart2js_incremental/lib/library_updater.dart |
+++ b/dart/pkg/dart2js_incremental/lib/library_updater.dart |
@@ -14,6 +14,7 @@ import 'package:compiler/compiler.dart' as api; |
import 'package:compiler/src/dart2jslib.dart' show |
Compiler, |
+ EnqueueTask, |
Script; |
import 'package:compiler/src/elements/elements.dart' show |
@@ -72,6 +73,9 @@ import 'package:compiler/src/elements/modelx.dart' show |
FieldElementX, |
LibraryElementX; |
+import 'package:compiler/src/universe/universe.dart' show |
+ Selector; |
+ |
import 'diff.dart' show |
Difference, |
computeDifference; |
@@ -547,12 +551,12 @@ class LibraryUpdater extends JsFeatures { |
} |
for (Element element in updatedElements) { |
if (!element.isClass) { |
- compiler.enqueuer.resolution.addToWorkList(element); |
+ enqueuer.resolution.addToWorkList(element); |
} else { |
NO_WARN(element).ensureResolved(compiler); |
} |
} |
- compiler.processQueue(compiler.enqueuer.resolution, null); |
+ compiler.processQueue(enqueuer.resolution, null); |
compiler.phase = Compiler.PHASE_DONE_RESOLVING; |
@@ -563,20 +567,57 @@ class LibraryUpdater extends JsFeatures { |
new Set<ClassElementX>.from(_classesWithSchemaChanges); |
for (Element element in updatedElements) { |
if (!element.isClass) { |
- compiler.enqueuer.codegen.addToWorkList(element); |
+ enqueuer.codegen.addToWorkList(element); |
} else { |
changedClasses.add(element); |
} |
} |
- compiler.processQueue(compiler.enqueuer.codegen, null); |
+ compiler.processQueue(enqueuer.codegen, null); |
+ |
+ // Run through all compiled methods and see if they may apply to |
+ // newlySeenSelectors. |
+ for (Element e in enqueuer.codegen.generatedCode.keys) { |
+ if (e.isFunction && !e.isConstructor && |
+ e.functionSignature.hasOptionalParameters) { |
+ for (Selector selector in enqueuer.codegen.newlySeenSelectors) { |
+ // TODO(ahe): Group selectors by name at this point for improved |
+ // performance. |
+ if (e.isInstanceMember && selector.applies(e, compiler.world)) { |
+ // TODO(ahe): Don't use |
+ // enqueuer.codegen.newlyEnqueuedElements directly like |
+ // this, make a copy. |
+ enqueuer.codegen.newlyEnqueuedElements.add(e); |
+ } |
+ if (selector.name == namer.closureInvocationSelectorName) { |
+ selector = new Selector.call( |
+ e.name, e.library, |
+ selector.argumentCount, selector.namedArguments); |
+ if (selector.appliesUnnamed(e, compiler.world)) { |
+ // TODO(ahe): Also make a copy here. |
+ enqueuer.codegen.newlyEnqueuedElements.add(e); |
+ } |
+ } |
+ } |
+ } |
+ } |
List<jsAst.Statement> updates = <jsAst.Statement>[]; |
- Set newClasses = new Set.from( |
+ // TODO(ahe): allInstantiatedClasses seem to include interfaces that aren't |
+ // needed. |
+ Set<ClassElementX> newClasses = new Set.from( |
compiler.codegenWorld.allInstantiatedClasses.where( |
emitter.computeClassFilter())); |
newClasses.removeAll(_existingClasses); |
+ // TODO(ahe): When more than one updated is computed, we need to make sure |
+ // that existing classes aren't overwritten. No test except the one test |
+ // that tests more than one update is affected by this problem, and only |
+ // because main is closurized because we always enable tear-off. Is that |
+ // really necessary? Also, add a test which tests directly that what |
+ // happens when tear-off is introduced in second update. |
+ emitter.neededClasses.addAll(newClasses); |
+ |
List<jsAst.Statement> inherits = <jsAst.Statement>[]; |
for (ClassElementX cls in newClasses) { |
@@ -617,12 +658,23 @@ class LibraryUpdater extends JsFeatures { |
for (RemovalUpdate update in removals) { |
update.writeUpdateJsOn(updates); |
} |
- for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
+ for (Element element in enqueuer.codegen.newlyEnqueuedElements) { |
if (!element.isField) { |
updates.add(computeMemberUpdateJs(element)); |
+ } else { |
+ if (backend.constants.lazyStatics.contains(element)) { |
+ throw new StateError("$element requires lazy initializer."); |
+ } |
} |
} |
+ updates.add(js.statement(r''' |
+if (self.$dart_unsafe_eval.pendingStubs) { |
+ self.$dart_unsafe_eval.pendingStubs.map(function(e) { return e(); }); |
+ self.$dart_unsafe_eval.pendingStubs = void 0; |
+} |
+''')); |
+ |
if (updates.length == 1) { |
return prettyPrintJs(updates.single); |
} else { |
@@ -1137,6 +1189,8 @@ abstract class JsFeatures { |
CodeEmitterTask get emitter => backend.emitter; |
ContainerBuilder get containerBuilder => emitter.oldEmitter.containerBuilder; |
+ |
+ EnqueueTask get enqueuer => compiler.enqueuer; |
} |
class EmitterHelper extends JsFeatures { |