From 2eee76303fb0600bb7a750ca62886d54adede2b2 Mon Sep 17 00:00:00 2001 From: Dmitry Stefantsov Date: Tue, 7 Jul 2020 15:22:01 +0000 Subject: [PATCH] [cfe] Add support for constants to Kernel text serialization The CL also finalizes the support for expressions because the constant expressions can now be serialized. Change-Id: I7bc98fc974d3be1d4b9f1712cf67f9fbe6496e01 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153461 Reviewed-by: Johnni Winther Commit-Queue: Dmitry Stefantsov --- .../test/spell_checking_list_code.txt | 3 + .../test/spell_checking_list_common.txt | 1 + .../lib/text/serializer_combinators.dart | 51 ++++++ .../lib/text/text_serialization_verifier.dart | 24 +-- pkg/kernel/lib/text/text_serializer.dart | 146 ++++++++++++++++++ 5 files changed, 202 insertions(+), 23 deletions(-) diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt index 374afb8796d2..40340b49aa63 100644 --- a/pkg/front_end/test/spell_checking_list_code.txt +++ b/pkg/front_end/test/spell_checking_list_code.txt @@ -154,6 +154,7 @@ casing cast casted casts +ce cfe ch channel @@ -495,6 +496,7 @@ human i i'll i2b +ic id identifies identifying @@ -1138,6 +1140,7 @@ tuple2 tuple3 tuple4 tuple5 +tuple6 type1 type2 typeref diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt index 0e81968d08f4..dc86c98de2bd 100644 --- a/pkg/front_end/test/spell_checking_list_common.txt +++ b/pkg/front_end/test/spell_checking_list_common.txt @@ -2701,6 +2701,7 @@ sink sites situation situations +sixth skip skipped skipping diff --git a/pkg/kernel/lib/text/serializer_combinators.dart b/pkg/kernel/lib/text/serializer_combinators.dart index 3cc23ebbf950..91d4ac079994 100644 --- a/pkg/kernel/lib/text/serializer_combinators.dart +++ b/pkg/kernel/lib/text/serializer_combinators.dart @@ -466,6 +466,57 @@ class Tuple5 { const Tuple5(this.first, this.second, this.third, this.fourth, this.fifth); } +class Tuple6Serializer + extends TextSerializer> { + final TextSerializer first; + final TextSerializer second; + final TextSerializer third; + final TextSerializer fourth; + final TextSerializer fifth; + final TextSerializer sixth; + + const Tuple6Serializer( + this.first, this.second, this.third, this.fourth, this.fifth, this.sixth); + + Tuple6 readFrom( + Iterator stream, DeserializationState state) { + return new Tuple6( + first.readFrom(stream, state), + second.readFrom(stream, state), + third.readFrom(stream, state), + fourth.readFrom(stream, state), + fifth.readFrom(stream, state), + sixth.readFrom(stream, state)); + } + + void writeTo(StringBuffer buffer, Tuple6 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); + if (!sixth.isEmpty) buffer.write(' '); + sixth.writeTo(buffer, object.sixth, state); + } +} + +class Tuple6 { + final T1 first; + final T2 second; + final T3 third; + final T4 fourth; + final T5 fifth; + final T6 sixth; + + const Tuple6( + this.first, this.second, this.third, this.fourth, this.fifth, this.sixth); +} + // A serializer/deserializer for lists. class ListSerializer extends TextSerializer> { final TextSerializer elements; diff --git a/pkg/kernel/lib/text/text_serialization_verifier.dart b/pkg/kernel/lib/text/text_serialization_verifier.dart index 1b30a3129fea..6e570c6f5f97 100644 --- a/pkg/kernel/lib/text/text_serialization_verifier.dart +++ b/pkg/kernel/lib/text/text_serialization_verifier.dart @@ -322,12 +322,6 @@ class VerificationState { } } - static bool isExpressionSupported(Expression node) => - !isExpressionNotSupported(node); - - static bool isExpressionNotSupported(Expression node) => - node is InstanceCreation || node is ConstantExpression; - static bool isStatementSupported(Statement node) => !isStatementNotSupported(node); @@ -343,46 +337,30 @@ class VerificationState { static bool isSupported(Node node) => !isNotSupported(node); static bool isNotSupported(Node node) => - node is Expression && isExpressionNotSupported(node) || node is Statement && isStatementNotSupported(node) || node is FunctionNode && node.body == null || node is Procedure && (!node.isStatic || node.kind != ProcedureKind.Method) || node is AssertInitializer || - node is BoolConstant || node is Catch || node is Class || node is Component || node is Constructor || - node is DoubleConstant || node is Extension || node is Field || node is FieldInitializer || - node is InstanceConstant || - node is IntConstant || node is InvalidInitializer || node is Library || 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 || - node is PrimitiveConstant || node is RedirectingFactoryConstructor || node is RedirectingInitializer || - node is SetConstant || - node is StringConstant || node is SuperInitializer || node is Supertype || node is SwitchCase || - node is SymbolConstant || - node is TearOffConstant || - node is TypeLiteralConstant || - node is Typedef || - node is UnevaluatedConstant; + node is Typedef; } class TextSerializationVerifier extends RecursiveVisitor { diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart index 6ff9d8f9f520..fcb5e0133605 100644 --- a/pkg/kernel/lib/text/text_serializer.dart +++ b/pkg/kernel/lib/text/text_serializer.dart @@ -121,6 +121,8 @@ class ExpressionTagger extends ExpressionVisitor String visitFileUriExpression(FileUriExpression _) => "with-uri"; String visitCheckLibraryIsLoaded(CheckLibraryIsLoaded _) => "is-loaded"; String visitLoadLibrary(LoadLibrary _) => "load"; + String visitConstantExpression(ConstantExpression _) => "const"; + String visitInstanceCreation(InstanceCreation _) => "object"; } const TextSerializer invalidExpressionSerializer = @@ -740,6 +742,29 @@ TextSerializer checkLibraryIsLoadedSerializer = Wrapped( TextSerializer loadLibrarySerializer = Wrapped( (ll) => ll.import, (i) => LoadLibrary(i), libraryDependencySerializer); +TextSerializer constantExpressionSerializer = Wrapped( + (ce) => Tuple2(ce.constant, ce.type), + (t) => ConstantExpression(t.first, t.second), + Tuple2Serializer(constantSerializer, dartTypeSerializer)); + +TextSerializer instanceCreationSerializer = Wrapped( + (ic) => Tuple6( + ic.classReference.canonicalName, + ic.typeArguments, + ic.fieldValues.keys.map((r) => r.canonicalName).toList(), + ic.fieldValues.values.toList(), + ic.asserts, + ic.unusedArguments), + (t) => InstanceCreation(t.first.getReference(), t.second, + Map.fromIterables(t.third, t.fourth), t.fifth, t.sixth), + Tuple6Serializer( + CanonicalNameSerializer(), + ListSerializer(dartTypeSerializer), + ListSerializer(CanonicalNameSerializer()), + ListSerializer(expressionSerializer), + ListSerializer(assertStatementSerializer), + ListSerializer(expressionSerializer))); + Case expressionSerializer = new Case.uninitialized(const ExpressionTagger()); @@ -1605,6 +1630,109 @@ TextSerializer libraryDependencySerializer = Wrapped( DartInt(), ListSerializer(expressionSerializer))); +class ConstantTagger extends ConstantVisitor + implements Tagger { + const ConstantTagger(); + + String tag(Constant node) => node.accept(this); + + String visitBoolConstant(BoolConstant node) => "const-bool"; + String visitDoubleConstant(DoubleConstant node) => "const-double"; + String visitInstanceConstant(InstanceConstant node) => "const-object"; + String visitIntConstant(IntConstant node) => "const-int"; + String visitListConstant(ListConstant node) => "const-list"; + String visitMapConstant(MapConstant node) => "const-map"; + String visitNullConstant(NullConstant node) => "const-null"; + String visitPartialInstantiationConstant(PartialInstantiationConstant node) => + "const-apply"; + String visitSetConstant(SetConstant node) => "const-set"; + String visitStringConstant(StringConstant node) => "const-string"; + String visitSymbolConstant(SymbolConstant node) => "const-symbol"; + String visitTearOffConstant(TearOffConstant node) => "const-tearoff"; + String visitTypeLiteralConstant(TypeLiteralConstant node) => "const-type"; + String visitUnevaluatedConstant(UnevaluatedConstant node) => "const-expr"; +} + +TextSerializer boolConstantSerializer = + Wrapped((w) => w.value, (u) => BoolConstant(u), DartBool()); + +TextSerializer doubleConstantSerializer = + Wrapped((w) => w.value, (u) => DoubleConstant(u), DartDouble()); + +TextSerializer intConstantSerializer = + Wrapped((w) => w.value, (u) => IntConstant(u), DartInt()); + +TextSerializer listConstantSerializer = Wrapped( + (w) => Tuple2(w.typeArgument, w.entries), + (u) => ListConstant(u.first, u.second), + Tuple2Serializer(dartTypeSerializer, ListSerializer(constantSerializer))); + +TextSerializer mapConstantSerializer = Wrapped( + (w) => Tuple3(w.keyType, w.valueType, w.entries), + (u) => MapConstant(u.first, u.second, u.third), + Tuple3Serializer( + dartTypeSerializer, + dartTypeSerializer, + Zip( + Tuple2Serializer(ListSerializer(constantSerializer), + ListSerializer(constantSerializer)), + (k, v) => ConstantMapEntry(k, v), + (z) => Tuple2(z.key, z.value)))); + +TextSerializer nullConstantSerializer = + Wrapped((w) => null, (u) => NullConstant(), Nothing()); + +TextSerializer + partialInstantiationConstantSerializer = Wrapped( + (w) => Tuple2(w.tearOffConstant, w.types), + (u) => PartialInstantiationConstant(u.first, u.second), + Tuple2Serializer( + tearOffConstantSerializer, ListSerializer(dartTypeSerializer))); + +TextSerializer setConstantSerializer = Wrapped( + (w) => Tuple2(w.typeArgument, w.entries), + (u) => SetConstant(u.first, u.second), + Tuple2Serializer(dartTypeSerializer, ListSerializer(constantSerializer))); + +TextSerializer stringConstantSerializer = + Wrapped((w) => w.value, (u) => StringConstant(u), DartString()); + +TextSerializer symbolConstantSerializer = Wrapped( + (w) => Tuple2(w.name, w.libraryReference?.canonicalName), + (u) => SymbolConstant(u.first, u.second?.getReference()), + Tuple2Serializer(DartString(), Optional(CanonicalNameSerializer()))); + +TextSerializer tearOffConstantSerializer = Wrapped( + (w) => w.procedureReference.canonicalName, + (u) => TearOffConstant.byReference(u.getReference()), + CanonicalNameSerializer()); + +TextSerializer typeLiteralConstantSerializer = + Wrapped((w) => w.type, (u) => TypeLiteralConstant(u), dartTypeSerializer); + +TextSerializer unevaluatedConstantSerializer = Wrapped( + (w) => w.expression, (u) => UnevaluatedConstant(u), expressionSerializer); + +TextSerializer instanceConstantSerializer = + Wrapped< + Tuple4, List, + List>, + InstanceConstant>( + (w) => Tuple4( + w.classReference.canonicalName, + w.typeArguments, + w.fieldValues.keys.map((r) => r.canonicalName).toList(), + w.fieldValues.values.toList()), + (u) => InstanceConstant(u.first.getReference(), u.second, + Map.fromIterables(u.third.map((c) => c.getReference()), u.fourth)), + Tuple4Serializer( + CanonicalNameSerializer(), + ListSerializer(dartTypeSerializer), + ListSerializer(CanonicalNameSerializer()), + ListSerializer(constantSerializer))); + +Case constantSerializer = Case.uninitialized(ConstantTagger()); + void initializeSerializers() { expressionSerializer.registerTags({ "string": stringLiteralSerializer, @@ -1660,6 +1788,8 @@ void initializeSerializers() { "with-uri": fileUriExpressionSerializer, "is-loaded": checkLibraryIsLoadedSerializer, "load": loadLibrarySerializer, + "const": constantExpressionSerializer, + "object": instanceCreationSerializer, }); dartTypeSerializer.registerTags({ "invalid": invalidTypeSerializer, @@ -1705,4 +1835,20 @@ void initializeSerializers() { "legacy": libraryContentsSerializer, "null-safe": libraryContentsSerializer, }); + constantSerializer.registerTags({ + "const-bool": boolConstantSerializer, + "const-double": doubleConstantSerializer, + "const-int": intConstantSerializer, + "const-list": listConstantSerializer, + "const-map": mapConstantSerializer, + "const-null": nullConstantSerializer, + "const-apply": partialInstantiationConstantSerializer, + "const-set": setConstantSerializer, + "const-string": stringConstantSerializer, + "const-symbol": symbolConstantSerializer, + "const-tearoff": tearOffConstantSerializer, + "const-type": typeLiteralConstantSerializer, + "const-expr": unevaluatedConstantSerializer, + "const-object": instanceConstantSerializer, + }); }