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

Side by Side Diff: dart/pkg/dart2js_incremental/lib/library_updater.dart

Issue 654523003: Handle top-level tear offs. (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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dart2js_incremental.library_updater; 5 library dart2js_incremental.library_updater;
6 6
7 import 'dart:async' show 7 import 'dart:async' show
8 Future; 8 Future;
9 9
10 import 'dart:convert' show 10 import 'dart:convert' show
11 UTF8; 11 UTF8;
12 12
13 import 'package:compiler/compiler.dart' as api; 13 import 'package:compiler/compiler.dart' as api;
14 14
15 import 'package:compiler/implementation/dart2jslib.dart' show 15 import 'package:compiler/implementation/dart2jslib.dart' show
16 Compiler, 16 Compiler,
17 Script; 17 Script;
18 18
19 import 'package:compiler/implementation/elements/elements.dart' show 19 import 'package:compiler/implementation/elements/elements.dart' show
20 Element, 20 Element,
21 FunctionElement,
21 LibraryElement; 22 LibraryElement;
22 23
23 import 'package:compiler/implementation/scanner/scannerlib.dart' show 24 import 'package:compiler/implementation/scanner/scannerlib.dart' show
24 EOF_TOKEN, 25 EOF_TOKEN,
25 PartialElement, 26 PartialElement,
26 PartialFunctionElement, 27 PartialFunctionElement,
27 Token; 28 Token;
28 29
29 import 'package:compiler/implementation/source_file.dart' show 30 import 'package:compiler/implementation/source_file.dart' show
30 StringSourceFile; 31 StringSourceFile;
31 32
32 import 'package:compiler/implementation/tree/tree.dart' show 33 import 'package:compiler/implementation/tree/tree.dart' show
33 FunctionExpression; 34 FunctionExpression;
34 35
35 import 'package:compiler/implementation/js/js.dart' show 36 import 'package:compiler/implementation/js/js.dart' show
36 js; 37 js;
37 38
38 import 'package:compiler/implementation/js/js.dart' as jsAst; 39 import 'package:compiler/implementation/js/js.dart' as jsAst;
39 40
40 import 'package:compiler/implementation/js_emitter/js_emitter.dart' show 41 import 'package:compiler/implementation/js_emitter/js_emitter.dart' show
41 ClassBuilder; 42 CodeEmitterTask,
43 MemberInfo;
42 44
43 import 'package:compiler/js_lib/shared/embedded_names.dart' as embeddedNames; 45 import 'package:compiler/js_lib/shared/embedded_names.dart' as embeddedNames;
44 46
47 import 'package:compiler/implementation/js_backend/js_backend.dart' show
48 JavaScriptBackend,
49 Namer;
50
45 import 'diff.dart' show 51 import 'diff.dart' show
46 Difference, 52 Difference,
47 computeDifference; 53 computeDifference;
48 54
49 typedef void Logger(message); 55 typedef void Logger(message);
50 56
51 // TODO(ahe): Generalize this class. For now only works for Compiler.mainApp, 57 // TODO(ahe): Generalize this class. For now only works for Compiler.mainApp,
52 // and only if that library has exactly one compilation unit. 58 // and only if that library has exactly one compilation unit.
53 class LibraryUpdater { 59 class LibraryUpdater {
54 final Compiler compiler; 60 final Compiler compiler;
(...skipping 14 matching lines...) Expand all
69 75
70 final List<Update> updates = <Update>[]; 76 final List<Update> updates = <Update>[];
71 77
72 LibraryUpdater( 78 LibraryUpdater(
73 this.compiler, 79 this.compiler,
74 this.inputProvider, 80 this.inputProvider,
75 this.uri, 81 this.uri,
76 this.logTime, 82 this.logTime,
77 this.logVerbose); 83 this.logVerbose);
78 84
85 JavaScriptBackend get backend => compiler.backend;
86
87 Namer get namer => backend.namer;
88
89 CodeEmitterTask get emitter => backend.emitter;
90
79 /// Used as tear-off passed to [LibraryLoaderTask.resetAsync]. 91 /// Used as tear-off passed to [LibraryLoaderTask.resetAsync].
80 Future<bool> reuseLibrary(LibraryElement library) { 92 Future<bool> reuseLibrary(LibraryElement library) {
81 assert(compiler != null); 93 assert(compiler != null);
82 if (library.isPlatformLibrary || library.isPackageLibrary) { 94 if (library.isPlatformLibrary || library.isPackageLibrary) {
83 logTime('Reusing $library.'); 95 logTime('Reusing $library.');
84 return new Future.value(true); 96 return new Future.value(true);
85 } else if (library != compiler.mainApp) { 97 } else if (library != compiler.mainApp) {
86 return new Future.value(false); 98 return new Future.value(false);
87 } 99 }
88 return inputProvider(uri).then((bytes) { 100 return inputProvider(uri).then((bytes) {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 210
199 compiler.phase = Compiler.PHASE_DONE_RESOLVING; 211 compiler.phase = Compiler.PHASE_DONE_RESOLVING;
200 212
201 for (Element element in updatedElements) { 213 for (Element element in updatedElements) {
202 compiler.enqueuer.codegen.addToWorkList(element); 214 compiler.enqueuer.codegen.addToWorkList(element);
203 } 215 }
204 compiler.processQueue(compiler.enqueuer.codegen, null); 216 compiler.processQueue(compiler.enqueuer.codegen, null);
205 217
206 List<jsAst.Statement> updates = <jsAst.Statement>[]; 218 List<jsAst.Statement> updates = <jsAst.Statement>[];
207 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { 219 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) {
208 updates.add(computeMemberUpdateJs(element)); 220 if (!element.isField) {
221 updates.add(computeMemberUpdateJs(element));
222 }
209 } 223 }
210 224
211 if (updates.length == 1) { 225 if (updates.length == 1) {
212 return prettyPrintJs(updates.single); 226 return prettyPrintJs(updates.single);
213 } else { 227 } else {
214 return prettyPrintJs(js.statement('{#}', [updates])); 228 return prettyPrintJs(js.statement('{#}', [updates]));
215 } 229 }
216 } 230 }
217 231
218 jsAst.Node computeMemberUpdateJs(Element element) { 232 jsAst.Node computeMemberUpdateJs(Element element) {
219 ClassBuilder builder = new ClassBuilder(element, compiler.backend.namer); 233 MemberInfo info = emitter.oldEmitter.containerBuilder
220 234 .analyzeMemberMethod(element);
221 compiler.backend.emitter.oldEmitter.containerBuilder.addMember( 235 if (info == null) {
222 element, builder); 236 throw '$element ${element.runtimeType}';
Johnni Winther 2014/10/14 07:40:26 internalError instead of throw?
ahe 2014/10/15 09:11:12 Good idea, I hadn't thought about this as part of
223 jsAst.Property property = builder.properties.single; 237 }
224 jsAst.Node name = property.name; 238 String name = info.name;
225 jsAst.Node function = property.value; 239 jsAst.Node function = info.code;
226 jsAst.Node elementAccess = compiler.backend.namer.elementAccess(element); 240 jsAst.Node elementAccess = namer.elementAccess(element);
227 jsAst.Expression globalFunctionsAccess = 241 jsAst.Expression globalFunctionsAccess =
228 compiler.backend.emitter.generateEmbeddedGlobalAccess( 242 emitter.generateEmbeddedGlobalAccess(embeddedNames.GLOBAL_FUNCTIONS);
229 embeddedNames.GLOBAL_FUNCTIONS);
230 List<jsAst.Statement> statements = <jsAst.Statement>[]; 243 List<jsAst.Statement> statements = <jsAst.Statement>[];
231 statements.add( 244 statements.add(
232 js.statement( 245 js.statement(
233 '#.# = # = f', 246 '#.# = # = f',
234 [globalFunctionsAccess, name, elementAccess])); 247 [globalFunctionsAccess, name, elementAccess]));
248 if (info.canTearOff) {
249 String globalName = namer.globalObjectFor(element);
250 statements.add(
251 js.statement(
252 '#.#().# = f',
253 [globalName, info.tearOffName, callNameFor(element)]));
254 }
235 // Create a scope by creating a new function. The updated function literal 255 // Create a scope by creating a new function. The updated function literal
236 // is passed as an argument to this function which ensures that temporary 256 // is passed as an argument to this function which ensures that temporary
237 // names in updateScope don't shadow global names. 257 // names in updateScope don't shadow global names.
238 jsAst.Fun updateScope = js('function (f) { # }', [statements]); 258 jsAst.Fun updateScope = js('function (f) { # }', [statements]);
239 return js.statement('(#)(#)', [updateScope, function]); 259 return js.statement('(#)(#)', [updateScope, function]);
240 } 260 }
241 261
242 String prettyPrintJs(jsAst.Node node) { 262 String prettyPrintJs(jsAst.Node node) {
243 jsAst.Printer printer = new jsAst.Printer(compiler, null); 263 jsAst.Printer printer = new jsAst.Printer(compiler, null);
244 printer.blockOutWithoutBraces(node); 264 printer.blockOutWithoutBraces(node);
245 return printer.outBuffer.getText(); 265 return printer.outBuffer.getText();
246 } 266 }
267
268 String callNameFor(FunctionElement element) {
269 // TODO(ahe): Call a method in the compiler to obtain this name.
270 String callPrefix = namer.callPrefix;
271 int parameterCount = element.functionSignature.parameterCount;
272 return '$callPrefix\$$parameterCount';
273 }
247 } 274 }
248 275
249 /// Represents an update (aka patch) of [before] to [after]. We use the word 276 /// Represents an update (aka patch) of [before] to [after]. We use the word
250 /// "update" to avoid confusion with the compiler feature of "patch" methods. 277 /// "update" to avoid confusion with the compiler feature of "patch" methods.
251 abstract class Update { 278 abstract class Update {
252 final Compiler compiler; 279 final Compiler compiler;
253 280
254 PartialElement get before; 281 PartialElement get before;
255 282
256 PartialElement get after; 283 PartialElement get after;
(...skipping 26 matching lines...) Expand all
283 before.getOrSet = after.getOrSet; 310 before.getOrSet = after.getOrSet;
284 } 311 }
285 312
286 /// Reset various caches and remove this element from the compiler's internal 313 /// Reset various caches and remove this element from the compiler's internal
287 /// state. 314 /// state.
288 void reuseElement() { 315 void reuseElement() {
289 compiler.forgetElement(before); 316 compiler.forgetElement(before);
290 before.reuseElement(); 317 before.reuseElement();
291 } 318 }
292 } 319 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698