Chromium Code Reviews| Index: pkg/compiler/lib/src/serialization/constant_serialization.dart |
| diff --git a/pkg/compiler/lib/src/serialization/constant_serialization.dart b/pkg/compiler/lib/src/serialization/constant_serialization.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..fd389f74e9fdbad1739accff0588d844c8cd5ac6 |
| --- /dev/null |
| +++ b/pkg/compiler/lib/src/serialization/constant_serialization.dart |
| @@ -0,0 +1,403 @@ |
| +// Copyright (c) 2015, 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 dart2js.serialization.constants; |
| + |
| +import '../constants/expressions.dart'; |
| +import '../dart_types.dart'; |
| +import '../elements/elements.dart' show FieldElement; |
| +import '../resolution/operators.dart'; |
| +import '../universe/universe.dart'; |
| +import 'serialization.dart'; |
| +import 'keys.dart'; |
| + |
| +class ConstantSerializer |
|
floitsch
2015/06/26 20:54:04
Comment what this class does.
Destructures, decom
Johnni Winther
2015/07/03 12:13:44
Done.
|
| + extends ConstantExpressionVisitor<dynamic, ObjectSerializer> { |
| + const ConstantSerializer(); |
| + |
| + void apply(ConstantExpression exp, ObjectSerializer serializer) { |
|
floitsch
2015/06/26 20:54:04
I prefer to call this "visit", but I have seen "ap
Johnni Winther
2015/07/03 12:13:44
Done.
|
| + exp.accept(this, serializer); |
| + } |
| + |
| + @override |
| + void visitBinary(BinaryConstantExpression exp, |
| + ObjectSerializer serializer) { |
| + serializer.setEnum(Key.OPERATOR, exp.operator.kind); |
| + serializer.setConstant(Key.LEFT, exp.left); |
| + serializer.setConstant(Key.RIGHT, exp.right); |
| + } |
| + |
| + @override |
| + void visitConcatenate(ConcatenateConstantExpression exp, |
| + ObjectSerializer serializer) { |
| + serializer.setConstants(Key.ARGUMENTS, exp.expressions); |
| + } |
| + |
| + @override |
| + void visitConditional(ConditionalConstantExpression exp, |
| + ObjectSerializer serializer) { |
| + serializer.setConstant(Key.CONDITION, exp.condition); |
| + serializer.setConstant(Key.TRUE, exp.trueExp); |
| + serializer.setConstant(Key.FALSE, exp.falseExp); |
| + } |
| + |
| + @override |
| + void visitConstructed(ConstructedConstantExpression exp, |
| + ObjectSerializer serializer) { |
| + serializer.setElement(Key.ELEMENT, exp.target); |
| + serializer.setType(Key.TYPE, exp.type); |
| + serializer.setStrings(Key.NAMES, exp.callStructure.namedArguments); |
| + serializer.setConstants(Key.ARGUMENTS, exp.arguments); |
| + } |
| + |
| + @override |
| + void visitFunction(FunctionConstantExpression exp, |
| + ObjectSerializer serializer) { |
| + serializer.setElement(Key.ELEMENT, exp.element); |
| + } |
| + |
| + @override |
| + void visitIdentical(IdenticalConstantExpression exp, |
| + ObjectSerializer serializer) { |
| + serializer.setConstant(Key.LEFT, exp.left); |
| + serializer.setConstant(Key.RIGHT, exp.right); |
| + } |
| + |
| + @override |
| + void visitList(ListConstantExpression exp, ObjectSerializer serializer) { |
| + serializer.setType(Key.TYPE, exp.type); |
| + serializer.setConstants(Key.VALUES, exp.values); |
| + } |
| + |
| + @override |
| + void visitMap(MapConstantExpression exp, ObjectSerializer serializer) { |
| + serializer.setType(Key.TYPE, exp.type); |
| + serializer.setConstants(Key.KEYS, exp.keys); |
| + serializer.setConstants(Key.VALUES, exp.values); |
| + } |
| + |
| + @override |
| + void visitBool(BoolConstantExpression exp, ObjectSerializer serializer) { |
| + serializer.setBool(Key.VALUE, exp.primitiveValue); |
| + } |
| + |
| + @override |
| + void visitInt(IntConstantExpression exp, ObjectSerializer serializer) { |
| + serializer.setInt(Key.VALUE, exp.primitiveValue); |
| + } |
| + |
| + @override |
| + void visitDouble(DoubleConstantExpression exp, ObjectSerializer serializer) { |
| + serializer.setDouble(Key.VALUE, exp.primitiveValue); |
| + } |
| + |
| + @override |
| + void visitString(StringConstantExpression exp, ObjectSerializer serializer) { |
| + serializer.setString(Key.VALUE, exp.primitiveValue); |
| + } |
| + |
| + @override |
| + void visitNull(NullConstantExpression exp, ObjectSerializer serializer) { |
| + // No additional data needed. |
| + } |
| + |
| + @override |
| + void visitSymbol(SymbolConstantExpression exp, |
| + ObjectSerializer serializer) { |
|
floitsch
2015/06/26 20:54:04
indentation.
Johnni Winther
2015/07/03 12:13:44
Done.
|
| + throw new UnsupportedError( |
| + "ConstantSerializer.visitSymbol: ${exp.getText()}"); |
| + } |
| + |
| + @override |
| + void visitType(TypeConstantExpression exp, |
| + ObjectSerializer serializer) { |
|
floitsch
2015/06/26 20:54:04
ditto and below.
Johnni Winther
2015/07/03 12:13:44
Done.
|
| + serializer.setType(Key.TYPE, exp.type); |
| + } |
| + |
| + @override |
| + void visitUnary(UnaryConstantExpression exp, |
| + ObjectSerializer serializer) { |
| + serializer.setEnum(Key.OPERATOR, exp.operator.kind); |
| + serializer.setConstant(Key.EXPRESSION, exp.expression); |
| + } |
| + |
| + @override |
| + void visitVariable(VariableConstantExpression exp, |
| + ObjectSerializer serializer) { |
| + serializer.setElement(Key.ELEMENT, exp.element); |
| + } |
| + |
| + @override |
| + void visitPositional(PositionalArgumentReference exp, |
| + ObjectSerializer serializer) { |
| + serializer.setInt(Key.INDEX, exp.index); |
| + } |
| + |
| + @override |
| + void visitNamed(NamedArgumentReference exp, ObjectSerializer serializer) { |
| + serializer.setString(Key.NAME, exp.name); |
| + } |
| + |
| + @override |
| + void visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp, |
| + ObjectSerializer serializer) { |
| + serializer.setConstant(Key.NAME, exp.name); |
| + if (exp.defaultValue != null) { |
| + serializer.setConstant(Key.DEFAULT, exp.defaultValue); |
| + } |
| + } |
| + |
| + @override |
| + void visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp, |
| + ObjectSerializer serializer) { |
| + serializer.setConstant(Key.NAME, exp.name); |
| + if (exp.defaultValue != null) { |
| + serializer.setConstant(Key.DEFAULT, exp.defaultValue); |
| + } |
| + } |
| + |
| + @override |
| + void visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp, |
| + ObjectSerializer serializer) { |
| + serializer.setConstant(Key.NAME, exp.name); |
| + if (exp.defaultValue != null) { |
| + serializer.setConstant(Key.DEFAULT, exp.defaultValue); |
| + } |
| + } |
| + |
| + @override |
| + void visitStringLength(StringLengthConstantExpression exp, |
| + ObjectSerializer serializer) { |
| + serializer.setConstant(Key.EXPRESSION, exp.expression); |
| + } |
| + |
| + |
| + @override |
| + void visitDeferred(DeferredConstantExpression exp, |
| + ObjectSerializer serializer) { |
| + throw new UnsupportedError( |
| + "ConstantSerializer.visitDeferred: ${exp.getText()}"); |
| + } |
| +} |
| + |
| +class ConstantDeserializer { |
|
floitsch
2015/06/26 20:54:04
Ditto.
Johnni Winther
2015/07/03 12:13:44
Done.
|
| + static ConstantExpression deserialize(ObjectDeserializer deserializer) { |
| + ConstantExpressionKind kind = |
| + deserializer.getEnum(Key.KIND, ConstantExpressionKind.values); |
| + switch (kind) { |
| + case ConstantExpressionKind.BINARY: |
| + BinaryOperator operator = BinaryOperator.fromKind(deserializer.getEnum( |
| + Key.OPERATOR, BinaryOperatorKind.values)); |
| + return new BinaryConstantExpression( |
| + deserializer.getConstant(Key.LEFT), |
| + operator, |
| + deserializer.getConstant(Key.RIGHT)); |
| + case ConstantExpressionKind.BOOL: |
| + return new BoolConstantExpression( |
| + deserializer.getBool(Key.VALUE)); |
| + case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT: |
| + return new BoolFromEnvironmentConstantExpression( |
| + deserializer.getConstant(Key.NAME), |
| + deserializer.getConstant(Key.DEFAULT, isOptional: true)); |
| + case ConstantExpressionKind.CONCATENATE: |
| + return new ConcatenateConstantExpression( |
| + deserializer.getConstants(Key.ARGUMENTS)); |
| + case ConstantExpressionKind.CONDITIONAL: |
| + return new ConditionalConstantExpression( |
| + deserializer.getConstant(Key.CONDITION), |
| + deserializer.getConstant(Key.TRUE), |
| + deserializer.getConstant(Key.FALSE)); |
| + case ConstantExpressionKind.CONSTRUCTED: |
| + List<String> names = |
| + deserializer.getStrings(Key.NAMES, isOptional: true); |
| + List<ConstantExpression> arguments = |
| + deserializer.getConstants(Key.ARGUMENTS, isOptional: true); |
| + return new ConstructedConstantExpression( |
| + deserializer.getType(Key.TYPE), |
| + deserializer.getElement(Key.ELEMENT), |
| + new CallStructure(arguments.length, names), |
| + arguments); |
| + case ConstantExpressionKind.DOUBLE: |
| + return new DoubleConstantExpression(deserializer.getDouble(Key.VALUE)); |
| + case ConstantExpressionKind.ERRONEOUS: |
| + break; |
| + case ConstantExpressionKind.FUNCTION: |
| + return new FunctionConstantExpression( |
| + deserializer.getElement(Key.ELEMENT)); |
| + case ConstantExpressionKind.IDENTICAL: |
| + return new IdenticalConstantExpression( |
| + deserializer.getConstant(Key.LEFT), |
| + deserializer.getConstant(Key.RIGHT)); |
| + case ConstantExpressionKind.INT: |
| + return new IntConstantExpression(deserializer.getInt(Key.VALUE)); |
| + case ConstantExpressionKind.INT_FROM_ENVIRONMENT: |
| + return new IntFromEnvironmentConstantExpression( |
| + deserializer.getConstant(Key.NAME), |
| + deserializer.getConstant(Key.DEFAULT, isOptional: true)); |
| + case ConstantExpressionKind.LIST: |
| + return new ListConstantExpression( |
| + deserializer.getType(Key.TYPE), |
| + deserializer.getConstants(Key.VALUES)); |
| + case ConstantExpressionKind.MAP: |
| + return new MapConstantExpression( |
| + deserializer.getType(Key.TYPE), |
| + deserializer.getConstants(Key.KEYS), |
| + deserializer.getConstants(Key.VALUES)); |
| + case ConstantExpressionKind.NULL: |
| + return new NullConstantExpression(); |
| + case ConstantExpressionKind.STRING: |
| + return new StringConstantExpression( |
| + deserializer.getString(Key.VALUE)); |
| + case ConstantExpressionKind.STRING_FROM_ENVIRONMENT: |
| + return new StringFromEnvironmentConstantExpression( |
| + deserializer.getConstant(Key.NAME), |
| + deserializer.getConstant(Key.DEFAULT, isOptional: true)); |
| + case ConstantExpressionKind.STRING_LENGTH: |
| + return new StringLengthConstantExpression( |
| + deserializer.getConstant(Key.EXPRESSION)); |
| + case ConstantExpressionKind.SYMBOL: |
| + break; |
| + case ConstantExpressionKind.TYPE: |
| + return new TypeConstantExpression(deserializer.getType(Key.TYPE)); |
| + case ConstantExpressionKind.UNARY: |
| + UnaryOperator operator = UnaryOperator.fromKind( |
| + deserializer.getEnum(Key.OPERATOR, UnaryOperatorKind.values)); |
| + return new UnaryConstantExpression( |
| + operator, |
| + deserializer.getConstant(Key.EXPRESSION)); |
| + case ConstantExpressionKind.VARIABLE: |
| + return new VariableConstantExpression( |
| + deserializer.getElement(Key.ELEMENT)); |
| + |
| + case ConstantExpressionKind.POSITIONAL_REFERENCE: |
| + return new PositionalArgumentReference( |
| + deserializer.getInt(Key.INDEX)); |
| + case ConstantExpressionKind.NAMED_REFERENCE: |
| + return new NamedArgumentReference( |
| + deserializer.getString(Key.NAME)); |
| + case ConstantExpressionKind.DEFERRED: |
| + case ConstantExpressionKind.SYNTHETIC: |
| + } |
| + throw new UnsupportedError( |
| + "Unexpected constant kind: ${kind} in $deserializer"); |
| + } |
| +} |
| + |
| +/// Serializer for [ConstantConstructor]s. |
| +class ConstantConstructorSerializer |
| + extends ConstantConstructorVisitor<dynamic, ObjectSerializer> { |
| + const ConstantConstructorSerializer(); |
| + |
| + @override |
| + void visit(ConstantConstructor constantConstructor, |
| + ObjectSerializer serializer) { |
|
floitsch
2015/06/26 20:54:04
indentation.
Johnni Winther
2015/07/03 12:13:44
Done.
|
| + serializer.setEnum(Key.KIND, constantConstructor.kind); |
| + constantConstructor.accept(this, serializer); |
| + } |
| + |
| + @override |
| + void visitGenerative( |
| + GenerativeConstantConstructor constructor, |
| + ObjectSerializer serializer) { |
| + serializer.setType(Key.TYPE, constructor.type); |
| + MapSerializer defaults = serializer.createMap(Key.DEFAULTS); |
| + constructor.defaultValues.forEach((key, e) { |
| + defaults.setConstant('$key', e); |
| + }); |
| + ListSerializer fields = serializer.createList(Key.FIELDS); |
| + constructor.fieldMap.forEach((FieldElement f, ConstantExpression e) { |
| + ObjectSerializer fieldSerializer = fields.createObject(); |
| + fieldSerializer.setElement(Key.FIELD, f); |
| + fieldSerializer.setConstant(Key.CONSTANT, e); |
| + }); |
| + if (constructor.superConstructorInvocation != null) { |
| + serializer.setConstant(Key.CONSTRUCTOR, |
| + constructor.superConstructorInvocation); |
| + } |
| + } |
| + |
| + @override |
| + void visitRedirectingFactory( |
| + RedirectingFactoryConstantConstructor constructor, |
| + ObjectSerializer serializer) { |
| + serializer.setConstant(Key.CONSTRUCTOR, |
| + constructor.targetConstructorInvocation); |
| + } |
| + |
| + @override |
| + void visitRedirectingGenerative( |
| + RedirectingGenerativeConstantConstructor constructor, |
| + ObjectSerializer serializer) { |
| + MapSerializer defaults = serializer.createMap(Key.DEFAULTS); |
| + constructor.defaultValues.forEach((key, ConstantExpression e) { |
| + defaults.setConstant('$key', e); |
| + }); |
| + serializer.setConstant(Key.CONSTRUCTOR, |
| + constructor.thisConstructorInvocation); |
| + } |
| +} |
| + |
| +class ConstantConstructorDeserializer { |
| + static ConstantConstructor deserialize(ObjectDeserializer deserializer) { |
| + |
| + ConstantConstructorKind kind = |
| + deserializer.getEnum(Key.KIND, ConstantConstructorKind.values); |
| + |
| + DartType readType() { |
| + return deserializer.getType(Key.TYPE); |
| + } |
| + |
| + Map<dynamic/*int|String*/, ConstantExpression> readDefaults() { |
| + Map<dynamic, ConstantExpression> defaultValues = |
| + <dynamic, ConstantExpression>{}; |
| + if (deserializer.containsKey(Key.DEFAULTS)) { |
| + MapDeserializer defaultsMap = deserializer.getMap(Key.DEFAULTS); |
| + defaultsMap.forEachKey((String key) { |
| + try { |
| + int index = int.parse(key); |
| + defaultValues[index] = defaultsMap.getConstant(key); |
| + } catch (e) { |
|
floitsch
2015/06/26 20:54:04
don't use try/catch.
if it's for the 'int.parse',
Johnni Winther
2015/07/03 12:13:44
Done.
|
| + defaultValues[key] = defaultsMap.getConstant(key); |
| + } |
| + }); |
| + } |
| + return defaultValues; |
| + } |
| + |
| + Map<FieldElement, ConstantExpression> readFields() { |
| + Map<FieldElement, ConstantExpression> fieldMap = |
| + <FieldElement, ConstantExpression>{}; |
| + if (deserializer.containsKey(Key.FIELDS)) { |
| + ListDeserializer fieldsList = deserializer.getList(Key.FIELDS); |
| + for (int i = 0; i < fieldsList.length; i++) { |
| + ObjectDeserializer object = fieldsList.getObject(i); |
| + FieldElement field = object.getElement(Key.FIELD); |
| + ConstantExpression constant = object.getConstant(Key.CONSTANT); |
| + fieldMap[field] = constant; |
| + } |
| + } |
| + return fieldMap; |
| + } |
| + |
| + ConstructedConstantExpression readConstructorInvocation() { |
| + return deserializer.getConstant(Key.CONSTRUCTOR, isOptional: true); |
| + } |
| + |
| + switch (kind) { |
| + case ConstantConstructorKind.GENERATIVE: |
| + return new GenerativeConstantConstructor( |
| + readType(), |
| + readDefaults(), |
| + readFields(), |
| + readConstructorInvocation()); |
| + case ConstantConstructorKind.REDIRECTING_GENERATIVE: |
| + return new RedirectingGenerativeConstantConstructor( |
| + readDefaults(), |
| + readConstructorInvocation()); |
| + case ConstantConstructorKind.REDIRECTING_FACTORY: |
| + return new RedirectingFactoryConstantConstructor( |
| + readConstructorInvocation()); |
| + } |
| + } |
| +} |