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 |
(...skipping 14 matching lines...) Expand all Loading... |
25 PartialElement, | 25 PartialElement, |
26 PartialFunctionElement, | 26 PartialFunctionElement, |
27 Token; | 27 Token; |
28 | 28 |
29 import 'package:compiler/implementation/source_file.dart' show | 29 import 'package:compiler/implementation/source_file.dart' show |
30 StringSourceFile; | 30 StringSourceFile; |
31 | 31 |
32 import 'package:compiler/implementation/tree/tree.dart' show | 32 import 'package:compiler/implementation/tree/tree.dart' show |
33 FunctionExpression; | 33 FunctionExpression; |
34 | 34 |
| 35 import 'package:compiler/implementation/js/js.dart' show |
| 36 js; |
| 37 |
| 38 import 'package:compiler/implementation/js/js.dart' as jsAst; |
| 39 |
| 40 import 'package:compiler/implementation/js_emitter/js_emitter.dart' show |
| 41 ClassBuilder; |
| 42 |
| 43 import 'package:compiler/js_lib/shared/embedded_names.dart' as embeddedNames; |
| 44 |
35 import 'diff.dart' show | 45 import 'diff.dart' show |
36 Difference, | 46 Difference, |
37 computeDifference; | 47 computeDifference; |
38 | 48 |
39 typedef void Logger(message); | 49 typedef void Logger(message); |
40 | 50 |
41 // TODO(ahe): Generalize this class. For now only works for Compiler.mainApp, | 51 // TODO(ahe): Generalize this class. For now only works for Compiler.mainApp, |
42 // and only if that library has exactly one compilation unit. | 52 // and only if that library has exactly one compilation unit. |
43 class LibraryUpdater { | 53 class LibraryUpdater { |
44 final Compiler compiler; | 54 final Compiler compiler; |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 token = token.next; | 178 token = token.next; |
169 } | 179 } |
170 print('Simple modification of ${after} detected'); | 180 print('Simple modification of ${after} detected'); |
171 updates.add(new FunctionUpdate(compiler, before, after)); | 181 updates.add(new FunctionUpdate(compiler, before, after)); |
172 return true; | 182 return true; |
173 } | 183 } |
174 | 184 |
175 List<Element> applyUpdates() { | 185 List<Element> applyUpdates() { |
176 return updates.map((Update update) => update.apply()).toList(); | 186 return updates.map((Update update) => update.apply()).toList(); |
177 } | 187 } |
| 188 |
| 189 String computeUpdateJs() { |
| 190 List<Element> updatedElements = applyUpdates(); |
| 191 compiler.progress.reset(); |
| 192 for (Element element in updatedElements) { |
| 193 compiler.enqueuer.resolution.addToWorkList(element); |
| 194 } |
| 195 compiler.processQueue(compiler.enqueuer.resolution, null); |
| 196 |
| 197 compiler.phase = Compiler.PHASE_DONE_RESOLVING; |
| 198 |
| 199 for (Element element in updatedElements) { |
| 200 compiler.enqueuer.codegen.addToWorkList(element); |
| 201 } |
| 202 compiler.processQueue(compiler.enqueuer.codegen, null); |
| 203 |
| 204 List<jsAst.Statement> updates = <jsAst.Statement>[]; |
| 205 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 206 updates.add(computeMemberUpdateJs(element)); |
| 207 } |
| 208 |
| 209 if (updates.length == 1) { |
| 210 return prettyPrintJs(updates.single); |
| 211 } else { |
| 212 return prettyPrintJs(js.statement('{#}', [updates])); |
| 213 } |
| 214 } |
| 215 |
| 216 jsAst.Node computeMemberUpdateJs(Element element) { |
| 217 ClassBuilder builder = new ClassBuilder(element, compiler.backend.namer); |
| 218 |
| 219 compiler.backend.emitter.oldEmitter.containerBuilder.addMember( |
| 220 element, builder); |
| 221 jsAst.Property property = builder.properties.single; |
| 222 jsAst.Node name = property.name; |
| 223 jsAst.Node function = property.value; |
| 224 jsAst.Node elementAccess = compiler.backend.namer.elementAccess(element); |
| 225 jsAst.Expression globalFunctionsAccess = |
| 226 compiler.backend.emitter.generateEmbeddedGlobalAccess( |
| 227 embeddedNames.GLOBAL_FUNCTIONS); |
| 228 List<jsAst.Statement> statements = <jsAst.Statement>[]; |
| 229 statements.add( |
| 230 js.statement( |
| 231 '#.# = # = f', |
| 232 [globalFunctionsAccess, name, elementAccess])); |
| 233 // Create a scope by creating a new function. The updated function literal |
| 234 // is passed as an argument to this function which ensures that temporary |
| 235 // names in updateScope don't shadow global names. |
| 236 jsAst.Fun updateScope = js('function (f) { # }', [statements]); |
| 237 return js.statement('(#)(#)', [updateScope, function]); |
| 238 } |
| 239 |
| 240 String prettyPrintJs(jsAst.Node node) { |
| 241 jsAst.Printer printer = new jsAst.Printer(compiler, null); |
| 242 printer.blockOutWithoutBraces(node); |
| 243 return printer.outBuffer.getText(); |
| 244 } |
178 } | 245 } |
179 | 246 |
180 /// Represents an update (aka patch) of [before] to [after]. We use the word | 247 /// Represents an update (aka patch) of [before] to [after]. We use the word |
181 /// "update" to avoid confusion with the compiler feature of "patch" methods. | 248 /// "update" to avoid confusion with the compiler feature of "patch" methods. |
182 abstract class Update { | 249 abstract class Update { |
183 final Compiler compiler; | 250 final Compiler compiler; |
184 | 251 |
185 PartialElement get before; | 252 PartialElement get before; |
186 | 253 |
187 PartialElement get after; | 254 PartialElement get after; |
(...skipping 26 matching lines...) Expand all Loading... |
214 before.getOrSet = after.getOrSet; | 281 before.getOrSet = after.getOrSet; |
215 } | 282 } |
216 | 283 |
217 /// Reset various caches and remove this element from the compiler's internal | 284 /// Reset various caches and remove this element from the compiler's internal |
218 /// state. | 285 /// state. |
219 void reuseElement() { | 286 void reuseElement() { |
220 compiler.forgetElement(before); | 287 compiler.forgetElement(before); |
221 before.reuseElement(); | 288 before.reuseElement(); |
222 } | 289 } |
223 } | 290 } |
OLD | NEW |