| Index: pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
|
| diff --git a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
|
| index d25426ec8756b5e7093ada4bdc9d26106697ad47..00b266dee1b3d241a70ecdc207d8cd5f21ae4855 100644
|
| --- a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
|
| +++ b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
|
| @@ -10,6 +10,7 @@ import '../constants/expressions.dart';
|
| import '../dart_types.dart';
|
| import '../diagnostics/diagnostic_listener.dart';
|
| import '../elements/elements.dart';
|
| +import '../elements/modelx.dart';
|
| import '../parser/parser.dart' show Parser;
|
| import '../parser/listener.dart' show ParserError;
|
| import '../parser/node_listener.dart' show NodeListener;
|
| @@ -19,6 +20,7 @@ import '../resolution/tree_elements.dart';
|
| import '../tree/tree.dart';
|
| import '../tokens/token.dart';
|
| import '../universe/selector.dart';
|
| +import '../util/util.dart';
|
| import 'keys.dart';
|
| import 'serialization.dart';
|
| import 'serialization_util.dart';
|
| @@ -71,6 +73,20 @@ class ResolvedAstSerializer extends Visitor {
|
| Map<Node, int> get nodeIndices => indexComputer.nodeIndices;
|
| List<Node> get nodeList => indexComputer.nodeList;
|
|
|
| + Map<JumpTarget, int> jumpTargetMap = <JumpTarget, int>{};
|
| + Map<LabelDefinition, int> labelDefinitionMap = <LabelDefinition, int>{};
|
| +
|
| + /// Returns the unique id for [jumpTarget], creating it if necessary.
|
| + int getJumpTargetId(JumpTarget jumpTarget) {
|
| + return jumpTargetMap.putIfAbsent(jumpTarget, () => jumpTargetMap.length);
|
| + }
|
| +
|
| + /// Returns the unique id for [labelDefinition], creating it if necessary.
|
| + int getLabelDefinitionId(LabelDefinition labelDefinition) {
|
| + return labelDefinitionMap.putIfAbsent(
|
| + labelDefinition, () => labelDefinitionMap.length);
|
| + }
|
| +
|
| /// Serializes [resolvedAst] into [objectEncoder].
|
| void serialize() {
|
| objectEncoder.setUri(
|
| @@ -113,6 +129,44 @@ class ResolvedAstSerializer extends Visitor {
|
| objectEncoder.setEnum(Key.KIND, kind);
|
| root.accept(indexComputer);
|
| root.accept(this);
|
| + if (jumpTargetMap.isNotEmpty) {
|
| + ListEncoder list = objectEncoder.createList(Key.JUMP_TARGETS);
|
| + for (JumpTarget jumpTarget in jumpTargetMap.keys) {
|
| + serializeJumpTarget(jumpTarget, list.createObject());
|
| + }
|
| + }
|
| + if (labelDefinitionMap.isNotEmpty) {
|
| + ListEncoder list = objectEncoder.createList(Key.LABEL_DEFINITIONS);
|
| + for (LabelDefinition labelDefinition in labelDefinitionMap.keys) {
|
| + serializeLabelDefinition(labelDefinition, list.createObject());
|
| + }
|
| + }
|
| + }
|
| +
|
| + /// Serialize [target] into [encoder].
|
| + void serializeJumpTarget(JumpTarget jumpTarget, ObjectEncoder encoder) {
|
| + encoder.setElement(Key.EXECUTABLE_CONTEXT, jumpTarget.executableContext);
|
| + encoder.setInt(Key.NODE, nodeIndices[jumpTarget.statement]);
|
| + encoder.setInt(Key.NESTING_LEVEL, jumpTarget.nestingLevel);
|
| + encoder.setBool(Key.IS_BREAK_TARGET, jumpTarget.isBreakTarget);
|
| + encoder.setBool(Key.IS_CONTINUE_TARGET, jumpTarget.isContinueTarget);
|
| + if (jumpTarget.labels.isNotEmpty) {
|
| + List<int> labelIdList = <int>[];
|
| + for (LabelDefinition label in jumpTarget.labels) {
|
| + labelIdList.add(getLabelDefinitionId(label));
|
| + }
|
| + encoder.setInts(Key.LABELS, labelIdList);
|
| + }
|
| + }
|
| +
|
| + /// Serialize [label] into [encoder].
|
| + void serializeLabelDefinition(
|
| + LabelDefinition labelDefinition, ObjectEncoder encoder) {
|
| + encoder.setInt(Key.NODE, nodeIndices[labelDefinition.label]);
|
| + encoder.setString(Key.NAME, labelDefinition.labelName);
|
| + encoder.setBool(Key.IS_BREAK_TARGET, labelDefinition.isBreakTarget);
|
| + encoder.setBool(Key.IS_CONTINUE_TARGET, labelDefinition.isContinueTarget);
|
| + encoder.setInt(Key.JUMP_TARGET, getJumpTargetId(labelDefinition.target));
|
| }
|
|
|
| /// Computes the [ListEncoder] for serializing data for nodes.
|
| @@ -162,7 +216,11 @@ class ResolvedAstSerializer extends Visitor {
|
| if (cachedType != null) {
|
| getNodeDataEncoder(node).setType(Key.CACHED_TYPE, cachedType);
|
| }
|
| - // TODO(johnniwinther): Serialize [JumpTarget]s.
|
| + JumpTarget jumpTargetDefinition = elements.getTargetDefinition(node);
|
| + if (jumpTargetDefinition != null) {
|
| + getNodeDataEncoder(node).setInt(
|
| + Key.JUMP_TARGET_DEFINITION, getJumpTargetId(jumpTargetDefinition));
|
| + }
|
| node.visitChildren(this);
|
| }
|
|
|
| @@ -189,13 +247,28 @@ class ResolvedAstSerializer extends Visitor {
|
| @override
|
| visitGotoStatement(GotoStatement node) {
|
| visitStatement(node);
|
| - // TODO(johnniwinther): Serialize [JumpTarget]s and [LabelDefinition]s.
|
| + JumpTarget jumpTarget = elements.getTargetOf(node);
|
| + if (jumpTarget != null) {
|
| + getNodeDataEncoder(node)
|
| + .setInt(Key.JUMP_TARGET, getJumpTargetId(jumpTarget));
|
| + }
|
| + if (node.target != null) {
|
| + LabelDefinition targetLabel = elements.getTargetLabel(node);
|
| + if (targetLabel != null) {
|
| + getNodeDataEncoder(node)
|
| + .setInt(Key.TARGET_LABEL, getLabelDefinitionId(targetLabel));
|
| + }
|
| + }
|
| }
|
|
|
| @override
|
| visitLabel(Label node) {
|
| visitNode(node);
|
| - // TODO(johnniwinther): Serialize[LabelDefinition]s.
|
| + LabelDefinition labelDefinition = elements.getLabelDefinition(node);
|
| + if (labelDefinition != null) {
|
| + getNodeDataEncoder(node)
|
| + .setInt(Key.LABEL_DEFINITION, getLabelDefinitionId(labelDefinition));
|
| + }
|
| }
|
| }
|
|
|
| @@ -373,6 +446,56 @@ class ResolvedAstDeserializer {
|
| Map<Node, int> nodeIndices = indexComputer.nodeIndices;
|
| List<Node> nodeList = indexComputer.nodeList;
|
| root.accept(indexComputer);
|
| +
|
| + List<JumpTarget> jumpTargets = <JumpTarget>[];
|
| + Map<JumpTarget, List<int>> jumpTargetLabels = <JumpTarget, List<int>>{};
|
| + List<LabelDefinition> labelDefinitions = <LabelDefinition>[];
|
| +
|
| + ListDecoder jumpTargetsDecoder =
|
| + objectDecoder.getList(Key.JUMP_TARGETS, isOptional: true);
|
| + if (jumpTargetsDecoder != null) {
|
| + for (int i = 0; i < jumpTargetsDecoder.length; i++) {
|
| + ObjectDecoder decoder = jumpTargetsDecoder.getObject(i);
|
| + ExecutableElement executableContext =
|
| + decoder.getElement(Key.EXECUTABLE_CONTEXT);
|
| + Node statement = nodeList[decoder.getInt(Key.NODE)];
|
| + int nestingLevel = decoder.getInt(Key.NESTING_LEVEL);
|
| + JumpTarget jumpTarget =
|
| + new JumpTargetX(statement, nestingLevel, executableContext);
|
| + jumpTarget.isBreakTarget = decoder.getBool(Key.IS_BREAK_TARGET);
|
| + jumpTarget.isContinueTarget = decoder.getBool(Key.IS_CONTINUE_TARGET);
|
| + jumpTargetLabels[jumpTarget] =
|
| + decoder.getInts(Key.LABELS, isOptional: true);
|
| + jumpTargets.add(jumpTarget);
|
| + }
|
| + }
|
| +
|
| + ListDecoder labelDefinitionsDecoder =
|
| + objectDecoder.getList(Key.LABEL_DEFINITIONS, isOptional: true);
|
| + if (labelDefinitionsDecoder != null) {
|
| + for (int i = 0; i < labelDefinitionsDecoder.length; i++) {
|
| + ObjectDecoder decoder = labelDefinitionsDecoder.getObject(i);
|
| + Label label = nodeList[decoder.getInt(Key.NODE)];
|
| + String labelName = decoder.getString(Key.NAME);
|
| + JumpTarget target = jumpTargets[decoder.getInt(Key.JUMP_TARGET)];
|
| + LabelDefinitionX labelDefinition =
|
| + new LabelDefinitionX(label, labelName, target);
|
| + labelDefinition.isBreakTarget = decoder.getBool(Key.IS_BREAK_TARGET);
|
| + labelDefinition.isContinueTarget =
|
| + decoder.getBool(Key.IS_CONTINUE_TARGET);
|
| + labelDefinitions.add(labelDefinition);
|
| + }
|
| + }
|
| + jumpTargetLabels.forEach((JumpTargetX jumpTarget, List<int> labelIds) {
|
| + if (labelIds.isEmpty) return;
|
| + LinkBuilder<LabelDefinition> linkBuilder =
|
| + new LinkBuilder<LabelDefinition>();
|
| + for (int labelId in labelIds) {
|
| + linkBuilder.addLast(labelDefinitions[labelId]);
|
| + }
|
| + jumpTarget.labels = linkBuilder.toLink();
|
| + });
|
| +
|
| ListDecoder dataDecoder = objectDecoder.getList(Key.DATA);
|
| if (dataDecoder != null) {
|
| for (int i = 0; i < dataDecoder.length; i++) {
|
| @@ -415,6 +538,26 @@ class ResolvedAstDeserializer {
|
| elements.setNewStructure(
|
| node, deserializeNewStructure(newStructureDecoder));
|
| }
|
| + int targetDefinitionId =
|
| + objectDecoder.getInt(Key.JUMP_TARGET_DEFINITION, isOptional: true);
|
| + if (targetDefinitionId != null) {
|
| + elements.defineTarget(node, jumpTargets[targetDefinitionId]);
|
| + }
|
| + int targetOfId =
|
| + objectDecoder.getInt(Key.JUMP_TARGET, isOptional: true);
|
| + if (targetOfId != null) {
|
| + elements.registerTargetOf(node, jumpTargets[targetOfId]);
|
| + }
|
| + int labelDefinitionId =
|
| + objectDecoder.getInt(Key.LABEL_DEFINITION, isOptional: true);
|
| + if (labelDefinitionId != null) {
|
| + elements.defineLabel(node, labelDefinitions[labelDefinitionId]);
|
| + }
|
| + int targetLabelId =
|
| + objectDecoder.getInt(Key.TARGET_LABEL, isOptional: true);
|
| + if (targetLabelId != null) {
|
| + elements.registerTargetLabel(node, labelDefinitions[targetLabelId]);
|
| + }
|
| }
|
| }
|
| return new ResolvedAst(element, root, elements);
|
|
|