Chromium Code Reviews| 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 |