| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 compiler.internalError(element, '${element.runtimeType}'); |
| 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 Loading... |
| 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 } |
| OLD | NEW |