929d5e4a98
This CL is the sum of the following 5 CLs: * https://dart-review.googlesource.com/c/sdk/+/149297/ * https://dart-review.googlesource.com/c/sdk/+/149299/ * https://dart-review.googlesource.com/c/sdk/+/149320/ * https://dart-review.googlesource.com/c/sdk/+/149321/ * https://dart-review.googlesource.com/c/sdk/+/149323/ The reason for landing the 5 CLs as one CL is to prevent potential troubles with bisecting over the branch because the change is fully functional only with all 5 CLs. Closes #40123. Bug: https://github.com/dart-lang/sdk/issues/40123 Change-Id: Ice52250a98acfe455b1d7fa5bb0624c115ca5dac Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150934 Commit-Queue: Dmitry Stefantsov <dmitryas@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
1626 lines
57 KiB
Dart
1626 lines
57 KiB
Dart
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
library kernel.text_serializer;
|
|
|
|
import '../ast.dart';
|
|
|
|
import 'serializer_combinators.dart';
|
|
|
|
import '../visitor.dart' show ExpressionVisitor;
|
|
|
|
abstract class Tagger<T extends Node> {
|
|
String tag(T node);
|
|
}
|
|
|
|
class NameTagger implements Tagger<Name> {
|
|
const NameTagger();
|
|
|
|
String tag(Name name) => name.isPrivate ? "private" : "public";
|
|
}
|
|
|
|
const TextSerializer<Name> publicName =
|
|
const Wrapped(unwrapPublicName, wrapPublicName, const DartString());
|
|
|
|
String unwrapPublicName(Name name) => name.name;
|
|
|
|
Name wrapPublicName(String name) => new Name(name);
|
|
|
|
const TextSerializer<Name> privateName = const Wrapped(unwrapPrivateName,
|
|
wrapPrivateName, Tuple2Serializer(const DartString(), const DartString()));
|
|
|
|
Tuple2<String, String> unwrapPrivateName(Name name) {
|
|
return new Tuple2(name.library.importUri.toString(), name.name);
|
|
}
|
|
|
|
Name wrapPrivateName(Tuple2<String, String> tuple) {
|
|
// We need a map from import URI to libraries. More generally, we will need
|
|
// a way to map any 'named' node to the node's reference.
|
|
throw UnimplementedError('Deserialization of private names.');
|
|
}
|
|
|
|
TextSerializer<Name> nameSerializer = new Case(
|
|
const NameTagger(), {"public": publicName, "private": privateName});
|
|
|
|
class ExpressionTagger extends ExpressionVisitor<String>
|
|
implements Tagger<Expression> {
|
|
const ExpressionTagger();
|
|
|
|
String tag(Expression expression) => expression.accept(this);
|
|
|
|
String visitStringLiteral(StringLiteral _) => "string";
|
|
String visitIntLiteral(IntLiteral _) => "int";
|
|
String visitDoubleLiteral(DoubleLiteral _) => "double";
|
|
String visitBoolLiteral(BoolLiteral _) => "bool";
|
|
String visitNullLiteral(NullLiteral _) => "null";
|
|
String visitInvalidExpression(InvalidExpression _) => "invalid";
|
|
String visitNot(Not _) => "not";
|
|
String visitLogicalExpression(LogicalExpression expression) {
|
|
return expression.operator;
|
|
}
|
|
|
|
String visitStringConcatenation(StringConcatenation _) => "concat";
|
|
String visitSymbolLiteral(SymbolLiteral _) => "symbol";
|
|
String visitThisExpression(ThisExpression _) => "this";
|
|
String visitRethrow(Rethrow _) => "rethrow";
|
|
String visitThrow(Throw _) => "throw";
|
|
String visitAwaitExpression(AwaitExpression _) => "await";
|
|
String visitConditionalExpression(ConditionalExpression _) => "cond";
|
|
String visitIsExpression(IsExpression _) => "is";
|
|
String visitAsExpression(AsExpression _) => "as";
|
|
String visitTypeLiteral(TypeLiteral _) => "type";
|
|
String visitListLiteral(ListLiteral expression) {
|
|
return expression.isConst ? "const-list" : "list";
|
|
}
|
|
|
|
String visitSetLiteral(SetLiteral expression) {
|
|
return expression.isConst ? "const-set" : "set";
|
|
}
|
|
|
|
String visitMapLiteral(MapLiteral expression) {
|
|
return expression.isConst ? "const-map" : "map";
|
|
}
|
|
|
|
String visitLet(Let _) => "let";
|
|
|
|
String visitPropertyGet(PropertyGet _) => "get-prop";
|
|
String visitPropertySet(PropertySet _) => "set-prop";
|
|
String visitSuperPropertyGet(SuperPropertyGet _) => "get-super";
|
|
String visitSuperPropertySet(SuperPropertySet _) => "set-super";
|
|
String visitMethodInvocation(MethodInvocation _) => "invoke-method";
|
|
String visitSuperMethodInvocation(SuperMethodInvocation _) => "invoke-super";
|
|
|
|
String visitVariableGet(VariableGet _) => "get-var";
|
|
String visitVariableSet(VariableSet _) => "set-var";
|
|
String visitStaticGet(StaticGet _) => "get-static";
|
|
String visitStaticSet(StaticSet _) => "set-static";
|
|
String visitDirectPropertyGet(DirectPropertyGet _) => "get-direct-prop";
|
|
String visitDirectPropertySet(DirectPropertySet _) => "set-direct-prop";
|
|
String visitStaticInvocation(StaticInvocation expression) {
|
|
return expression.isConst ? "invoke-const-static" : "invoke-static";
|
|
}
|
|
|
|
String visitDirectMethodInvocation(DirectMethodInvocation _) {
|
|
return "invoke-direct-method";
|
|
}
|
|
|
|
String visitConstructorInvocation(ConstructorInvocation expression) {
|
|
return expression.isConst
|
|
? "invoke-const-constructor"
|
|
: "invoke-constructor";
|
|
}
|
|
|
|
String visitFunctionExpression(FunctionExpression _) => "fun";
|
|
}
|
|
|
|
const TextSerializer<InvalidExpression> invalidExpressionSerializer =
|
|
const Wrapped(
|
|
unwrapInvalidExpression, wrapInvalidExpression, const DartString());
|
|
|
|
String unwrapInvalidExpression(InvalidExpression expression) {
|
|
return expression.message;
|
|
}
|
|
|
|
InvalidExpression wrapInvalidExpression(String message) {
|
|
return new InvalidExpression(message);
|
|
}
|
|
|
|
TextSerializer<Not> notSerializer =
|
|
new Wrapped(unwrapNot, wrapNot, expressionSerializer);
|
|
|
|
Expression unwrapNot(Not expression) => expression.operand;
|
|
|
|
Not wrapNot(Expression operand) => new Not(operand);
|
|
|
|
TextSerializer<LogicalExpression> logicalAndSerializer = new Wrapped(
|
|
unwrapLogicalExpression,
|
|
wrapLogicalAnd,
|
|
new Tuple2Serializer(expressionSerializer, expressionSerializer));
|
|
|
|
Tuple2<Expression, Expression> unwrapLogicalExpression(
|
|
LogicalExpression expression) {
|
|
return new Tuple2(expression.left, expression.right);
|
|
}
|
|
|
|
LogicalExpression wrapLogicalAnd(Tuple2<Expression, Expression> tuple) {
|
|
return new LogicalExpression(tuple.first, '&&', tuple.second);
|
|
}
|
|
|
|
TextSerializer<LogicalExpression> logicalOrSerializer = new Wrapped(
|
|
unwrapLogicalExpression,
|
|
wrapLogicalOr,
|
|
new Tuple2Serializer(expressionSerializer, expressionSerializer));
|
|
|
|
LogicalExpression wrapLogicalOr(Tuple2<Expression, Expression> tuple) {
|
|
return new LogicalExpression(tuple.first, '||', tuple.second);
|
|
}
|
|
|
|
TextSerializer<StringConcatenation> stringConcatenationSerializer = new Wrapped(
|
|
unwrapStringConcatenation,
|
|
wrapStringConcatenation,
|
|
new ListSerializer(expressionSerializer));
|
|
|
|
List<Expression> unwrapStringConcatenation(StringConcatenation expression) {
|
|
return expression.expressions;
|
|
}
|
|
|
|
StringConcatenation wrapStringConcatenation(List<Expression> expressions) {
|
|
return new StringConcatenation(expressions);
|
|
}
|
|
|
|
const TextSerializer<StringLiteral> stringLiteralSerializer =
|
|
const Wrapped(unwrapStringLiteral, wrapStringLiteral, const DartString());
|
|
|
|
String unwrapStringLiteral(StringLiteral literal) => literal.value;
|
|
|
|
StringLiteral wrapStringLiteral(String value) => new StringLiteral(value);
|
|
|
|
const TextSerializer<IntLiteral> intLiteralSerializer =
|
|
const Wrapped(unwrapIntLiteral, wrapIntLiteral, const DartInt());
|
|
|
|
int unwrapIntLiteral(IntLiteral literal) => literal.value;
|
|
|
|
IntLiteral wrapIntLiteral(int value) => new IntLiteral(value);
|
|
|
|
const TextSerializer<DoubleLiteral> doubleLiteralSerializer =
|
|
const Wrapped(unwrapDoubleLiteral, wrapDoubleLiteral, const DartDouble());
|
|
|
|
double unwrapDoubleLiteral(DoubleLiteral literal) => literal.value;
|
|
|
|
DoubleLiteral wrapDoubleLiteral(double value) => new DoubleLiteral(value);
|
|
|
|
const TextSerializer<BoolLiteral> boolLiteralSerializer =
|
|
const Wrapped(unwrapBoolLiteral, wrapBoolLiteral, const DartBool());
|
|
|
|
bool unwrapBoolLiteral(BoolLiteral literal) => literal.value;
|
|
|
|
BoolLiteral wrapBoolLiteral(bool value) => new BoolLiteral(value);
|
|
|
|
const TextSerializer<NullLiteral> nullLiteralSerializer =
|
|
const Wrapped(unwrapNullLiteral, wrapNullLiteral, const Nothing());
|
|
|
|
void unwrapNullLiteral(NullLiteral literal) {}
|
|
|
|
NullLiteral wrapNullLiteral(void ignored) => new NullLiteral();
|
|
|
|
const TextSerializer<SymbolLiteral> symbolLiteralSerializer =
|
|
const Wrapped(unwrapSymbolLiteral, wrapSymbolLiteral, const DartString());
|
|
|
|
String unwrapSymbolLiteral(SymbolLiteral expression) => expression.value;
|
|
|
|
SymbolLiteral wrapSymbolLiteral(String value) => new SymbolLiteral(value);
|
|
|
|
const TextSerializer<ThisExpression> thisExpressionSerializer =
|
|
const Wrapped(unwrapThisExpression, wrapThisExpression, const Nothing());
|
|
|
|
void unwrapThisExpression(ThisExpression expression) {}
|
|
|
|
ThisExpression wrapThisExpression(void ignored) => new ThisExpression();
|
|
|
|
const TextSerializer<Rethrow> rethrowSerializer =
|
|
const Wrapped(unwrapRethrow, wrapRethrow, const Nothing());
|
|
|
|
void unwrapRethrow(Rethrow expression) {}
|
|
|
|
Rethrow wrapRethrow(void ignored) => new Rethrow();
|
|
|
|
TextSerializer<Throw> throwSerializer =
|
|
new Wrapped(unwrapThrow, wrapThrow, expressionSerializer);
|
|
|
|
Expression unwrapThrow(Throw expression) => expression.expression;
|
|
|
|
Throw wrapThrow(Expression expression) => new Throw(expression);
|
|
|
|
TextSerializer<AwaitExpression> awaitExpressionSerializer = new Wrapped(
|
|
unwrapAwaitExpression, wrapAwaitExpression, expressionSerializer);
|
|
|
|
Expression unwrapAwaitExpression(AwaitExpression expression) =>
|
|
expression.operand;
|
|
|
|
AwaitExpression wrapAwaitExpression(Expression operand) =>
|
|
new AwaitExpression(operand);
|
|
|
|
TextSerializer<ConditionalExpression> conditionalExpressionSerializer =
|
|
new Wrapped(
|
|
unwrapConditionalExpression,
|
|
wrapConditionalExpression,
|
|
new Tuple4Serializer(expressionSerializer, dartTypeSerializer,
|
|
expressionSerializer, expressionSerializer));
|
|
|
|
Tuple4<Expression, DartType, Expression, Expression>
|
|
unwrapConditionalExpression(ConditionalExpression expression) {
|
|
return new Tuple4(expression.condition, expression.staticType,
|
|
expression.then, expression.otherwise);
|
|
}
|
|
|
|
ConditionalExpression wrapConditionalExpression(
|
|
Tuple4<Expression, DartType, Expression, Expression> tuple) {
|
|
return new ConditionalExpression(
|
|
tuple.first, tuple.third, tuple.fourth, tuple.second);
|
|
}
|
|
|
|
TextSerializer<IsExpression> isExpressionSerializer = new Wrapped(
|
|
unwrapIsExpression,
|
|
wrapIsExpression,
|
|
new Tuple2Serializer(expressionSerializer, dartTypeSerializer));
|
|
|
|
Tuple2<Expression, DartType> unwrapIsExpression(IsExpression expression) {
|
|
return new Tuple2(expression.operand, expression.type);
|
|
}
|
|
|
|
IsExpression wrapIsExpression(Tuple2<Expression, DartType> tuple) {
|
|
return new IsExpression(tuple.first, tuple.second);
|
|
}
|
|
|
|
TextSerializer<AsExpression> asExpressionSerializer = new Wrapped(
|
|
unwrapAsExpression,
|
|
wrapAsExpression,
|
|
new Tuple2Serializer(expressionSerializer, dartTypeSerializer));
|
|
|
|
Tuple2<Expression, DartType> unwrapAsExpression(AsExpression expression) {
|
|
return new Tuple2(expression.operand, expression.type);
|
|
}
|
|
|
|
AsExpression wrapAsExpression(Tuple2<Expression, DartType> tuple) {
|
|
return new AsExpression(tuple.first, tuple.second);
|
|
}
|
|
|
|
TextSerializer<TypeLiteral> typeLiteralSerializer =
|
|
new Wrapped(unwrapTypeLiteral, wrapTypeLiteral, dartTypeSerializer);
|
|
|
|
DartType unwrapTypeLiteral(TypeLiteral expression) => expression.type;
|
|
|
|
TypeLiteral wrapTypeLiteral(DartType type) => new TypeLiteral(type);
|
|
|
|
TextSerializer<ListLiteral> listLiteralSerializer = new Wrapped(
|
|
unwrapListLiteral,
|
|
wrapListLiteral,
|
|
new Tuple2Serializer(
|
|
dartTypeSerializer, new ListSerializer(expressionSerializer)));
|
|
|
|
Tuple2<DartType, List<Expression>> unwrapListLiteral(ListLiteral expression) {
|
|
return new Tuple2(expression.typeArgument, expression.expressions);
|
|
}
|
|
|
|
ListLiteral wrapListLiteral(Tuple2<DartType, List<Expression>> tuple) {
|
|
return new ListLiteral(tuple.second,
|
|
typeArgument: tuple.first, isConst: false);
|
|
}
|
|
|
|
TextSerializer<ListLiteral> constListLiteralSerializer = new Wrapped(
|
|
unwrapListLiteral,
|
|
wrapConstListLiteral,
|
|
new Tuple2Serializer(
|
|
dartTypeSerializer, new ListSerializer(expressionSerializer)));
|
|
|
|
ListLiteral wrapConstListLiteral(Tuple2<DartType, List<Expression>> tuple) {
|
|
return new ListLiteral(tuple.second,
|
|
typeArgument: tuple.first, isConst: true);
|
|
}
|
|
|
|
TextSerializer<SetLiteral> setLiteralSerializer = new Wrapped(
|
|
unwrapSetLiteral,
|
|
wrapSetLiteral,
|
|
new Tuple2Serializer(
|
|
dartTypeSerializer, new ListSerializer(expressionSerializer)));
|
|
|
|
Tuple2<DartType, List<Expression>> unwrapSetLiteral(SetLiteral expression) {
|
|
return new Tuple2(expression.typeArgument, expression.expressions);
|
|
}
|
|
|
|
SetLiteral wrapSetLiteral(Tuple2<DartType, List<Expression>> tuple) {
|
|
return new SetLiteral(tuple.second,
|
|
typeArgument: tuple.first, isConst: false);
|
|
}
|
|
|
|
TextSerializer<SetLiteral> constSetLiteralSerializer = new Wrapped(
|
|
unwrapSetLiteral,
|
|
wrapConstSetLiteral,
|
|
new Tuple2Serializer(
|
|
dartTypeSerializer, new ListSerializer(expressionSerializer)));
|
|
|
|
SetLiteral wrapConstSetLiteral(Tuple2<DartType, List<Expression>> tuple) {
|
|
return new SetLiteral(tuple.second, typeArgument: tuple.first, isConst: true);
|
|
}
|
|
|
|
TextSerializer<MapLiteral> mapLiteralSerializer = new Wrapped(
|
|
unwrapMapLiteral,
|
|
wrapMapLiteral,
|
|
new Tuple3Serializer(dartTypeSerializer, dartTypeSerializer,
|
|
new ListSerializer(expressionSerializer)));
|
|
|
|
Tuple3<DartType, DartType, List<Expression>> unwrapMapLiteral(
|
|
MapLiteral expression) {
|
|
List<Expression> entries = new List(2 * expression.entries.length);
|
|
for (int from = 0, to = 0; from < expression.entries.length; ++from) {
|
|
MapEntry entry = expression.entries[from];
|
|
entries[to++] = entry.key;
|
|
entries[to++] = entry.value;
|
|
}
|
|
return new Tuple3(expression.keyType, expression.valueType, entries);
|
|
}
|
|
|
|
MapLiteral wrapMapLiteral(Tuple3<DartType, DartType, List<Expression>> tuple) {
|
|
List<MapEntry> entries = new List(tuple.third.length ~/ 2);
|
|
for (int from = 0, to = 0; to < entries.length; ++to) {
|
|
entries[to] = new MapEntry(tuple.third[from++], tuple.third[from++]);
|
|
}
|
|
return new MapLiteral(entries,
|
|
keyType: tuple.first, valueType: tuple.second, isConst: false);
|
|
}
|
|
|
|
TextSerializer<MapLiteral> constMapLiteralSerializer = new Wrapped(
|
|
unwrapMapLiteral,
|
|
wrapConstMapLiteral,
|
|
new Tuple3Serializer(dartTypeSerializer, dartTypeSerializer,
|
|
new ListSerializer(expressionSerializer)));
|
|
|
|
MapLiteral wrapConstMapLiteral(
|
|
Tuple3<DartType, DartType, List<Expression>> tuple) {
|
|
List<MapEntry> entries = new List(tuple.third.length ~/ 2);
|
|
for (int from = 0, to = 0; to < entries.length; ++to) {
|
|
entries[to] = new MapEntry(tuple.third[from++], tuple.third[from++]);
|
|
}
|
|
return new MapLiteral(entries,
|
|
keyType: tuple.first, valueType: tuple.second, isConst: true);
|
|
}
|
|
|
|
TextSerializer<Let> letSerializer = new Wrapped(unwrapLet, wrapLet,
|
|
new Bind(variableDeclarationSerializer, expressionSerializer));
|
|
|
|
Tuple2<VariableDeclaration, Expression> unwrapLet(Let expression) {
|
|
return new Tuple2(expression.variable, expression.body);
|
|
}
|
|
|
|
Let wrapLet(Tuple2<VariableDeclaration, Expression> tuple) {
|
|
return new Let(tuple.first, tuple.second);
|
|
}
|
|
|
|
String getVariableDeclarationName(VariableDeclaration node) => node.name;
|
|
|
|
void setVariableDeclarationName(VariableDeclaration node, String name) {
|
|
node.name = name;
|
|
}
|
|
|
|
TextSerializer<PropertyGet> propertyGetSerializer = new Wrapped(
|
|
unwrapPropertyGet,
|
|
wrapPropertyGet,
|
|
new Tuple2Serializer(expressionSerializer, nameSerializer));
|
|
|
|
Tuple2<Expression, Name> unwrapPropertyGet(PropertyGet expression) {
|
|
return new Tuple2(expression.receiver, expression.name);
|
|
}
|
|
|
|
PropertyGet wrapPropertyGet(Tuple2<Expression, Name> tuple) {
|
|
return new PropertyGet(tuple.first, tuple.second);
|
|
}
|
|
|
|
TextSerializer<PropertySet> propertySetSerializer = new Wrapped(
|
|
unwrapPropertySet,
|
|
wrapPropertySet,
|
|
new Tuple3Serializer(
|
|
expressionSerializer, nameSerializer, expressionSerializer));
|
|
|
|
Tuple3<Expression, Name, Expression> unwrapPropertySet(PropertySet expression) {
|
|
return new Tuple3(expression.receiver, expression.name, expression.value);
|
|
}
|
|
|
|
PropertySet wrapPropertySet(Tuple3<Expression, Name, Expression> tuple) {
|
|
return new PropertySet(tuple.first, tuple.second, tuple.third);
|
|
}
|
|
|
|
TextSerializer<SuperPropertyGet> superPropertyGetSerializer =
|
|
new Wrapped(unwrapSuperPropertyGet, wrapSuperPropertyGet, nameSerializer);
|
|
|
|
Name unwrapSuperPropertyGet(SuperPropertyGet expression) {
|
|
return expression.name;
|
|
}
|
|
|
|
SuperPropertyGet wrapSuperPropertyGet(Name name) {
|
|
return new SuperPropertyGet(name);
|
|
}
|
|
|
|
TextSerializer<SuperPropertySet> superPropertySetSerializer = new Wrapped(
|
|
unwrapSuperPropertySet,
|
|
wrapSuperPropertySet,
|
|
new Tuple2Serializer(nameSerializer, expressionSerializer));
|
|
|
|
Tuple2<Name, Expression> unwrapSuperPropertySet(SuperPropertySet expression) {
|
|
return new Tuple2(expression.name, expression.value);
|
|
}
|
|
|
|
SuperPropertySet wrapSuperPropertySet(Tuple2<Name, Expression> tuple) {
|
|
return new SuperPropertySet(tuple.first, tuple.second, null);
|
|
}
|
|
|
|
TextSerializer<MethodInvocation> methodInvocationSerializer = new Wrapped(
|
|
unwrapMethodInvocation,
|
|
wrapMethodInvocation,
|
|
new Tuple3Serializer(
|
|
expressionSerializer, nameSerializer, argumentsSerializer));
|
|
|
|
Tuple3<Expression, Name, Arguments> unwrapMethodInvocation(
|
|
MethodInvocation expression) {
|
|
return new Tuple3(expression.receiver, expression.name, expression.arguments);
|
|
}
|
|
|
|
MethodInvocation wrapMethodInvocation(
|
|
Tuple3<Expression, Name, Arguments> tuple) {
|
|
return new MethodInvocation(tuple.first, tuple.second, tuple.third);
|
|
}
|
|
|
|
TextSerializer<SuperMethodInvocation> superMethodInvocationSerializer =
|
|
new Wrapped(unwrapSuperMethodInvocation, wrapSuperMethodInvocation,
|
|
new Tuple2Serializer(nameSerializer, argumentsSerializer));
|
|
|
|
Tuple2<Name, Arguments> unwrapSuperMethodInvocation(
|
|
SuperMethodInvocation expression) {
|
|
return new Tuple2(expression.name, expression.arguments);
|
|
}
|
|
|
|
SuperMethodInvocation wrapSuperMethodInvocation(Tuple2<Name, Arguments> tuple) {
|
|
return new SuperMethodInvocation(tuple.first, tuple.second);
|
|
}
|
|
|
|
TextSerializer<VariableGet> variableGetSerializer = new Wrapped(
|
|
unwrapVariableGet,
|
|
wrapVariableGet,
|
|
new Tuple2Serializer(const ScopedUse<VariableDeclaration>(),
|
|
new Optional(dartTypeSerializer)));
|
|
|
|
Tuple2<VariableDeclaration, DartType> unwrapVariableGet(VariableGet node) {
|
|
return new Tuple2<VariableDeclaration, DartType>(
|
|
node.variable, node.promotedType);
|
|
}
|
|
|
|
VariableGet wrapVariableGet(Tuple2<VariableDeclaration, DartType> tuple) {
|
|
return new VariableGet(tuple.first, tuple.second);
|
|
}
|
|
|
|
TextSerializer<VariableSet> variableSetSerializer = new Wrapped(
|
|
unwrapVariableSet,
|
|
wrapVariableSet,
|
|
new Tuple2Serializer(
|
|
const ScopedUse<VariableDeclaration>(), expressionSerializer));
|
|
|
|
Tuple2<VariableDeclaration, Expression> unwrapVariableSet(VariableSet node) {
|
|
return new Tuple2<VariableDeclaration, Expression>(node.variable, node.value);
|
|
}
|
|
|
|
VariableSet wrapVariableSet(Tuple2<VariableDeclaration, Expression> tuple) {
|
|
return new VariableSet(tuple.first, tuple.second);
|
|
}
|
|
|
|
class CanonicalNameSerializer extends TextSerializer<CanonicalName> {
|
|
static const String delimiter = "::";
|
|
|
|
const CanonicalNameSerializer();
|
|
|
|
static void writeName(CanonicalName name, StringBuffer buffer) {
|
|
if (!name.isRoot) {
|
|
if (!name.parent.isRoot) {
|
|
writeName(name.parent, buffer);
|
|
buffer.write(delimiter);
|
|
}
|
|
buffer.write(name.name);
|
|
}
|
|
}
|
|
|
|
CanonicalName readFrom(Iterator<Object> stream, DeserializationState state) {
|
|
String string = const DartString().readFrom(stream, state);
|
|
CanonicalName name = state.nameRoot;
|
|
for (String s in string.split(delimiter)) {
|
|
name = name.getChild(s);
|
|
}
|
|
return name;
|
|
}
|
|
|
|
void writeTo(
|
|
StringBuffer buffer, CanonicalName name, SerializationState state) {
|
|
StringBuffer sb = new StringBuffer();
|
|
writeName(name, sb);
|
|
const DartString().writeTo(buffer, sb.toString(), state);
|
|
}
|
|
}
|
|
|
|
const TextSerializer<StaticGet> staticGetSerializer = const Wrapped(
|
|
unwrapStaticGet, wrapStaticGet, const CanonicalNameSerializer());
|
|
|
|
CanonicalName unwrapStaticGet(StaticGet expression) {
|
|
return expression.targetReference.canonicalName;
|
|
}
|
|
|
|
StaticGet wrapStaticGet(CanonicalName name) {
|
|
return new StaticGet.byReference(name.getReference());
|
|
}
|
|
|
|
TextSerializer<StaticSet> staticSetSerializer = new Wrapped(
|
|
unwrapStaticSet,
|
|
wrapStaticSet,
|
|
new Tuple2Serializer(
|
|
const CanonicalNameSerializer(), expressionSerializer));
|
|
|
|
Tuple2<CanonicalName, Expression> unwrapStaticSet(StaticSet expression) {
|
|
return new Tuple2(expression.targetReference.canonicalName, expression.value);
|
|
}
|
|
|
|
StaticSet wrapStaticSet(Tuple2<CanonicalName, Expression> tuple) {
|
|
return new StaticSet.byReference(tuple.first.getReference(), tuple.second);
|
|
}
|
|
|
|
TextSerializer<DirectPropertyGet> directPropertyGetSerializer = new Wrapped(
|
|
unwrapDirectPropertyGet,
|
|
wrapDirectPropertyGet,
|
|
new Tuple2Serializer(
|
|
expressionSerializer, const CanonicalNameSerializer()));
|
|
|
|
Tuple2<Expression, CanonicalName> unwrapDirectPropertyGet(
|
|
DirectPropertyGet expression) {
|
|
return new Tuple2(
|
|
expression.receiver, expression.targetReference.canonicalName);
|
|
}
|
|
|
|
DirectPropertyGet wrapDirectPropertyGet(
|
|
Tuple2<Expression, CanonicalName> tuple) {
|
|
return new DirectPropertyGet.byReference(
|
|
tuple.first, tuple.second.getReference());
|
|
}
|
|
|
|
TextSerializer<DirectPropertySet> directPropertySetSerializer = new Wrapped(
|
|
unwrapDirectPropertySet,
|
|
wrapDirectPropertySet,
|
|
new Tuple3Serializer(expressionSerializer, const CanonicalNameSerializer(),
|
|
expressionSerializer));
|
|
|
|
Tuple3<Expression, CanonicalName, Expression> unwrapDirectPropertySet(
|
|
DirectPropertySet expression) {
|
|
return new Tuple3(expression.receiver,
|
|
expression.targetReference.canonicalName, expression.value);
|
|
}
|
|
|
|
DirectPropertySet wrapDirectPropertySet(
|
|
Tuple3<Expression, CanonicalName, Expression> tuple) {
|
|
return new DirectPropertySet.byReference(
|
|
tuple.first, tuple.second.getReference(), tuple.third);
|
|
}
|
|
|
|
TextSerializer<StaticInvocation> staticInvocationSerializer = new Wrapped(
|
|
unwrapStaticInvocation,
|
|
wrapStaticInvocation,
|
|
new Tuple2Serializer(const CanonicalNameSerializer(), argumentsSerializer));
|
|
|
|
Tuple2<CanonicalName, Arguments> unwrapStaticInvocation(
|
|
StaticInvocation expression) {
|
|
return new Tuple2(
|
|
expression.targetReference.canonicalName, expression.arguments);
|
|
}
|
|
|
|
StaticInvocation wrapStaticInvocation(Tuple2<CanonicalName, Arguments> tuple) {
|
|
return new StaticInvocation.byReference(
|
|
tuple.first.getReference(), tuple.second,
|
|
isConst: false);
|
|
}
|
|
|
|
TextSerializer<StaticInvocation> constStaticInvocationSerializer = new Wrapped(
|
|
unwrapStaticInvocation,
|
|
wrapConstStaticInvocation,
|
|
new Tuple2Serializer(const CanonicalNameSerializer(), argumentsSerializer));
|
|
|
|
StaticInvocation wrapConstStaticInvocation(
|
|
Tuple2<CanonicalName, Arguments> tuple) {
|
|
return new StaticInvocation.byReference(
|
|
tuple.first.getReference(), tuple.second,
|
|
isConst: true);
|
|
}
|
|
|
|
TextSerializer<DirectMethodInvocation> directMethodInvocationSerializer =
|
|
new Wrapped(
|
|
unwrapDirectMethodInvocation,
|
|
wrapDirectMethodInvocation,
|
|
new Tuple3Serializer(expressionSerializer,
|
|
const CanonicalNameSerializer(), argumentsSerializer));
|
|
|
|
Tuple3<Expression, CanonicalName, Arguments> unwrapDirectMethodInvocation(
|
|
DirectMethodInvocation expression) {
|
|
return new Tuple3(expression.receiver,
|
|
expression.targetReference.canonicalName, expression.arguments);
|
|
}
|
|
|
|
DirectMethodInvocation wrapDirectMethodInvocation(
|
|
Tuple3<Expression, CanonicalName, Arguments> tuple) {
|
|
return new DirectMethodInvocation.byReference(
|
|
tuple.first, tuple.second.getReference(), tuple.third);
|
|
}
|
|
|
|
TextSerializer<ConstructorInvocation> constructorInvocationSerializer =
|
|
new Wrapped(
|
|
unwrapConstructorInvocation,
|
|
wrapConstructorInvocation,
|
|
new Tuple2Serializer(
|
|
const CanonicalNameSerializer(), argumentsSerializer));
|
|
|
|
Tuple2<CanonicalName, Arguments> unwrapConstructorInvocation(
|
|
ConstructorInvocation expression) {
|
|
return new Tuple2(
|
|
expression.targetReference.canonicalName, expression.arguments);
|
|
}
|
|
|
|
ConstructorInvocation wrapConstructorInvocation(
|
|
Tuple2<CanonicalName, Arguments> tuple) {
|
|
return new ConstructorInvocation.byReference(
|
|
tuple.first.getReference(), tuple.second,
|
|
isConst: false);
|
|
}
|
|
|
|
TextSerializer<ConstructorInvocation> constConstructorInvocationSerializer =
|
|
new Wrapped(unwrapConstructorInvocation, wrapConstConstructorInvocation,
|
|
Tuple2Serializer(const CanonicalNameSerializer(), argumentsSerializer));
|
|
|
|
ConstructorInvocation wrapConstConstructorInvocation(
|
|
Tuple2<CanonicalName, Arguments> tuple) {
|
|
return new ConstructorInvocation.byReference(
|
|
tuple.first.getReference(), tuple.second,
|
|
isConst: true);
|
|
}
|
|
|
|
TextSerializer<FunctionExpression> functionExpressionSerializer = new Wrapped(
|
|
unwrapFunctionExpression, wrapFunctionExpression, functionNodeSerializer);
|
|
|
|
FunctionNode unwrapFunctionExpression(FunctionExpression expression) {
|
|
return expression.function;
|
|
}
|
|
|
|
FunctionExpression wrapFunctionExpression(FunctionNode node) {
|
|
return new FunctionExpression(node);
|
|
}
|
|
|
|
Case<Expression> expressionSerializer =
|
|
new Case.uninitialized(const ExpressionTagger());
|
|
|
|
TextSerializer<NamedExpression> namedExpressionSerializer = new Wrapped(
|
|
unwrapNamedExpression,
|
|
wrapNamedExpression,
|
|
new Tuple2Serializer(const DartString(), expressionSerializer));
|
|
|
|
Tuple2<String, Expression> unwrapNamedExpression(NamedExpression expression) {
|
|
return new Tuple2(expression.name, expression.value);
|
|
}
|
|
|
|
NamedExpression wrapNamedExpression(Tuple2<String, Expression> tuple) {
|
|
return new NamedExpression(tuple.first, tuple.second);
|
|
}
|
|
|
|
TextSerializer<Arguments> argumentsSerializer = new Wrapped(
|
|
unwrapArguments,
|
|
wrapArguments,
|
|
Tuple3Serializer(
|
|
new ListSerializer(dartTypeSerializer),
|
|
new ListSerializer(expressionSerializer),
|
|
new ListSerializer(namedExpressionSerializer)));
|
|
|
|
Tuple3<List<DartType>, List<Expression>, List<NamedExpression>> unwrapArguments(
|
|
Arguments arguments) {
|
|
return new Tuple3(arguments.types, arguments.positional, arguments.named);
|
|
}
|
|
|
|
Arguments wrapArguments(
|
|
Tuple3<List<DartType>, List<Expression>, List<NamedExpression>> tuple) {
|
|
return new Arguments(tuple.second, types: tuple.first, named: tuple.third);
|
|
}
|
|
|
|
class VariableDeclarationTagger implements Tagger<VariableDeclaration> {
|
|
const VariableDeclarationTagger();
|
|
|
|
String tag(VariableDeclaration decl) {
|
|
if (decl.isCovariant) throw UnimplementedError("Covariant declaration.");
|
|
if (decl.isFieldFormal) throw UnimplementedError("Initializing formal.");
|
|
if (decl.isConst) {
|
|
// It's not clear what invariants we assume about const/final. For now
|
|
// throw if we have both.
|
|
if (decl.isFinal) throw UnimplementedError("const and final");
|
|
return "const";
|
|
}
|
|
if (decl.isFinal) {
|
|
return "final";
|
|
}
|
|
return "var";
|
|
}
|
|
}
|
|
|
|
TextSerializer<VariableDeclaration> varDeclarationSerializer = new Wrapped(
|
|
unwrapVariableDeclaration,
|
|
wrapVarDeclaration,
|
|
Tuple4Serializer(
|
|
const DartString(),
|
|
dartTypeSerializer,
|
|
new Optional(expressionSerializer),
|
|
new ListSerializer(expressionSerializer)));
|
|
|
|
Tuple4<String, DartType, Expression, List<Expression>>
|
|
unwrapVariableDeclaration(VariableDeclaration declaration) {
|
|
return new Tuple4(declaration.name ?? "", declaration.type,
|
|
declaration.initializer, declaration.annotations);
|
|
}
|
|
|
|
VariableDeclaration wrapVarDeclaration(
|
|
Tuple4<String, DartType, Expression, List<Expression>> tuple) {
|
|
var result = new VariableDeclaration(tuple.first.isEmpty ? null : tuple.first,
|
|
initializer: tuple.third, type: tuple.second);
|
|
for (int i = 0; i < tuple.fourth.length; ++i) {
|
|
result.addAnnotation(tuple.fourth[i]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
TextSerializer<VariableDeclaration> finalDeclarationSerializer = new Wrapped(
|
|
unwrapVariableDeclaration,
|
|
wrapFinalDeclaration,
|
|
Tuple4Serializer(
|
|
const DartString(),
|
|
dartTypeSerializer,
|
|
new Optional(expressionSerializer),
|
|
new ListSerializer(expressionSerializer)));
|
|
|
|
VariableDeclaration wrapFinalDeclaration(
|
|
Tuple4<String, DartType, Expression, List<Expression>> tuple) {
|
|
var result = new VariableDeclaration(tuple.first.isEmpty ? null : tuple.first,
|
|
initializer: tuple.third, type: tuple.second, isFinal: true);
|
|
for (int i = 0; i < tuple.fourth.length; ++i) {
|
|
result.addAnnotation(tuple.fourth[i]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
TextSerializer<VariableDeclaration> constDeclarationSerializer = new Wrapped(
|
|
unwrapVariableDeclaration,
|
|
wrapConstDeclaration,
|
|
Tuple4Serializer(
|
|
const DartString(),
|
|
dartTypeSerializer,
|
|
new Optional(expressionSerializer),
|
|
new ListSerializer(expressionSerializer)));
|
|
|
|
VariableDeclaration wrapConstDeclaration(
|
|
Tuple4<String, DartType, Expression, List<Expression>> tuple) {
|
|
var result = new VariableDeclaration(tuple.first.isEmpty ? null : tuple.first,
|
|
initializer: tuple.third, type: tuple.second, isConst: true);
|
|
for (int i = 0; i < tuple.fourth.length; ++i) {
|
|
result.addAnnotation(tuple.fourth[i]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
TextSerializer<VariableDeclaration> variableDeclarationSerializer = new Binder(
|
|
new Case(const VariableDeclarationTagger(), {
|
|
"var": varDeclarationSerializer,
|
|
"final": finalDeclarationSerializer,
|
|
"const": constDeclarationSerializer,
|
|
}),
|
|
getVariableDeclarationName,
|
|
setVariableDeclarationName);
|
|
|
|
TextSerializer<TypeParameter> typeParameterSerializer = new Binder(
|
|
const Wrapped(unwrapTypeParameter, wrapTypeParameter, const DartString()),
|
|
getTypeParameterName,
|
|
setTypeParameterName);
|
|
|
|
String unwrapTypeParameter(TypeParameter node) => node.name;
|
|
|
|
TypeParameter wrapTypeParameter(String name) => new TypeParameter(name);
|
|
|
|
TextSerializer<List<TypeParameter>> typeParametersSerializer = new Zip(
|
|
new Rebind(
|
|
new Zip(
|
|
new Rebind(new ListSerializer(typeParameterSerializer),
|
|
new ListSerializer(dartTypeSerializer)),
|
|
zipTypeParameterBound,
|
|
unzipTypeParameterBound),
|
|
new ListSerializer(dartTypeSerializer)),
|
|
zipTypeParameterDefaultType,
|
|
unzipTypeParameterDefaultType);
|
|
|
|
String getTypeParameterName(TypeParameter node) => node.name;
|
|
|
|
void setTypeParameterName(TypeParameter node, String name) {
|
|
node.name = name;
|
|
}
|
|
|
|
TypeParameter zipTypeParameterBound(TypeParameter node, DartType bound) {
|
|
return node..bound = bound;
|
|
}
|
|
|
|
Tuple2<TypeParameter, DartType> unzipTypeParameterBound(TypeParameter node) {
|
|
return new Tuple2(node, node.bound);
|
|
}
|
|
|
|
TypeParameter zipTypeParameterDefaultType(
|
|
TypeParameter node, DartType defaultType) {
|
|
return node..defaultType = defaultType;
|
|
}
|
|
|
|
Tuple2<TypeParameter, DartType> unzipTypeParameterDefaultType(
|
|
TypeParameter node) {
|
|
return new Tuple2(node, node.defaultType);
|
|
}
|
|
|
|
class DartTypeTagger extends DartTypeVisitor<String>
|
|
implements Tagger<DartType> {
|
|
const DartTypeTagger();
|
|
|
|
String tag(DartType type) => type.accept(this);
|
|
|
|
String visitInvalidType(InvalidType _) => "invalid";
|
|
String visitDynamicType(DynamicType _) => "dynamic";
|
|
String visitVoidType(VoidType _) => "void";
|
|
String visitBottomType(BottomType _) => "bottom";
|
|
String visitFunctionType(FunctionType _) => "->";
|
|
String visitTypeParameterType(TypeParameterType _) => "par";
|
|
String visitInterfaceType(InterfaceType _) => "interface";
|
|
String visitNeverType(NeverType _) => "never";
|
|
String visitTypedefType(TypedefType _) => "typedef";
|
|
String visitFutureOrType(FutureOrType _) => "futureor";
|
|
}
|
|
|
|
const TextSerializer<InvalidType> invalidTypeSerializer =
|
|
const Wrapped(unwrapInvalidType, wrapInvalidType, const Nothing());
|
|
|
|
void unwrapInvalidType(InvalidType type) {}
|
|
|
|
InvalidType wrapInvalidType(void ignored) => const InvalidType();
|
|
|
|
const TextSerializer<DynamicType> dynamicTypeSerializer =
|
|
const Wrapped(unwrapDynamicType, wrapDynamicType, const Nothing());
|
|
|
|
void unwrapDynamicType(DynamicType type) {}
|
|
|
|
DynamicType wrapDynamicType(void ignored) => const DynamicType();
|
|
|
|
const TextSerializer<VoidType> voidTypeSerializer =
|
|
const Wrapped(unwrapVoidType, wrapVoidType, const Nothing());
|
|
|
|
void unwrapVoidType(VoidType type) {}
|
|
|
|
VoidType wrapVoidType(void ignored) => const VoidType();
|
|
|
|
const TextSerializer<BottomType> bottomTypeSerializer =
|
|
const Wrapped(unwrapBottomType, wrapBottomType, const Nothing());
|
|
|
|
void unwrapBottomType(BottomType type) {}
|
|
|
|
BottomType wrapBottomType(void ignored) => const BottomType();
|
|
|
|
const TextSerializer<NeverType> neverTypeSerializer =
|
|
const Wrapped(unwrapNeverType, wrapNeverType, const Nothing());
|
|
|
|
void unwrapNeverType(NeverType type) {}
|
|
|
|
NeverType wrapNeverType(void ignored) => const NeverType(Nullability.legacy);
|
|
|
|
// TODO(dmitryas): Also handle nameParameters, and typedefType.
|
|
TextSerializer<FunctionType> functionTypeSerializer = new Wrapped(
|
|
unwrapFunctionType,
|
|
wrapFunctionType,
|
|
new Bind(
|
|
typeParametersSerializer,
|
|
new Tuple4Serializer(
|
|
new ListSerializer(dartTypeSerializer),
|
|
new ListSerializer(dartTypeSerializer),
|
|
new ListSerializer(namedTypeSerializer),
|
|
dartTypeSerializer)));
|
|
|
|
Tuple2<List<TypeParameter>,
|
|
Tuple4<List<DartType>, List<DartType>, List<NamedType>, DartType>>
|
|
unwrapFunctionType(FunctionType type) {
|
|
return new Tuple2(
|
|
type.typeParameters,
|
|
new Tuple4(
|
|
type.positionalParameters.sublist(0, type.requiredParameterCount),
|
|
type.positionalParameters.sublist(type.requiredParameterCount),
|
|
type.namedParameters,
|
|
type.returnType));
|
|
}
|
|
|
|
FunctionType wrapFunctionType(
|
|
Tuple2<List<TypeParameter>,
|
|
Tuple4<List<DartType>, List<DartType>, List<NamedType>, DartType>>
|
|
tuple) {
|
|
return new FunctionType(tuple.second.first + tuple.second.second,
|
|
tuple.second.fourth, Nullability.legacy,
|
|
requiredParameterCount: tuple.second.first.length,
|
|
typeParameters: tuple.first,
|
|
namedParameters: tuple.second.third);
|
|
}
|
|
|
|
TextSerializer<NamedType> namedTypeSerializer = new Wrapped(unwrapNamedType,
|
|
wrapNamedType, Tuple2Serializer(const DartString(), dartTypeSerializer));
|
|
|
|
Tuple2<String, DartType> unwrapNamedType(NamedType namedType) {
|
|
return new Tuple2(namedType.name, namedType.type);
|
|
}
|
|
|
|
NamedType wrapNamedType(Tuple2<String, DartType> tuple) {
|
|
return new NamedType(tuple.first, tuple.second);
|
|
}
|
|
|
|
TextSerializer<TypeParameterType> typeParameterTypeSerializer = new Wrapped(
|
|
unwrapTypeParameterType,
|
|
wrapTypeParameterType,
|
|
Tuple2Serializer(
|
|
new ScopedUse<TypeParameter>(), new Optional(dartTypeSerializer)));
|
|
|
|
Tuple2<TypeParameter, DartType> unwrapTypeParameterType(
|
|
TypeParameterType node) {
|
|
return new Tuple2(node.parameter, node.promotedBound);
|
|
}
|
|
|
|
TypeParameterType wrapTypeParameterType(Tuple2<TypeParameter, DartType> tuple) {
|
|
return new TypeParameterType(tuple.first, Nullability.legacy, tuple.second);
|
|
}
|
|
|
|
TextSerializer<InterfaceType> interfaceTypeSerializer = new Wrapped(
|
|
unwrapInterfaceType,
|
|
wrapInterfaceType,
|
|
Tuple2Serializer(const CanonicalNameSerializer(),
|
|
new ListSerializer(dartTypeSerializer)));
|
|
|
|
Tuple2<CanonicalName, List<DartType>> unwrapInterfaceType(InterfaceType node) {
|
|
return new Tuple2(node.className.canonicalName, node.typeArguments);
|
|
}
|
|
|
|
InterfaceType wrapInterfaceType(Tuple2<CanonicalName, List<DartType>> tuple) {
|
|
return new InterfaceType.byReference(
|
|
tuple.first.reference, Nullability.legacy, tuple.second);
|
|
}
|
|
|
|
TextSerializer<TypedefType> typedefTypeSerializer = new Wrapped(
|
|
unwrapTypedefType,
|
|
wrapTypedefType,
|
|
Tuple2Serializer(const CanonicalNameSerializer(),
|
|
new ListSerializer(dartTypeSerializer)));
|
|
|
|
Tuple2<CanonicalName, List<DartType>> unwrapTypedefType(TypedefType node) {
|
|
return new Tuple2(node.typedefReference.canonicalName, node.typeArguments);
|
|
}
|
|
|
|
TypedefType wrapTypedefType(Tuple2<CanonicalName, List<DartType>> tuple) {
|
|
return new TypedefType.byReference(
|
|
tuple.first.reference, Nullability.legacy, tuple.second);
|
|
}
|
|
|
|
TextSerializer<FutureOrType> futureOrTypeSerializer =
|
|
new Wrapped(unwrapFutureOrType, wrapFutureOrType, dartTypeSerializer);
|
|
|
|
DartType unwrapFutureOrType(FutureOrType node) {
|
|
return node.typeArgument;
|
|
}
|
|
|
|
FutureOrType wrapFutureOrType(DartType typeArgument) {
|
|
return new FutureOrType(typeArgument, Nullability.legacy);
|
|
}
|
|
|
|
Case<DartType> dartTypeSerializer =
|
|
new Case.uninitialized(const DartTypeTagger());
|
|
|
|
class StatementTagger extends StatementVisitor<String>
|
|
implements Tagger<Statement> {
|
|
const StatementTagger();
|
|
|
|
String tag(Statement statement) => statement.accept(this);
|
|
|
|
String visitExpressionStatement(ExpressionStatement _) => "expr";
|
|
String visitReturnStatement(ReturnStatement node) {
|
|
return node.expression == null ? "ret-void" : "ret";
|
|
}
|
|
|
|
String visitYieldStatement(YieldStatement _) => "yield";
|
|
String visitBlock(Block _) => "block";
|
|
String visitVariableDeclaration(VariableDeclaration _) => "local";
|
|
String visitIfStatement(IfStatement node) {
|
|
return node.otherwise == null ? "if" : "if-else";
|
|
}
|
|
|
|
String visitEmptyStatement(EmptyStatement node) => "skip";
|
|
String visitWhileStatement(WhileStatement node) => "while";
|
|
String visitDoStatement(DoStatement node) => "do-while";
|
|
String visitForStatement(ForStatement node) => "for";
|
|
String visitForInStatement(ForInStatement node) {
|
|
return node.isAsync ? "await-for-in" : "for-in";
|
|
}
|
|
|
|
String visitAssertStatement(AssertStatement node) => "assert";
|
|
String visitAssertBlock(AssertBlock node) => "assert-block";
|
|
}
|
|
|
|
TextSerializer<ExpressionStatement> expressionStatementSerializer = new Wrapped(
|
|
unwrapExpressionStatement, wrapExpressionStatement, expressionSerializer);
|
|
|
|
Expression unwrapExpressionStatement(ExpressionStatement statement) {
|
|
return statement.expression;
|
|
}
|
|
|
|
ExpressionStatement wrapExpressionStatement(Expression expression) {
|
|
return new ExpressionStatement(expression);
|
|
}
|
|
|
|
TextSerializer<ReturnStatement> returnStatementSerializer = new Wrapped(
|
|
unwrapReturnStatement, wrapReturnStatement, expressionSerializer);
|
|
|
|
Expression unwrapReturnStatement(ReturnStatement statement) {
|
|
return statement.expression;
|
|
}
|
|
|
|
ReturnStatement wrapReturnStatement(Expression expression) {
|
|
return new ReturnStatement(expression);
|
|
}
|
|
|
|
TextSerializer<ReturnStatement> returnVoidStatementSerializer = new Wrapped(
|
|
unwrapReturnVoidStatement, wrapReturnVoidStatement, const Nothing());
|
|
|
|
void unwrapReturnVoidStatement(void ignored) {}
|
|
|
|
ReturnStatement wrapReturnVoidStatement(void ignored) => new ReturnStatement();
|
|
|
|
TextSerializer<YieldStatement> yieldStatementSerializer =
|
|
new Wrapped(unwrapYieldStatement, wrapYieldStatement, expressionSerializer);
|
|
|
|
Expression unwrapYieldStatement(YieldStatement node) => node.expression;
|
|
|
|
YieldStatement wrapYieldStatement(Expression expression) {
|
|
return new YieldStatement(expression);
|
|
}
|
|
|
|
TextSerializer<AssertStatement> assertStatementSerializer = new Wrapped(
|
|
unwrapAssertStatement,
|
|
wrapAssertStatement,
|
|
new Tuple2Serializer(expressionSerializer, expressionSerializer));
|
|
|
|
Tuple2<Expression, Expression> unwrapAssertStatement(AssertStatement node) {
|
|
return new Tuple2<Expression, Expression>(node.condition, node.message);
|
|
}
|
|
|
|
AssertStatement wrapAssertStatement(Tuple2<Expression, Expression> tuple) {
|
|
return new AssertStatement(tuple.first, message: tuple.second);
|
|
}
|
|
|
|
TextSerializer<Block> blockSerializer =
|
|
new Wrapped(unwrapBlock, wrapBlock, const BlockSerializer());
|
|
|
|
List<Statement> unwrapBlock(Block node) => node.statements;
|
|
|
|
Block wrapBlock(List<Statement> statements) => new Block(statements);
|
|
|
|
TextSerializer<AssertBlock> assertBlockSerializer =
|
|
new Wrapped(unwrapAssertBlock, wrapAssertBlock, const BlockSerializer());
|
|
|
|
List<Statement> unwrapAssertBlock(AssertBlock node) => node.statements;
|
|
|
|
AssertBlock wrapAssertBlock(List<Statement> statements) =>
|
|
new AssertBlock(statements);
|
|
|
|
/// Serializer for [Block]s.
|
|
///
|
|
/// [BlockSerializer] is a combination of [ListSerializer] and [Bind]. As in
|
|
/// the case of [ListSerializer], [BlockSerializer] is a sequence of statements.
|
|
/// As in the case of [Bind], a statement in a block can be a
|
|
/// [VariableDeclaration] introducing binders that are bound in the rest of the
|
|
/// statements in the block. Effectively, [BlockSerializer] could have been
|
|
/// expressed in terms of [ListSerializer] and [Bind], but that would transform
|
|
/// blocks like {stmt1; stmt2; stmt3;} into {stmt1; {stmt2; {stmt3; {}}}} via
|
|
/// the round-trip, and an extra pass will be required to flatten the
|
|
/// unnecessary nested blocks. Instead, [BlockSerializer] is implemented
|
|
/// without direct invocations of either [ListSerializer] or [Bind], but with a
|
|
/// certain internal correspondence to how they work.
|
|
class BlockSerializer extends TextSerializer<List<Statement>> {
|
|
const BlockSerializer();
|
|
|
|
List<Statement> readFrom(
|
|
Iterator<Object> stream, DeserializationState state) {
|
|
if (stream.current is! Iterator) {
|
|
throw StateError("Expected a list, found an atom: '${stream.current}'.");
|
|
}
|
|
Iterator<Object> list = stream.current;
|
|
list.moveNext();
|
|
List<Statement> result = [];
|
|
DeserializationState currentState = state;
|
|
while (list.current != null) {
|
|
currentState = new DeserializationState(
|
|
new DeserializationEnvironment(currentState.environment),
|
|
currentState.nameRoot);
|
|
result.add(statementSerializer.readFrom(list, currentState));
|
|
currentState.environment.close();
|
|
}
|
|
stream.moveNext();
|
|
return result;
|
|
}
|
|
|
|
void writeTo(StringBuffer buffer, List<Statement> statements,
|
|
SerializationState state) {
|
|
buffer.write('(');
|
|
SerializationState currentState = state;
|
|
for (int i = 0; i < statements.length; ++i) {
|
|
if (i != 0) buffer.write(' ');
|
|
currentState = new SerializationState(
|
|
new SerializationEnvironment(currentState.environment));
|
|
statementSerializer.writeTo(buffer, statements[i], currentState);
|
|
currentState.environment.close();
|
|
}
|
|
buffer.write(')');
|
|
}
|
|
}
|
|
|
|
TextSerializer<IfStatement> ifStatementSerializer = new Wrapped(
|
|
unwrapIfStatement,
|
|
wrapIfStatement,
|
|
Tuple2Serializer(expressionSerializer, statementSerializer));
|
|
|
|
Tuple2<Expression, Statement> unwrapIfStatement(IfStatement node) {
|
|
return new Tuple2(node.condition, node.then);
|
|
}
|
|
|
|
IfStatement wrapIfStatement(Tuple2<Expression, Statement> tuple) {
|
|
return new IfStatement(tuple.first, tuple.second, null);
|
|
}
|
|
|
|
TextSerializer<IfStatement> ifElseStatementSerializer = new Wrapped(
|
|
unwrapIfElseStatement,
|
|
wrapIfElseStatement,
|
|
Tuple3Serializer(
|
|
expressionSerializer, statementSerializer, statementSerializer));
|
|
|
|
Tuple3<Expression, Statement, Statement> unwrapIfElseStatement(
|
|
IfStatement node) {
|
|
return new Tuple3(node.condition, node.then, node.otherwise);
|
|
}
|
|
|
|
IfStatement wrapIfElseStatement(
|
|
Tuple3<Expression, Statement, Statement> tuple) {
|
|
return new IfStatement(tuple.first, tuple.second, tuple.third);
|
|
}
|
|
|
|
TextSerializer<EmptyStatement> emptyStatementSerializer =
|
|
new Wrapped(unwrapEmptyStatement, wrapEmptyStatement, const Nothing());
|
|
|
|
void unwrapEmptyStatement(EmptyStatement node) {}
|
|
|
|
EmptyStatement wrapEmptyStatement(void ignored) => new EmptyStatement();
|
|
|
|
TextSerializer<WhileStatement> whileStatementSerializer = new Wrapped(
|
|
unwrapWhileStatement,
|
|
wrapWhileStatement,
|
|
new Tuple2Serializer(expressionSerializer, statementSerializer));
|
|
|
|
Tuple2<Expression, Statement> unwrapWhileStatement(WhileStatement node) {
|
|
return new Tuple2(node.condition, node.body);
|
|
}
|
|
|
|
WhileStatement wrapWhileStatement(Tuple2<Expression, Statement> tuple) {
|
|
return new WhileStatement(tuple.first, tuple.second);
|
|
}
|
|
|
|
TextSerializer<DoStatement> doStatementSerializer = new Wrapped(
|
|
unwrapDoStatement,
|
|
wrapDoStatement,
|
|
new Tuple2Serializer(statementSerializer, expressionSerializer));
|
|
|
|
Tuple2<Statement, Expression> unwrapDoStatement(DoStatement node) {
|
|
return new Tuple2(node.body, node.condition);
|
|
}
|
|
|
|
DoStatement wrapDoStatement(Tuple2<Statement, Expression> tuple) {
|
|
return new DoStatement(tuple.first, tuple.second);
|
|
}
|
|
|
|
TextSerializer<ForStatement> forStatementSerializer = new Wrapped(
|
|
unwrapForStatement,
|
|
wrapForStatement,
|
|
new Bind(
|
|
ListSerializer(variableDeclarationSerializer),
|
|
new Tuple3Serializer(expressionSerializer,
|
|
new ListSerializer(expressionSerializer), statementSerializer)));
|
|
|
|
Tuple2<List<VariableDeclaration>,
|
|
Tuple3<Expression, List<Expression>, Statement>>
|
|
unwrapForStatement(ForStatement node) {
|
|
return new Tuple2(
|
|
node.variables, new Tuple3(node.condition, node.updates, node.body));
|
|
}
|
|
|
|
ForStatement wrapForStatement(
|
|
Tuple2<List<VariableDeclaration>,
|
|
Tuple3<Expression, List<Expression>, Statement>>
|
|
tuple) {
|
|
return new ForStatement(
|
|
tuple.first, tuple.second.first, tuple.second.second, tuple.second.third);
|
|
}
|
|
|
|
TextSerializer<ForInStatement> forInStatementSerializer = new Wrapped(
|
|
unwrapForInStatement,
|
|
wrapForInStatement,
|
|
new Tuple2Serializer(expressionSerializer,
|
|
new Bind(variableDeclarationSerializer, statementSerializer)));
|
|
|
|
Tuple2<Expression, Tuple2<VariableDeclaration, Statement>> unwrapForInStatement(
|
|
ForInStatement node) {
|
|
return new Tuple2(node.iterable, new Tuple2(node.variable, node.body));
|
|
}
|
|
|
|
ForInStatement wrapForInStatement(
|
|
Tuple2<Expression, Tuple2<VariableDeclaration, Statement>> tuple) {
|
|
return new ForInStatement(
|
|
tuple.second.first, tuple.first, tuple.second.second);
|
|
}
|
|
|
|
TextSerializer<ForInStatement> awaitForInStatementSerializer = new Wrapped(
|
|
unwrapForInStatement,
|
|
wrapAwaitForInStatement,
|
|
new Tuple2Serializer(expressionSerializer,
|
|
new Bind(variableDeclarationSerializer, statementSerializer)));
|
|
|
|
ForInStatement wrapAwaitForInStatement(
|
|
Tuple2<Expression, Tuple2<VariableDeclaration, Statement>> tuple) {
|
|
return new ForInStatement(
|
|
tuple.second.first, tuple.first, tuple.second.second,
|
|
isAsync: true);
|
|
}
|
|
|
|
Case<Statement> statementSerializer =
|
|
new Case.uninitialized(const StatementTagger());
|
|
|
|
class FunctionNodeTagger implements Tagger<FunctionNode> {
|
|
const FunctionNodeTagger();
|
|
|
|
String tag(FunctionNode node) {
|
|
switch (node.asyncMarker) {
|
|
case AsyncMarker.Async:
|
|
return "async";
|
|
case AsyncMarker.Sync:
|
|
return "sync";
|
|
case AsyncMarker.AsyncStar:
|
|
return "async-star";
|
|
case AsyncMarker.SyncStar:
|
|
return "sync-star";
|
|
case AsyncMarker.SyncYielding:
|
|
return "sync-yielding";
|
|
}
|
|
throw new UnsupportedError("${node.asyncMarker}");
|
|
}
|
|
}
|
|
|
|
TextSerializer<FunctionNode> syncFunctionNodeSerializer = new Wrapped(
|
|
unwrapFunctionNode,
|
|
wrapSyncFunctionNode,
|
|
new Bind(
|
|
new Rebind(
|
|
typeParametersSerializer,
|
|
new Tuple3Serializer(
|
|
new ListSerializer(variableDeclarationSerializer),
|
|
new ListSerializer(variableDeclarationSerializer),
|
|
new ListSerializer(variableDeclarationSerializer))),
|
|
new Tuple2Serializer(dartTypeSerializer, statementSerializer)));
|
|
|
|
Tuple2<
|
|
Tuple2<
|
|
List<TypeParameter>,
|
|
Tuple3<List<VariableDeclaration>, List<VariableDeclaration>,
|
|
List<VariableDeclaration>>>,
|
|
Tuple2<DartType, Statement>> unwrapFunctionNode(FunctionNode node) {
|
|
return new Tuple2(
|
|
new Tuple2(
|
|
node.typeParameters,
|
|
new Tuple3(
|
|
node.positionalParameters.sublist(0, node.requiredParameterCount),
|
|
node.positionalParameters.sublist(node.requiredParameterCount),
|
|
node.namedParameters)),
|
|
new Tuple2(node.returnType, node.body));
|
|
}
|
|
|
|
FunctionNode wrapSyncFunctionNode(
|
|
Tuple2<
|
|
Tuple2<
|
|
List<TypeParameter>,
|
|
Tuple3<List<VariableDeclaration>, List<VariableDeclaration>,
|
|
List<VariableDeclaration>>>,
|
|
Tuple2<DartType, Statement>>
|
|
tuple) {
|
|
return new FunctionNode(tuple.second.second,
|
|
typeParameters: tuple.first.first,
|
|
positionalParameters:
|
|
tuple.first.second.first + tuple.first.second.second,
|
|
namedParameters: tuple.first.second.third,
|
|
requiredParameterCount: tuple.first.second.first.length,
|
|
returnType: tuple.second.first,
|
|
asyncMarker: AsyncMarker.Sync);
|
|
}
|
|
|
|
TextSerializer<FunctionNode> asyncFunctionNodeSerializer = new Wrapped(
|
|
unwrapFunctionNode,
|
|
wrapAsyncFunctionNode,
|
|
new Bind(
|
|
new Rebind(
|
|
typeParametersSerializer,
|
|
new Tuple3Serializer(
|
|
new ListSerializer(variableDeclarationSerializer),
|
|
new ListSerializer(variableDeclarationSerializer),
|
|
new ListSerializer(variableDeclarationSerializer))),
|
|
new Tuple2Serializer(dartTypeSerializer, statementSerializer)));
|
|
|
|
FunctionNode wrapAsyncFunctionNode(
|
|
Tuple2<
|
|
Tuple2<
|
|
List<TypeParameter>,
|
|
Tuple3<List<VariableDeclaration>, List<VariableDeclaration>,
|
|
List<VariableDeclaration>>>,
|
|
Tuple2<DartType, Statement>>
|
|
tuple) {
|
|
return new FunctionNode(tuple.second.second,
|
|
typeParameters: tuple.first.first,
|
|
positionalParameters:
|
|
tuple.first.second.first + tuple.first.second.second,
|
|
namedParameters: tuple.first.second.third,
|
|
requiredParameterCount: tuple.first.second.first.length,
|
|
returnType: tuple.second.first,
|
|
asyncMarker: AsyncMarker.Async);
|
|
}
|
|
|
|
TextSerializer<FunctionNode> syncStarFunctionNodeSerializer = new Wrapped(
|
|
unwrapFunctionNode,
|
|
wrapSyncStarFunctionNode,
|
|
new Bind(
|
|
new Rebind(
|
|
typeParametersSerializer,
|
|
new Tuple3Serializer(
|
|
new ListSerializer(variableDeclarationSerializer),
|
|
new ListSerializer(variableDeclarationSerializer),
|
|
new ListSerializer(variableDeclarationSerializer))),
|
|
new Tuple2Serializer(dartTypeSerializer, statementSerializer)));
|
|
|
|
FunctionNode wrapSyncStarFunctionNode(
|
|
Tuple2<
|
|
Tuple2<
|
|
List<TypeParameter>,
|
|
Tuple3<List<VariableDeclaration>, List<VariableDeclaration>,
|
|
List<VariableDeclaration>>>,
|
|
Tuple2<DartType, Statement>>
|
|
tuple) {
|
|
return new FunctionNode(tuple.second.second,
|
|
typeParameters: tuple.first.first,
|
|
positionalParameters:
|
|
tuple.first.second.first + tuple.first.second.second,
|
|
namedParameters: tuple.first.second.third,
|
|
requiredParameterCount: tuple.first.second.first.length,
|
|
returnType: tuple.second.first,
|
|
asyncMarker: AsyncMarker.SyncStar);
|
|
}
|
|
|
|
TextSerializer<FunctionNode> asyncStarFunctionNodeSerializer = new Wrapped(
|
|
unwrapFunctionNode,
|
|
wrapAsyncStarFunctionNode,
|
|
new Bind(
|
|
new Rebind(
|
|
typeParametersSerializer,
|
|
new Tuple3Serializer(
|
|
new ListSerializer(variableDeclarationSerializer),
|
|
new ListSerializer(variableDeclarationSerializer),
|
|
new ListSerializer(variableDeclarationSerializer))),
|
|
new Tuple2Serializer(dartTypeSerializer, statementSerializer)));
|
|
|
|
FunctionNode wrapAsyncStarFunctionNode(
|
|
Tuple2<
|
|
Tuple2<
|
|
List<TypeParameter>,
|
|
Tuple3<List<VariableDeclaration>, List<VariableDeclaration>,
|
|
List<VariableDeclaration>>>,
|
|
Tuple2<DartType, Statement>>
|
|
tuple) {
|
|
return new FunctionNode(tuple.second.second,
|
|
typeParameters: tuple.first.first,
|
|
positionalParameters:
|
|
tuple.first.second.first + tuple.first.second.second,
|
|
namedParameters: tuple.first.second.third,
|
|
requiredParameterCount: tuple.first.second.first.length,
|
|
returnType: tuple.second.first,
|
|
asyncMarker: AsyncMarker.AsyncStar);
|
|
}
|
|
|
|
TextSerializer<FunctionNode> syncYieldingStarFunctionNodeSerializer =
|
|
new Wrapped(
|
|
unwrapFunctionNode,
|
|
wrapSyncYieldingFunctionNode,
|
|
new Bind(
|
|
new Rebind(
|
|
typeParametersSerializer,
|
|
new Tuple3Serializer(
|
|
new ListSerializer(variableDeclarationSerializer),
|
|
new ListSerializer(variableDeclarationSerializer),
|
|
new ListSerializer(variableDeclarationSerializer))),
|
|
new Tuple2Serializer(dartTypeSerializer, statementSerializer)));
|
|
|
|
FunctionNode wrapSyncYieldingFunctionNode(
|
|
Tuple2<
|
|
Tuple2<
|
|
List<TypeParameter>,
|
|
Tuple3<List<VariableDeclaration>, List<VariableDeclaration>,
|
|
List<VariableDeclaration>>>,
|
|
Tuple2<DartType, Statement>>
|
|
tuple) {
|
|
return new FunctionNode(tuple.second.second,
|
|
typeParameters: tuple.first.first,
|
|
positionalParameters:
|
|
tuple.first.second.first + tuple.first.second.second,
|
|
namedParameters: tuple.first.second.third,
|
|
requiredParameterCount: tuple.first.second.first.length,
|
|
returnType: tuple.second.first,
|
|
asyncMarker: AsyncMarker.SyncYielding);
|
|
}
|
|
|
|
Case<FunctionNode> functionNodeSerializer =
|
|
new Case.uninitialized(const FunctionNodeTagger());
|
|
|
|
class ProcedureTagger implements Tagger<Procedure> {
|
|
const ProcedureTagger();
|
|
|
|
String tag(Procedure node) {
|
|
String prefix = node.isStatic ? "static-" : "";
|
|
switch (node.kind) {
|
|
case ProcedureKind.Method:
|
|
return "${prefix}method";
|
|
default:
|
|
throw new UnsupportedError("${node.kind}");
|
|
}
|
|
}
|
|
}
|
|
|
|
TextSerializer<Procedure> staticMethodSerializer = new Wrapped(
|
|
unwrapStaticMethod,
|
|
wrapStaticMethod,
|
|
new Tuple2Serializer(nameSerializer, functionNodeSerializer));
|
|
|
|
Tuple2<Name, FunctionNode> unwrapStaticMethod(Procedure procedure) {
|
|
return new Tuple2(procedure.name, procedure.function);
|
|
}
|
|
|
|
Procedure wrapStaticMethod(Tuple2<Name, FunctionNode> tuple) {
|
|
return new Procedure(tuple.first, ProcedureKind.Method, tuple.second,
|
|
isStatic: true);
|
|
}
|
|
|
|
Case<Procedure> procedureSerializer =
|
|
new Case.uninitialized(const ProcedureTagger());
|
|
|
|
class LibraryTagger implements Tagger<Library> {
|
|
const LibraryTagger();
|
|
|
|
String tag(Library node) {
|
|
return node.isNonNullableByDefault ? "null-safe" : "legacy";
|
|
}
|
|
}
|
|
|
|
TextSerializer<Library> libraryContentsSerializer = new Wrapped(
|
|
unwrapLibraryNode,
|
|
wrapLibraryNode,
|
|
new Tuple2Serializer(
|
|
const UriSerializer(), new ListSerializer(procedureSerializer)),
|
|
);
|
|
|
|
Tuple2<Uri, List<Procedure>> unwrapLibraryNode(Library library) {
|
|
return new Tuple2(library.importUri, library.procedures);
|
|
}
|
|
|
|
Library wrapLibraryNode(Tuple2<Uri, List<Procedure>> tuple) {
|
|
return new Library(tuple.first, procedures: tuple.second);
|
|
}
|
|
|
|
Case<Library> librarySerializer = new Case.uninitialized(const LibraryTagger());
|
|
|
|
void initializeSerializers() {
|
|
expressionSerializer.registerTags({
|
|
"string": stringLiteralSerializer,
|
|
"int": intLiteralSerializer,
|
|
"double": doubleLiteralSerializer,
|
|
"bool": boolLiteralSerializer,
|
|
"null": nullLiteralSerializer,
|
|
"invalid": invalidExpressionSerializer,
|
|
"not": notSerializer,
|
|
"&&": logicalAndSerializer,
|
|
"||": logicalOrSerializer,
|
|
"concat": stringConcatenationSerializer,
|
|
"symbol": symbolLiteralSerializer,
|
|
"this": thisExpressionSerializer,
|
|
"rethrow": rethrowSerializer,
|
|
"throw": throwSerializer,
|
|
"await": awaitExpressionSerializer,
|
|
"cond": conditionalExpressionSerializer,
|
|
"is": isExpressionSerializer,
|
|
"as": asExpressionSerializer,
|
|
"type": typeLiteralSerializer,
|
|
"list": listLiteralSerializer,
|
|
"const-list": constListLiteralSerializer,
|
|
"set": setLiteralSerializer,
|
|
"const-set": constSetLiteralSerializer,
|
|
"map": mapLiteralSerializer,
|
|
"const-map": constMapLiteralSerializer,
|
|
"let": letSerializer,
|
|
"get-prop": propertyGetSerializer,
|
|
"set-prop": propertySetSerializer,
|
|
"get-super": superPropertyGetSerializer,
|
|
"set-super": superPropertySetSerializer,
|
|
"invoke-method": methodInvocationSerializer,
|
|
"invoke-super": superMethodInvocationSerializer,
|
|
"get-var": variableGetSerializer,
|
|
"set-var": variableSetSerializer,
|
|
"get-static": staticGetSerializer,
|
|
"set-static": staticSetSerializer,
|
|
"get-direct-prop": directPropertyGetSerializer,
|
|
"set-direct-prop": directPropertySetSerializer,
|
|
"invoke-static": staticInvocationSerializer,
|
|
"invoke-const-static": constStaticInvocationSerializer,
|
|
"invoke-direct-method": directMethodInvocationSerializer,
|
|
"invoke-constructor": constructorInvocationSerializer,
|
|
"invoke-const-constructor": constConstructorInvocationSerializer,
|
|
"fun": functionExpressionSerializer,
|
|
});
|
|
dartTypeSerializer.registerTags({
|
|
"invalid": invalidTypeSerializer,
|
|
"dynamic": dynamicTypeSerializer,
|
|
"void": voidTypeSerializer,
|
|
"bottom": bottomTypeSerializer,
|
|
"->": functionTypeSerializer,
|
|
"par": typeParameterTypeSerializer,
|
|
"interface": interfaceTypeSerializer,
|
|
"never": neverTypeSerializer,
|
|
"typedef": typedefTypeSerializer,
|
|
"futureor": futureOrTypeSerializer,
|
|
});
|
|
statementSerializer.registerTags({
|
|
"expr": expressionStatementSerializer,
|
|
"ret": returnStatementSerializer,
|
|
"ret-void": returnVoidStatementSerializer,
|
|
"yield": yieldStatementSerializer,
|
|
"block": blockSerializer,
|
|
"local": variableDeclarationSerializer,
|
|
"if": ifStatementSerializer,
|
|
"if-else": ifElseStatementSerializer,
|
|
"skip": emptyStatementSerializer,
|
|
"while": whileStatementSerializer,
|
|
"do-while": doStatementSerializer,
|
|
"for": forStatementSerializer,
|
|
"for-in": forInStatementSerializer,
|
|
"await-for-in": awaitForInStatementSerializer,
|
|
"assert": assertStatementSerializer,
|
|
"assert-block": assertBlockSerializer,
|
|
});
|
|
functionNodeSerializer.registerTags({
|
|
"sync": syncFunctionNodeSerializer,
|
|
"async": asyncFunctionNodeSerializer,
|
|
"sync-star": syncStarFunctionNodeSerializer,
|
|
"async-star": asyncStarFunctionNodeSerializer,
|
|
"sync-yielding": syncYieldingStarFunctionNodeSerializer,
|
|
});
|
|
procedureSerializer.registerTags({"static-method": staticMethodSerializer});
|
|
librarySerializer.registerTags({
|
|
"legacy": libraryContentsSerializer,
|
|
"null-safe": libraryContentsSerializer,
|
|
});
|
|
}
|