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 // TODO(johnniwinther): Should we support element->node mapping as well? |
| 174 getNodeDataEncoder(parameterImpl.node) |
| 175 .setElement(PARAMETER_NODE, parameter); |
| 176 if (parameter.initializer != null) { |
| 177 getNodeDataEncoder(parameterImpl.initializer) |
| 178 .setElement(PARAMETER_INITIALIZER, parameter); |
| 179 } |
| 180 }); |
| 181 } |
168 } | 182 } |
169 | 183 |
170 /// Serialize [target] into [encoder]. | 184 /// Serialize [target] into [encoder]. |
171 void serializeJumpTarget(JumpTarget jumpTarget, ObjectEncoder encoder) { | 185 void serializeJumpTarget(JumpTarget jumpTarget, ObjectEncoder encoder) { |
172 encoder.setElement(Key.EXECUTABLE_CONTEXT, jumpTarget.executableContext); | 186 encoder.setElement(Key.EXECUTABLE_CONTEXT, jumpTarget.executableContext); |
173 encoder.setInt(Key.NODE, nodeIndices[jumpTarget.statement]); | 187 encoder.setInt(Key.NODE, nodeIndices[jumpTarget.statement]); |
174 encoder.setInt(Key.NESTING_LEVEL, jumpTarget.nestingLevel); | 188 encoder.setInt(Key.NESTING_LEVEL, jumpTarget.nestingLevel); |
175 encoder.setBool(Key.IS_BREAK_TARGET, jumpTarget.isBreakTarget); | 189 encoder.setBool(Key.IS_BREAK_TARGET, jumpTarget.isBreakTarget); |
176 encoder.setBool(Key.IS_CONTINUE_TARGET, jumpTarget.isContinueTarget); | 190 encoder.setBool(Key.IS_CONTINUE_TARGET, jumpTarget.isContinueTarget); |
177 if (jumpTarget.labels.isNotEmpty) { | 191 if (jumpTarget.labels.isNotEmpty) { |
(...skipping 18 matching lines...) Expand all Loading... |
196 /// Computes the [ListEncoder] for serializing data for nodes. | 210 /// Computes the [ListEncoder] for serializing data for nodes. |
197 ListEncoder get nodeDataEncoder { | 211 ListEncoder get nodeDataEncoder { |
198 if (_nodeDataEncoder == null) { | 212 if (_nodeDataEncoder == null) { |
199 _nodeDataEncoder = objectEncoder.createList(Key.DATA); | 213 _nodeDataEncoder = objectEncoder.createList(Key.DATA); |
200 } | 214 } |
201 return _nodeDataEncoder; | 215 return _nodeDataEncoder; |
202 } | 216 } |
203 | 217 |
204 /// Computes the [ObjectEncoder] for serializing data for [node]. | 218 /// Computes the [ObjectEncoder] for serializing data for [node]. |
205 ObjectEncoder getNodeDataEncoder(Node node) { | 219 ObjectEncoder getNodeDataEncoder(Node node) { |
| 220 assert(invariant(element, node != null, message: "Node must be non-null.")); |
206 int id = nodeIndices[node]; | 221 int id = nodeIndices[node]; |
| 222 assert(invariant(element, id != null, message: "Node without id: $node")); |
207 return nodeData.putIfAbsent(id, () { | 223 return nodeData.putIfAbsent(id, () { |
208 ObjectEncoder objectEncoder = nodeDataEncoder.createObject(); | 224 ObjectEncoder objectEncoder = nodeDataEncoder.createObject(); |
209 objectEncoder.setInt(Key.ID, id); | 225 objectEncoder.setInt(Key.ID, id); |
210 return objectEncoder; | 226 return objectEncoder; |
211 }); | 227 }); |
212 } | 228 } |
213 | 229 |
214 @override | 230 @override |
215 visitNode(Node node) { | 231 visitNode(Node node) { |
216 Element nodeElement = elements[node]; | 232 Element nodeElement = elements[node]; |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 } | 659 } |
644 FunctionElement function = | 660 FunctionElement function = |
645 objectDecoder.getElement(Key.FUNCTION, isOptional: true); | 661 objectDecoder.getElement(Key.FUNCTION, isOptional: true); |
646 if (function != null) { | 662 if (function != null) { |
647 FunctionExpression functionExpression = node; | 663 FunctionExpression functionExpression = node; |
648 assert(invariant(function, !resolvedAstMap.containsKey(function), | 664 assert(invariant(function, !resolvedAstMap.containsKey(function), |
649 message: "ResolvedAst has already been computed for $function.")); | 665 message: "ResolvedAst has already been computed for $function.")); |
650 resolvedAstMap[function] = new ParsedResolvedAst(function, | 666 resolvedAstMap[function] = new ParsedResolvedAst(function, |
651 functionExpression, functionExpression.body, elements, uri); | 667 functionExpression, functionExpression.body, elements, uri); |
652 } | 668 } |
| 669 // TODO(johnniwinther): Remove these when inference doesn't need `.node` |
| 670 // and `.initializer` of [ParameterElement]s. |
| 671 ParameterElementZ parameter = |
| 672 objectDecoder.getElement(PARAMETER_NODE, isOptional: true); |
| 673 if (parameter != null) { |
| 674 parameter.node = node; |
| 675 } |
| 676 parameter = |
| 677 objectDecoder.getElement(PARAMETER_INITIALIZER, isOptional: true); |
| 678 if (parameter != null) { |
| 679 parameter.initializer = node; |
| 680 } |
653 } | 681 } |
654 } | 682 } |
655 assert(invariant(element, !resolvedAstMap.containsKey(element), | 683 assert(invariant(element, !resolvedAstMap.containsKey(element), |
656 message: "ResolvedAst has already been computed for $element.")); | 684 message: "ResolvedAst has already been computed for $element.")); |
657 resolvedAstMap[element] = | 685 resolvedAstMap[element] = |
658 new ParsedResolvedAst(element, root, body, elements, uri); | 686 new ParsedResolvedAst(element, root, body, elements, uri); |
659 } | 687 } |
660 } | 688 } |
| 689 |
| 690 const Key PARAMETER_NODE = const Key('parameter.node'); |
| 691 const Key PARAMETER_INITIALIZER = const Key('parameter.initializer'); |
OLD | NEW |