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 jsAst.Block updates = new jsAst.Block.empty(); | |
205 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | |
206 updates.statements.add(computeMemberUpdateJs(element)); | |
sra1
2014/10/07 18:03:06
Construct ASTs functionally.
Don't modify construc
ahe
2014/10/08 12:09:45
I'm doing something like that.
| |
207 } | |
208 | |
209 if (updates.statements.length == 1) { | |
210 return prettyPrintJs(updates.statements.single); | |
211 } else { | |
212 return prettyPrintJs(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 globalObject = compiler.backend.namer.globalObjectFor(element); | |
225 jsAst.Expression globalFunctionsAccess = | |
226 compiler.backend.emitter.generateEmbeddedGlobalAccess( | |
227 embeddedNames.GLOBAL_FUNCTIONS); | |
228 jsAst.Node updateGlobalFunction = | |
229 js.statement( | |
230 '#.# = #.# = f', [globalFunctionsAccess, name, globalObject, name]); | |
231 // Create a scope by creating a new function. The updated function literal | |
232 // is passed as an argument to this function which ensures that temporary | |
233 // names in updateScope don't shadow global names. | |
floitsch
2014/10/07 15:56:58
The only temporary variable updateScope has is the
ahe
2014/10/07 16:32:40
Yes, but I know I want to add at least one more st
floitsch
2014/10/07 17:48:38
Maybe you could write it with conditions:
if (#) #
sra1
2014/10/07 18:03:06
You can conditionally generate code with templates
ahe
2014/10/08 12:09:45
I think I'll avoid templates with conditionals in
| |
234 jsAst.Fun updateScope = new jsAst.Fun( | |
235 [new jsAst.Parameter('f')], new jsAst.Block.empty()); | |
floitsch
2014/10/07 15:56:58
does the following work?
jsAst.Fun = js('function
ahe
2014/10/07 16:32:40
Yes. But doesn't scale to multiple statements. I
floitsch
2014/10/07 17:48:38
I think you don't even need a block:
js('function
sra1
2014/10/07 18:03:06
It does work, with a minor tweak.
Blocks (and ite
ahe
2014/10/08 12:09:45
That's pretty nifty, but I feel that this is more
| |
236 updateScope.body.statements.add(updateGlobalFunction); | |
sra1
2014/10/07 18:03:06
Ditto: Construct ASTs functionally.
ahe
2014/10/08 12:09:45
I don't know what you mean by that.
| |
237 return js.statement('(#)(#)', [updateScope, function]); | |
238 } | |
239 | |
240 String prettyPrintJs(jsAst.Node node) { | |
241 return jsAst.prettyPrint(node, compiler).getText(); | |
242 } | |
178 } | 243 } |
179 | 244 |
180 /// Represents an update (aka patch) of [before] to [after]. We use the word | 245 /// 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. | 246 /// "update" to avoid confusion with the compiler feature of "patch" methods. |
182 abstract class Update { | 247 abstract class Update { |
183 final Compiler compiler; | 248 final Compiler compiler; |
184 | 249 |
185 PartialElement get before; | 250 PartialElement get before; |
186 | 251 |
187 PartialElement get after; | 252 PartialElement get after; |
(...skipping 26 matching lines...) Expand all Loading... | |
214 before.getOrSet = after.getOrSet; | 279 before.getOrSet = after.getOrSet; |
215 } | 280 } |
216 | 281 |
217 /// Reset various caches and remove this element from the compiler's internal | 282 /// Reset various caches and remove this element from the compiler's internal |
218 /// state. | 283 /// state. |
219 void reuseElement() { | 284 void reuseElement() { |
220 compiler.forgetElement(before); | 285 compiler.forgetElement(before); |
221 before.reuseElement(); | 286 before.reuseElement(); |
222 } | 287 } |
223 } | 288 } |
OLD | NEW |