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

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

Issue 659813002: Apply updates to static methods. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 months 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
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 d3eb2e87c98474dec7f8cd9cf6d19630c8cc36d7..600f1f516289fc6d7d3a5894a03c716b6134a7ab 100644
--- a/dart/pkg/dart2js_incremental/lib/library_updater.dart
+++ b/dart/pkg/dart2js_incremental/lib/library_updater.dart
@@ -19,10 +19,12 @@ import 'package:compiler/implementation/dart2jslib.dart' show
import 'package:compiler/implementation/elements/elements.dart' show
Element,
FunctionElement,
- LibraryElement;
+ LibraryElement,
+ ScopeContainerElement;
import 'package:compiler/implementation/scanner/scannerlib.dart' show
EOF_TOKEN,
+ PartialClassElement,
PartialElement,
PartialFunctionElement,
Token;
@@ -31,6 +33,7 @@ import 'package:compiler/implementation/source_file.dart' show
StringSourceFile;
import 'package:compiler/implementation/tree/tree.dart' show
+ ClassNode,
FunctionExpression;
import 'package:compiler/implementation/js/js.dart' show
@@ -54,6 +57,8 @@ import 'diff.dart' show
typedef void Logger(message);
+typedef bool Reuser(Token diffToken, Element before, Element after);
+
// TODO(ahe): Generalize this class. For now only works for Compiler.mainApp,
// and only if that library has exactly one compilation unit.
class LibraryUpdater {
@@ -73,6 +78,8 @@ class LibraryUpdater {
// [compiler]'s state correctly reflects the updated program.
bool hasPendingUpdates = false;
+ bool onlySimpleUpdates = true;
+
final List<Update> updates = <Update>[];
LibraryUpdater(
@@ -126,35 +133,50 @@ class LibraryUpdater {
LibraryElement newLibrary = dartPrivacyIsBroken.createLibrarySync(
null, sourceScript, uri);
logTime('New library synthesized.');
- List<Difference> differences = computeDifference(library, newLibrary);
+ return canReuseScopeContainerElement(library, newLibrary);
+ }
+
+ bool canReuseScopeContainerElement(
+ ScopeContainerElement element,
+ ScopeContainerElement newElement) {
+ List<Difference> differences = computeDifference(element, newElement);
logTime('Differences computed.');
for (Difference difference in differences) {
logTime('Looking at difference: $difference');
if (difference.before == null || difference.after == null) {
logVerbose('Scope changed in $difference');
// Scope changed, don't reuse library.
+ onlySimpleUpdates = false;
return false;
}
Token diffToken = difference.token;
if (diffToken == null) {
logVerbose('No token stored in difference.');
+ onlySimpleUpdates = false;
return false;
}
if (difference.after is! PartialElement &&
difference.before is! PartialElement) {
logVerbose('Not a PartialElement: $difference');
// Don't know how to recompile element.
+ onlySimpleUpdates = false;
return false;
}
PartialElement before = difference.before;
PartialElement after = difference.after;
+ Reuser reuser;
+
if (before is PartialFunctionElement && after is PartialFunctionElement) {
- if (!canReuseFunction(diffToken, before, after)) {
- return false;
- }
+ reuser = canReuseFunction;
+ } else if (before is PartialClassElement &&
+ after is PartialClassElement) {
+ reuser = canReuseClass;
} else {
- // Unhandled kind of element.
+ reuser = cannotReuse;
+ }
+ if (!reuser(diffToken, before, after)) {
+ onlySimpleUpdates = false;
return false;
}
}
@@ -174,27 +196,66 @@ class LibraryUpdater {
FunctionExpression node =
after.parseNode(compiler).asFunctionExpression();
if (node == null) {
- print('Not a function expression.');
+ logVerbose('Not a function expression.');
return false;
}
Token last = after.endToken;
if (node.body != null) {
last = node.body.getBeginToken();
}
- Token token = after.beginToken;
- while (token != last && token.kind != EOF_TOKEN) {
- if (token == diffToken) {
- logVerbose('Signature changed');
- return false;
- }
- token = token.next;
+ if (isTokenBetween(diffToken, after.beginToken, last)) {
+ logVerbose('Signature changed.');
+ return false;
}
- print('Simple modification of ${after} detected');
+ logVerbose('Simple modification of ${after} detected');
updates.add(new FunctionUpdate(compiler, before, after));
return true;
}
+ bool canReuseClass(
+ Token diffToken,
+ PartialClassElement before,
+ PartialClassElement after) {
+ ClassNode node = after.parseNode(compiler).asClassNode();
+ if (node == null) {
+ logVerbose('Not a ClassNode.');
+ return false;
+ }
+ NodeList body = node.body;
+ if (body == null) {
+ logVerbose('Class has no body.');
+ return false;
+ }
+ if (isTokenBetween(diffToken, node.beginToken, body.beginToken)) {
+ logVerbose('Class header changed.');
+ return false;
+ }
+ logVerbose('Simple modification of ${after} detected');
+ return canReuseScopeContainerElement(before, after);
+ }
+
+ bool isTokenBetween(Token token, Token first, Token last) {
+ Token current = first;
+ while (current != last && current.kind != EOF_TOKEN) {
+ if (current == token) {
+ return true;
+ }
+ current = current.next;
+ }
+ return false;
+ }
+
+ bool cannotReuse(Token diffToken, Element before, Element after) {
+ logVerbose(
+ 'Unhandled change:'
+ ' ${before.name} (${before.runtimeType} -> ${after.runtimeType}).');
+ return false;
+ }
+
List<Element> applyUpdates() {
+ if (!onlySimpleUpdates) {
+ throw new StateError("Can't compute update.");
+ }
return updates.map((Update update) => update.apply()).toList();
}

Powered by Google App Engine
This is Rietveld 408576698