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

Unified Diff: dart/pkg/dart2js_incremental/lib/library_updater.dart

Issue 730423002: Incremental compilation of superclass change. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | dart/tests/try/web/incremental_compilation_update_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 772e7e6ef9114ab1a1205907f2adf72c9385df48..cb43d3b7e3af93410839346346e3df6eacbeb254 100644
--- a/dart/pkg/dart2js_incremental/lib/library_updater.dart
+++ b/dart/pkg/dart2js_incremental/lib/library_updater.dart
@@ -21,6 +21,7 @@ import 'package:compiler/src/elements/elements.dart' show
Element,
FunctionElement,
LibraryElement,
+ STATE_NOT_STARTED,
ScopeContainerElement;
import 'package:compiler/src/scanner/scannerlib.dart' show
@@ -373,9 +374,13 @@ class LibraryUpdater extends JsFeatures {
return cannotReuse(after, "Class has no body.");
}
if (isTokenBetween(diffToken, node.beginToken, body.beginToken)) {
- return cannotReuse(after, "Class header changed.");
+ logVerbose('Class header modified in ${after}');
+ updates.add(new ClassUpdate(compiler, before, after));
+ before.forEachLocalMember((ElementX member) {
+ // TODO(ahe): Quadratic.
+ invalidateScopesAffectedBy(member, before);
+ });
}
- logVerbose('Simple modification of ${after} detected');
return canReuseScopeContainerElement(before, after);
}
@@ -446,15 +451,20 @@ class LibraryUpdater extends JsFeatures {
for (Element element in updatedElements) {
if (!element.isClass) {
compiler.enqueuer.resolution.addToWorkList(element);
+ } else {
+ element.ensureResolved(compiler);
}
}
compiler.processQueue(compiler.enqueuer.resolution, null);
compiler.phase = Compiler.PHASE_DONE_RESOLVING;
+ Set changedClasses = new Set();
Johnni Winther 2014/11/19 12:52:57 Add type argument.
ahe 2014/11/21 10:12:24 Done.
for (Element element in updatedElements) {
if (!element.isClass) {
compiler.enqueuer.codegen.addToWorkList(element);
+ } else {
+ changedClasses.add(element);
}
}
compiler.processQueue(compiler.enqueuer.codegen, null);
@@ -498,6 +508,22 @@ class LibraryUpdater extends JsFeatures {
updates.addAll(inherits);
+ for (ClassElementX cls in changedClasses) {
+ ClassElement superclass = cls.superclass;
+ if (superclass != null) {
+ jsAst.Node classAccess = namer.elementAccess(cls);
+ jsAst.Node superAccess = namer.elementAccess(superclass);
+ updates.add(
+ js.statement(
+ r'#.prototype.__proto__ = #.prototype',
+ [classAccess, superAccess]));
+ updates.add(
+ js.statement(
+ r'#.prototype.constructor = #',
+ [classAccess, classAccess]));
+ }
+ }
+
for (RemovedFunctionUpdate update in removals) {
update.writeUpdateJsOn(updates);
}
@@ -857,6 +883,40 @@ class AddedClassUpdate extends Update with JsFeatures {
}
}
+class ClassUpdate extends Update with JsFeatures {
+ final PartialClassElement before;
+
+ final PartialClassElement after;
+
+ ClassUpdate(Compiler compiler, this.before, this.after)
+ : super(compiler);
+
+ PartialFunctionElement apply() {
+ patchElement();
+ reuseElement();
+ return before;
+ }
+
+ /// Destructively change the tokens in [before] to match those of [after].
+ void patchElement() {
+ before.cachedNode = after.cachedNode;
+ before.beginToken = after.beginToken;
+ before.endToken = after.endToken;
+ }
+
+ void reuseElement() {
+ before.supertype = null;
+ before.interfaces = null;
+ before.nativeTagInfo = null;
+ before.supertypeLoadState = STATE_NOT_STARTED;
+ before.resolutionState = STATE_NOT_STARTED;
+ before.isProxy = false;
+ before.hasIncompleteHierarchy = false;
+ before.backendMembers = const Link<Element>();
+ before.allSupertypesAndSelf = null;
+ }
+}
+
/// Returns all qualified names in [element] with less than four identifiers. A
/// qualified name is an identifier followed by a sequence of dots and
/// identifiers, for example, "x", and "x.y.z". But not "x.y.z.w" ("w" is the
« no previous file with comments | « no previous file | dart/tests/try/web/incremental_compilation_update_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698