Skip to content

Commit

Permalink
[cfe] Support more Expression nodes in text serialization
Browse files Browse the repository at this point in the history
The following nodes are now supported:
* SetConcatenation
* MapConcatenation
* FileUriExpression
* BlockExpression
* ListConcatenation
* NullCheck
* Instantiation
* CheckLibraryIsLoaded
* LoadLibrary

Change-Id: Ia269196c36facb211995d0ef8cd8a68cbf836e37
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153346
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
  • Loading branch information
Dmitry Stefantsov authored and commit-bot@chromium.org committed Jul 7, 2020
1 parent da87123 commit e196354
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 28 deletions.
8 changes: 8 additions & 0 deletions pkg/front_end/test/spell_checking_list_code.txt
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ class6a
class6b
clazz
cli
clil
clock
cls
cn
Expand Down Expand Up @@ -432,6 +433,7 @@ frontend
frontends
fs
fsource
fue
fuller
function's
fuse
Expand Down Expand Up @@ -577,6 +579,8 @@ largest
lattice
layer
layout
lc
ld
leafp
len
lets
Expand All @@ -593,6 +597,7 @@ linearized
linebreak
linter
lives
ll
llub
lm
locationd
Expand Down Expand Up @@ -622,6 +627,7 @@ masking
master
matcher
mb
mc
md
me
merely
Expand Down Expand Up @@ -679,6 +685,7 @@ nameless
namer
natively
nbsp
nc
ncs
ncurses
nd
Expand Down Expand Up @@ -1130,6 +1137,7 @@ tuple
tuple2
tuple3
tuple4
tuple5
type1
type2
typeref
Expand Down
3 changes: 2 additions & 1 deletion pkg/front_end/test/spell_checking_list_common.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1083,8 +1083,8 @@ experimental
experimentally
experiments
expired
explanation
explain
explanation
explicit
explicitly
exponent
Expand Down Expand Up @@ -1152,6 +1152,7 @@ field
field's
fieldname
fields
fifth
figure
file
filename
Expand Down
45 changes: 45 additions & 0 deletions pkg/kernel/lib/text/serializer_combinators.dart
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,51 @@ class Tuple4<T1, T2, T3, T4> {
const Tuple4(this.first, this.second, this.third, this.fourth);
}

class Tuple5Serializer<T1, T2, T3, T4, T5>
extends TextSerializer<Tuple5<T1, T2, T3, T4, T5>> {
final TextSerializer<T1> first;
final TextSerializer<T2> second;
final TextSerializer<T3> third;
final TextSerializer<T4> fourth;
final TextSerializer<T5> fifth;

const Tuple5Serializer(
this.first, this.second, this.third, this.fourth, this.fifth);

Tuple5<T1, T2, T3, T4, T5> readFrom(
Iterator<Object> stream, DeserializationState state) {
return new Tuple5(
first.readFrom(stream, state),
second.readFrom(stream, state),
third.readFrom(stream, state),
fourth.readFrom(stream, state),
fifth.readFrom(stream, state));
}

void writeTo(StringBuffer buffer, Tuple5<T1, T2, T3, T4, T5> object,
SerializationState state) {
first.writeTo(buffer, object.first, state);
if (!second.isEmpty) buffer.write(' ');
second.writeTo(buffer, object.second, state);
if (!third.isEmpty) buffer.write(' ');
third.writeTo(buffer, object.third, state);
if (!fourth.isEmpty) buffer.write(' ');
fourth.writeTo(buffer, object.fourth, state);
if (!fifth.isEmpty) buffer.write(' ');
fifth.writeTo(buffer, object.fifth, state);
}
}

class Tuple5<T1, T2, T3, T4, T5> {
final T1 first;
final T2 second;
final T3 third;
final T4 fourth;
final T5 fifth;

const Tuple5(this.first, this.second, this.third, this.fourth, this.fifth);
}

