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'; |
11 import '../diagnostics/diagnostic_listener.dart'; | 11 import '../diagnostics/diagnostic_listener.dart'; |
12 import '../elements/elements.dart'; | 12 import '../elements/elements.dart'; |
13 import '../elements/modelx.dart'; | 13 import '../elements/modelx.dart'; |
14 import '../parser/listener.dart' show ParserError; | 14 import '../parser/listener.dart' show ParserError; |
15 import '../parser/node_listener.dart' show NodeListener; | 15 import '../parser/node_listener.dart' show NodeListener; |
16 import '../parser/parser.dart' show Parser; | 16 import '../parser/parser.dart' show Parser; |
17 import '../resolution/enum_creator.dart'; | 17 import '../resolution/enum_creator.dart'; |
18 import '../resolution/send_structure.dart'; | 18 import '../resolution/send_structure.dart'; |
19 import '../resolution/tree_elements.dart'; | 19 import '../resolution/tree_elements.dart'; |
20 import '../tokens/token.dart'; | 20 import '../tokens/token.dart'; |
21 import '../tree/tree.dart'; | 21 import '../tree/tree.dart'; |
22 import '../universe/selector.dart'; | 22 import '../universe/selector.dart'; |
23 import '../util/util.dart'; | 23 import '../util/util.dart'; |
24 import 'keys.dart'; | 24 import 'keys.dart'; |
25 import 'modelz.dart'; | |
25 import 'serialization.dart'; | 26 import 'serialization.dart'; |
26 import 'serialization_util.dart'; | 27 import 'serialization_util.dart'; |
27 | 28 |
28 /// Visitor that computes a node-index mapping. | 29 /// Visitor that computes a node-index mapping. |
29 class AstIndexComputer extends Visitor { | 30 class AstIndexComputer extends Visitor { |
30 final Map<Node, int> nodeIndices = <Node, int>{}; | 31 final Map<Node, int> nodeIndices = <Node, int>{}; |
31 final List<Node> nodeList = <Node>[]; | 32 final List<Node> nodeList = <Node>[]; |
32 | 33 |
33 @override | 34 @override |
34 visitNode(Node node) { | 35 visitNode(Node node) { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 for (JumpTarget jumpTarget in jumpTargetMap.keys) { | 159 for (JumpTarget jumpTarget in jumpTargetMap.keys) { |
159 serializeJumpTarget(jumpTarget, list.createObject()); | 160 serializeJumpTarget(jumpTarget, list.createObject()); |
160 } | 161 } |
161 } | 162 } |
162 if (labelDefinitionMap.isNotEmpty) { | 163 if (labelDefinitionMap.isNotEmpty) { |
163 ListEncoder list = objectEncoder.createList(Key.LABEL_DEFINITIONS); | 164 ListEncoder list = objectEncoder.createList(Key.LABEL_DEFINITIONS); |
164 for (LabelDefinition labelDefinition in labelDefinitionMap.keys) { | 165 for (LabelDefinition labelDefinition in labelDefinitionMap.keys) { |
165 serializeLabelDefinition(labelDefinition, list.createObject()); | 166 serializeLabelDefinition(labelDefinition, list.createObject()); |
166 } | 167 } |
167 } | 168 } |
169 if (element is FunctionElement) { | |
170 FunctionElement function = element; | |
171 function.functionSignature.forEachParameter((ParameterElement parameter) { | |
172 ParameterElement parameterImpl = parameter.implementation; | |
173 getNodeDataEncoder(parameterImpl.node) | |
174 .setElement(PARAMETER_NODE, parameter); | |
Siggi Cherem (dart-lang)
2016/05/07 01:34:35
interesting --- it feels a bit odd that our storag
Johnni Winther
2016/05/09 08:18:19
Yes, it does feel awkward to map nodes to elements
| |
175 if (parameter.initializer != null) { | |
176 getNodeDataEncoder(parameterImpl.initializer) | |
177 .setElement(PARAMETER_INITIALIZER, parameter); | |
178 } | |
179 }); | |
180 } | |
168 } | 181 } |
169 | 182 |
170 /// Serialize [target] into [encoder]. | 183 /// Serialize [target] into [encoder]. |
171 void serializeJumpTarget(JumpTarget jumpTarget, ObjectEncoder encoder) { | 184 void serializeJumpTarget(JumpTarget jumpTarget, ObjectEncoder encoder) { |
172 encoder.setElement(Key.EXECUTABLE_CONTEXT, jumpTarget.executableContext); | 185 encoder.setElement(Key.EXECUTABLE_CONTEXT, jumpTarget.executableContext); |
173 encoder.setInt(Key.NODE, nodeIndices[jumpTarget.statement]); | 186 encoder.setInt(Key.NODE, nodeIndices[jumpTarget.statement]); |
174 encoder.setInt(Key.NESTING_LEVEL, jumpTarget.nestingLevel); | 187 encoder.setInt(Key.NESTING_LEVEL, jumpTarget.nestingLevel); |
175 encoder.setBool(Key.IS_BREAK_TARGET, jumpTarget.isBreakTarget); | 188 encoder.setBool(Key.IS_BREAK_TARGET, jumpTarget.isBreakTarget); |
176 encoder.setBool(Key.IS_CONTINUE_TARGET, jumpTarget.isContinueTarget); | 189 encoder.setBool(Key.IS_CONTINUE_TARGET, jumpTarget.isContinueTarget); |
177 if (jumpTarget.labels.isNotEmpty) { | 190 if (jumpTarget.labels.isNotEmpty) { |
(...skipping 18 matching lines...) Expand all Loading... | |
196 /// Computes the [ListEncoder] for serializing data for nodes. | 209 /// Computes the [ListEncoder] for serializing data for nodes. |
197 ListEncoder get nodeDataEncoder { | 210 ListEncoder get nodeDataEncoder { |
198 if (_nodeDataEncoder == null) { | 211 if (_nodeDataEncoder == null) { |
199 _nodeDataEncoder = objectEncoder.createList(Key.DATA); | 212 _nodeDataEncoder = objectEncoder.createList(Key.DATA); |
200 } | 213 } |
201 return _nodeDataEncoder; | 214 return _nodeDataEncoder; |
202 } | 215 } |
203 | 216 |
204 /// Computes the [ObjectEncoder] for serializing data for [node]. | 217 /// Computes the [ObjectEncoder] for serializing data for [node]. |
205 ObjectEncoder getNodeDataEncoder(Node node) { | 218 ObjectEncoder getNodeDataEncoder(Node node) { |
219 assert(invariant(element, node != null, message: "Node must be non-null.")); | |
206 int id = nodeIndices[node]; | 220 int id = nodeIndices[node]; |
221 assert(invariant(element, id != null, message: "Node without id: $node")); | |
207 return nodeData.putIfAbsent(id, () { | 222 return nodeData.putIfAbsent(id, () { |
208 ObjectEncoder objectEncoder = nodeDataEncoder.createObject(); | 223 ObjectEncoder objectEncoder = nodeDataEncoder.createObject(); |
209 objectEncoder.setInt(Key.ID, id); | 224 objectEncoder.setInt(Key.ID, id); |
210 return objectEncoder; | 225 return objectEncoder; |
211 }); | 226 }); |
212 } | 227 } |
213 | 228 |
214 @override | 229 @override |
215 visitNode(Node node) { | 230 visitNode(Node node) { |
216 Element nodeElement = elements[node]; | 231 Element nodeElement = elements[node]; |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
643 } | 658 } |
644 FunctionElement function = | 659 FunctionElement function = |
645 objectDecoder.getElement(Key.FUNCTION, isOptional: true); | 660 objectDecoder.getElement(Key.FUNCTION, isOptional: true); |
646 if (function != null) { | 661 if (function != null) { |
647 FunctionExpression functionExpression = node; | 662 FunctionExpression functionExpression = node; |
648 assert(invariant(function, !resolvedAstMap.containsKey(function), | 663 assert(invariant(function, !resolvedAstMap.containsKey(function), |
649 message: "ResolvedAst has already been computed for $function.")); | 664 message: "ResolvedAst has already been computed for $function.")); |
650 resolvedAstMap[function] = new ParsedResolvedAst(function, | 665 resolvedAstMap[function] = new ParsedResolvedAst(function, |
651 functionExpression, functionExpression.body, elements, uri); | 666 functionExpression, functionExpression.body, elements, uri); |
652 } | 667 } |
668 // TODO(johnniwinther): Remove these when inference doesn't need `.node` | |
669 // and `.initializer` of [ParameterElement]s. | |
670 ParameterElementZ parameter = | |
671 objectDecoder.getElement(PARAMETER_NODE, isOptional: true); | |
672 if (parameter != null) { | |
673 parameter.node = node; | |
674 } | |
675 parameter = | |
676 objectDecoder.getElement(PARAMETER_INITIALIZER, isOptional: true); | |
677 if (parameter != null) { | |
678 parameter.initializer = node; | |
679 } | |
653 } | 680 } |
654 } | 681 } |
655 assert(invariant(element, !resolvedAstMap.containsKey(element), | 682 assert(invariant(element, !resolvedAstMap.containsKey(element), |
656 message: "ResolvedAst has already been computed for $element.")); | 683 message: "ResolvedAst has already been computed for $element.")); |
657 resolvedAstMap[element] = | 684 resolvedAstMap[element] = |
658 new ParsedResolvedAst(element, root, body, elements, uri); | 685 new ParsedResolvedAst(element, root, body, elements, uri); |
659 } | 686 } |
660 } | 687 } |
688 | |
689 const Key PARAMETER_NODE = const Key('parameter.node'); | |
690 const Key PARAMETER_INITIALIZER = const Key('parameter.initializer'); | |
OLD | NEW |