OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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.serialization.resolved_ast; | 5 library dart2js.serialization.resolved_ast; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/resolution.dart'; | 8 import '../common/resolution.dart'; |
9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 | 287 |
288 @override | 288 @override |
289 visitLabel(Label node) { | 289 visitLabel(Label node) { |
290 visitNode(node); | 290 visitNode(node); |
291 LabelDefinition labelDefinition = elements.getLabelDefinition(node); | 291 LabelDefinition labelDefinition = elements.getLabelDefinition(node); |
292 if (labelDefinition != null) { | 292 if (labelDefinition != null) { |
293 getNodeDataEncoder(node) | 293 getNodeDataEncoder(node) |
294 .setInt(Key.LABEL_DEFINITION, getLabelDefinitionId(labelDefinition)); | 294 .setInt(Key.LABEL_DEFINITION, getLabelDefinitionId(labelDefinition)); |
295 } | 295 } |
296 } | 296 } |
| 297 |
| 298 @override |
| 299 visitFunctionExpression(FunctionExpression node) { |
| 300 visitExpression(node); |
| 301 Element function = elements.getFunctionDefinition(node); |
| 302 if (function != null && function.isFunction && function.isLocal) { |
| 303 // Mark root nodes of local functions; these need their own ResolvedAst. |
| 304 getNodeDataEncoder(node).setElement(Key.FUNCTION, function); |
| 305 } |
| 306 } |
297 } | 307 } |
298 | 308 |
299 class ResolvedAstDeserializer { | 309 class ResolvedAstDeserializer { |
300 /// Find the [Token] at [offset] searching through successors of [token]. | 310 /// Find the [Token] at [offset] searching through successors of [token]. |
301 static Token findTokenInStream(Token token, int offset) { | 311 static Token findTokenInStream(Token token, int offset) { |
302 while (token.charOffset <= offset && token.next != token) { | 312 while (token.charOffset <= offset && token.next != token) { |
303 if (token.charOffset == offset) { | 313 if (token.charOffset == offset) { |
304 return token; | 314 return token; |
305 } | 315 } |
306 token = token.next; | 316 token = token.next; |
307 } | 317 } |
308 return null; | 318 return null; |
309 } | 319 } |
310 | 320 |
311 /// Deserializes the [ResolvedAst] for [element] from [objectDecoder]. | 321 /// Deserializes the [ResolvedAst]s for [element] and its nested local |
| 322 /// functions from [objectDecoder] and adds these to [resolvedAstMap]. |
312 /// [parsing] and [getBeginToken] are used for parsing the [Node] for | 323 /// [parsing] and [getBeginToken] are used for parsing the [Node] for |
313 /// [element] from its source code. | 324 /// [element] from its source code. |
314 static ResolvedAst deserialize( | 325 static void deserialize( |
315 Element element, | 326 Element element, |
316 ObjectDecoder objectDecoder, | 327 ObjectDecoder objectDecoder, |
317 ParsingContext parsing, | 328 ParsingContext parsing, |
318 Token getBeginToken(Uri uri, int charOffset), | 329 Token getBeginToken(Uri uri, int charOffset), |
319 DeserializerPlugin nativeDataDeserializer) { | 330 DeserializerPlugin nativeDataDeserializer, |
| 331 Map<Element, ResolvedAst> resolvedAstMap) { |
320 ResolvedAstKind kind = | 332 ResolvedAstKind kind = |
321 objectDecoder.getEnum(Key.KIND, ResolvedAstKind.values); | 333 objectDecoder.getEnum(Key.KIND, ResolvedAstKind.values); |
322 switch (kind) { | 334 switch (kind) { |
323 case ResolvedAstKind.PARSED: | 335 case ResolvedAstKind.PARSED: |
324 return deserializeParsed(element, objectDecoder, parsing, getBeginToken, | 336 deserializeParsed(element, objectDecoder, parsing, getBeginToken, |
325 nativeDataDeserializer); | 337 nativeDataDeserializer, resolvedAstMap); |
| 338 break; |
326 case ResolvedAstKind.DEFAULT_CONSTRUCTOR: | 339 case ResolvedAstKind.DEFAULT_CONSTRUCTOR: |
327 case ResolvedAstKind.FORWARDING_CONSTRUCTOR: | 340 case ResolvedAstKind.FORWARDING_CONSTRUCTOR: |
328 return new SynthesizedResolvedAst(element, kind); | 341 resolvedAstMap[element] = new SynthesizedResolvedAst(element, kind); |
| 342 break; |
329 } | 343 } |
330 } | 344 } |
331 | 345 |
332 /// Deserialize a [ResolvedAst] that is defined in terms of an AST together | 346 /// Deserialize the [ResolvedAst]s for the member [element] (constructor, |
333 /// with [TreeElements]. | 347 /// method, or field) and its nested closures. The [ResolvedAst]s are added |
334 static ResolvedAst deserializeParsed( | 348 /// to [resolvedAstMap]. |
| 349 static void deserializeParsed( |
335 Element element, | 350 Element element, |
336 ObjectDecoder objectDecoder, | 351 ObjectDecoder objectDecoder, |
337 ParsingContext parsing, | 352 ParsingContext parsing, |
338 Token getBeginToken(Uri uri, int charOffset), | 353 Token getBeginToken(Uri uri, int charOffset), |
339 DeserializerPlugin nativeDataDeserializer) { | 354 DeserializerPlugin nativeDataDeserializer, |
| 355 Map<Element, ResolvedAst> resolvedAstMap) { |
340 CompilationUnitElement compilationUnit = element.compilationUnit; | 356 CompilationUnitElement compilationUnit = element.compilationUnit; |
341 DiagnosticReporter reporter = parsing.reporter; | 357 DiagnosticReporter reporter = parsing.reporter; |
342 | 358 |
343 /// Returns the first [Token] for parsing the [Node] for [element]. | 359 /// Returns the first [Token] for parsing the [Node] for [element]. |
344 Token readBeginToken() { | 360 Token readBeginToken() { |
345 Uri uri = objectDecoder.getUri(Key.URI); | 361 Uri uri = objectDecoder.getUri(Key.URI); |
346 int charOffset = objectDecoder.getInt(Key.OFFSET); | 362 int charOffset = objectDecoder.getInt(Key.OFFSET); |
347 Token beginToken = getBeginToken(uri, charOffset); | 363 Token beginToken = getBeginToken(uri, charOffset); |
348 if (beginToken == null) { | 364 if (beginToken == null) { |
349 reporter.internalError( | 365 reporter.internalError( |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 jumpTargetLabels.forEach((JumpTargetX jumpTarget, List<int> labelIds) { | 561 jumpTargetLabels.forEach((JumpTargetX jumpTarget, List<int> labelIds) { |
546 if (labelIds.isEmpty) return; | 562 if (labelIds.isEmpty) return; |
547 LinkBuilder<LabelDefinition> linkBuilder = | 563 LinkBuilder<LabelDefinition> linkBuilder = |
548 new LinkBuilder<LabelDefinition>(); | 564 new LinkBuilder<LabelDefinition>(); |
549 for (int labelId in labelIds) { | 565 for (int labelId in labelIds) { |
550 linkBuilder.addLast(labelDefinitions[labelId]); | 566 linkBuilder.addLast(labelDefinitions[labelId]); |
551 } | 567 } |
552 jumpTarget.labels = linkBuilder.toLink(); | 568 jumpTarget.labels = linkBuilder.toLink(); |
553 }); | 569 }); |
554 | 570 |
555 ListDecoder dataDecoder = objectDecoder.getList(Key.DATA); | 571 ListDecoder dataDecoder = objectDecoder.getList(Key.DATA, isOptional: true); |
556 if (dataDecoder != null) { | 572 if (dataDecoder != null) { |
557 for (int i = 0; i < dataDecoder.length; i++) { | 573 for (int i = 0; i < dataDecoder.length; i++) { |
558 ObjectDecoder objectDecoder = dataDecoder.getObject(i); | 574 ObjectDecoder objectDecoder = dataDecoder.getObject(i); |
559 int id = objectDecoder.getInt(Key.ID); | 575 int id = objectDecoder.getInt(Key.ID); |
560 Node node = nodeList[id]; | 576 Node node = nodeList[id]; |
561 Element nodeElement = deserializeElementReference( | 577 Element nodeElement = deserializeElementReference( |
562 element, Key.ELEMENT, Key.NAME, objectDecoder, | 578 element, Key.ELEMENT, Key.NAME, objectDecoder, |
563 isOptional: true); | 579 isOptional: true); |
564 if (nodeElement != null) { | 580 if (nodeElement != null) { |
565 elements[node] = nodeElement; | 581 elements[node] = nodeElement; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 elements.registerTargetLabel(node, labelDefinitions[targetLabelId]); | 632 elements.registerTargetLabel(node, labelDefinitions[targetLabelId]); |
617 } | 633 } |
618 ObjectDecoder nativeDataDecoder = | 634 ObjectDecoder nativeDataDecoder = |
619 objectDecoder.getObject(Key.NATIVE, isOptional: true); | 635 objectDecoder.getObject(Key.NATIVE, isOptional: true); |
620 if (nativeDataDecoder != null) { | 636 if (nativeDataDecoder != null) { |
621 var nativeData = nativeDataDeserializer.onData(nativeDataDecoder); | 637 var nativeData = nativeDataDeserializer.onData(nativeDataDecoder); |
622 if (nativeData != null) { | 638 if (nativeData != null) { |
623 elements.registerNativeData(node, nativeData); | 639 elements.registerNativeData(node, nativeData); |
624 } | 640 } |
625 } | 641 } |
| 642 FunctionElement function = |
| 643 objectDecoder.getElement(Key.FUNCTION, isOptional: true); |
| 644 if (function != null) { |
| 645 FunctionExpression functionExpression = node; |
| 646 assert(invariant(function, !resolvedAstMap.containsKey(function), |
| 647 message: "ResolvedAst has already been computed for $function.")); |
| 648 resolvedAstMap[function] = new ParsedResolvedAst( |
| 649 function, functionExpression, functionExpression.body, elements); |
| 650 } |
626 } | 651 } |
627 } | 652 } |
628 return new ParsedResolvedAst(element, root, body, elements); | 653 assert(invariant(element, !resolvedAstMap.containsKey(element), |
| 654 message: "ResolvedAst has already been computed for $element.")); |
| 655 resolvedAstMap[element] = |
| 656 new ParsedResolvedAst(element, root, body, elements); |
629 } | 657 } |
630 } | 658 } |
OLD | NEW |