// A serializer/deserializer for lists.
class ListSerializer<T> extends TextSerializer<List<T>> {
final TextSerializer<T> elements;
Expand Down
21 changes: 6 additions & 15 deletions pkg/kernel/lib/text/text_serialization_verifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -326,19 +326,7 @@ class VerificationState {
!isExpressionNotSupported(node);

static bool isExpressionNotSupported(Expression node) =>
node is SetConcatenation ||
node is MapConcatenation ||
node is InstanceCreation ||
node is FileUriExpression ||
node is BlockExpression ||
node is ListConcatenation ||
node is NullCheck ||
node is BasicLiteral ||
node is InvocationExpression ||
node is Instantiation ||
node is ConstantExpression ||
node is CheckLibraryIsLoaded ||
node is LoadLibrary;
node is InstanceCreation || node is ConstantExpression;

static bool isStatementSupported(Statement node) =>
!isStatementNotSupported(node);
Expand All @@ -364,7 +352,6 @@ class VerificationState {
node is BoolConstant ||
node is Catch ||
node is Class ||
node is Combinator ||
node is Component ||
node is Constructor ||
node is DoubleConstant ||
Expand All @@ -375,11 +362,11 @@ class VerificationState {
node is IntConstant ||
node is InvalidInitializer ||
node is Library ||
node is LibraryDependency ||
node is LibraryPart ||
node is ListConstant ||
node is LocalInitializer ||
node is MapConstant ||
node is MapEntry ||
node is Name && node.isPrivate ||
node is NullConstant ||
node is PartialInstantiationConstant ||
Expand Down Expand Up @@ -532,6 +519,10 @@ class TextSerializationVerifier extends RecursiveVisitor<void> {
makeRoundTrip<NamedType>(node, namedTypeSerializer);
} else if (node is Name) {
makeRoundTrip<Name>(node, nameSerializer);
} else if (node is Combinator) {
makeRoundTrip<Combinator>(node, showHideSerializer);
} else if (node is LibraryDependency) {
makeRoundTrip<LibraryDependency>(node, libraryDependencySerializer);
} else {
throw new StateError(
"Don't know how to make a round trip for a supported node "
Expand Down
103 changes: 91 additions & 12 deletions pkg/kernel/lib/text/text_serializer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ class ExpressionTagger extends ExpressionVisitor<String>
}

String visitFunctionExpression(FunctionExpression _) => "fun";
String visitListConcatenation(ListConcatenation _) => "lists";
String visitSetConcatenation(SetConcatenation _) => "sets";
String visitMapConcatenation(MapConcatenation _) => "maps";
String visitBlockExpression(BlockExpression _) => "let-block";
String visitInstantiation(Instantiation _) => "apply";
String visitNullCheck(NullCheck _) => "not-null";
String visitFileUriExpression(FileUriExpression _) => "with-uri";
String visitCheckLibraryIsLoaded(CheckLibraryIsLoaded _) => "is-loaded";
String visitLoadLibrary(LoadLibrary _) => "load";
}

const TextSerializer<InvalidExpression> invalidExpressionSerializer =
Expand Down Expand Up @@ -689,6 +698,48 @@ FunctionExpression wrapFunctionExpression(FunctionNode node) {
return new FunctionExpression(node);
}

TextSerializer<ListConcatenation> listConcatenationSerializer = Wrapped(
(lc) => Tuple2(lc.typeArgument, lc.lists),
(t) => ListConcatenation(t.second, typeArgument: t.first),
Tuple2Serializer(dartTypeSerializer, ListSerializer(expressionSerializer)));

TextSerializer<SetConcatenation> setConcatenationSerializer = Wrapped(
(sc) => Tuple2(sc.typeArgument, sc.sets),
(t) => SetConcatenation(t.second, typeArgument: t.first),
Tuple2Serializer(dartTypeSerializer, ListSerializer(expressionSerializer)));

TextSerializer<MapConcatenation> mapConcatenationSerializer = Wrapped(
(mc) => Tuple3(mc.keyType, mc.valueType, mc.maps),
(t) => MapConcatenation(t.third, keyType: t.first, valueType: t.second),
Tuple3Serializer(dartTypeSerializer, dartTypeSerializer,
ListSerializer(expressionSerializer)));

TextSerializer<BlockExpression> blockExpressionSerializer = Wrapped(
(be) => Tuple2(be.body, be.value),
(t) => BlockExpression(t.first, t.second),
Tuple2Serializer(blockSerializer, expressionSerializer));

TextSerializer<Instantiation> instantiationSerializer = Wrapped(
(i) => Tuple2(i.expression, i.typeArguments),
(t) => Instantiation(t.first, t.second),
Tuple2Serializer(expressionSerializer, ListSerializer(dartTypeSerializer)));

TextSerializer<NullCheck> nullCheckSerializer =
Wrapped((nc) => nc.operand, (op) => NullCheck(op), expressionSerializer);

TextSerializer<FileUriExpression> fileUriExpressionSerializer = Wrapped(
(fue) => Tuple2(fue.expression, fue.fileUri),
(t) => FileUriExpression(t.first, t.second),
Tuple2Serializer(expressionSerializer, const UriSerializer()));

TextSerializer<CheckLibraryIsLoaded> checkLibraryIsLoadedSerializer = Wrapped(
(clil) => clil.import,
(i) => CheckLibraryIsLoaded(i),
libraryDependencySerializer);

TextSerializer<LoadLibrary> loadLibrarySerializer = Wrapped(
(ll) => ll.import, (i) => LoadLibrary(i), libraryDependencySerializer);

Case<Expression> expressionSerializer =
new Case.uninitialized(const ExpressionTagger());

Expand Down Expand Up @@ -1067,18 +1118,10 @@ 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<AssertStatement> assertStatementSerializer = Wrapped(
(a) => Tuple2(a.condition, a.message),
(t) => AssertStatement(t.first, message: t.second),
Tuple2Serializer(expressionSerializer, Optional(expressionSerializer)));

TextSerializer<Block> blockSerializer =
new Wrapped(unwrapBlock, wrapBlock, const BlockSerializer());
Expand Down Expand Up @@ -1535,6 +1578,33 @@ Library wrapLibraryNode(Tuple2<Uri, List<Procedure>> tuple) {

Case<Library> librarySerializer = new Case.uninitialized(const LibraryTagger());

class ShowHideTagger implements Tagger<Combinator> {
String tag(Combinator node) => node.isShow ? "show" : "hide";
}

TextSerializer<Combinator> showSerializer = Wrapped(
(c) => c.names, (ns) => Combinator(true, ns), ListSerializer(DartString()));

TextSerializer<Combinator> hideSerializer = Wrapped((c) => c.names,
(ns) => Combinator(false, ns), ListSerializer(DartString()));

Case<Combinator> showHideSerializer = new Case(ShowHideTagger(), {
"show": showSerializer,
"hide": hideSerializer,
});

TextSerializer<LibraryDependency> libraryDependencySerializer = Wrapped(
(ld) => Tuple5(ld.importedLibraryReference.canonicalName, ld.name,
ld.combinators, ld.flags, ld.annotations),
(t) => LibraryDependency.byReference(
t.fourth, t.fifth, t.first.getReference(), t.second, t.third),
Tuple5Serializer(
CanonicalNameSerializer(),
Optional(DartString()),
ListSerializer(showHideSerializer),
DartInt(),
ListSerializer(expressionSerializer)));

void initializeSerializers() {
expressionSerializer.registerTags({
"string": stringLiteralSerializer,
Expand Down Expand Up @@ -1581,6 +1651,15 @@ void initializeSerializers() {
"invoke-constructor": constructorInvocationSerializer,
"invoke-const-constructor": constConstructorInvocationSerializer,
"fun": functionExpressionSerializer,
"lists": listConcatenationSerializer,
"sets": setConcatenationSerializer,
"maps": mapConcatenationSerializer,
"let-block": blockExpressionSerializer,
"apply": instantiationSerializer,
"not-null": nullCheckSerializer,
"with-uri": fileUriExpressionSerializer,
"is-loaded": checkLibraryIsLoadedSerializer,
"load": loadLibrarySerializer,
});
dartTypeSerializer.registerTags({
"invalid": invalidTypeSerializer,
Expand Down

0 comments on commit e196354

Please sign in to comment.