blob: 96f659e1bf862c50c60a380f8588d7d3b8b7a3db [file] [log] [blame]
// 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.types;
import '../dart_types.dart';
import '../elements/elements.dart';
import 'keys.dart';
import 'serialization.dart';
/// Visitor that serializes a [DartType] by encoding it into an [ObjectEncoder].
///
/// This class is called from the [Serializer] when a [DartType] needs
/// serialization. The [ObjectEncoder] ensures that any [Element], and other
/// [DartType] that the serialized [DartType] depends upon are also serialized.
class TypeSerializer extends DartTypeVisitor<dynamic, ObjectEncoder> {
const TypeSerializer();
void visitType(DartType type, ObjectEncoder encoder) {
throw new UnsupportedError('Unsupported type: $type');
}
void visitVoidType(VoidType type, ObjectEncoder encoder) {}
void visitTypeVariableType(TypeVariableType type, ObjectEncoder encoder) {
encoder.setElement(Key.ELEMENT, type.element);
encoder.setBool(
Key.IS_METHOD_TYPE_VARIABLE_TYPE, type is MethodTypeVariableType);
}
void visitFunctionType(FunctionType type, ObjectEncoder encoder) {
// TODO(johnniwinther): Support encoding of `type.element`.
encoder.setType(Key.RETURN_TYPE, type.returnType);
encoder.setTypes(Key.PARAMETER_TYPES, type.parameterTypes);
encoder.setTypes(Key.OPTIONAL_PARAMETER_TYPES, type.optionalParameterTypes);
encoder.setStrings(Key.NAMED_PARAMETERS, type.namedParameters);
encoder.setTypes(Key.NAMED_PARAMETER_TYPES, type.namedParameterTypes);
}
void visitMalformedType(MalformedType type, ObjectEncoder encoder) {
encoder.setElement(Key.ELEMENT, type.element);
}
void visitInterfaceType(InterfaceType type, ObjectEncoder encoder) {
encoder.setElement(Key.ELEMENT, type.element);
encoder.setTypes(Key.TYPE_ARGUMENTS, type.typeArguments);
}
void visitTypedefType(TypedefType type, ObjectEncoder encoder) {
encoder.setElement(Key.ELEMENT, type.element);
encoder.setTypes(Key.TYPE_ARGUMENTS, type.typeArguments);
}
void visitDynamicType(DynamicType type, ObjectEncoder encoder) {}
}
/// Utility class for deserializing [DartType]s.
///
/// This is used by the [Deserializer].
class TypeDeserializer {
/// Deserializes a [DartType] from an [ObjectDecoder].
///
/// The class is called from the [Deserializer] when a [DartType] needs
/// deserialization. The [ObjectDecoder] ensures that any [Element], other
/// [DartType] that the deserialized [DartType] depends upon are available.
static DartType deserialize(ObjectDecoder decoder) {
TypeKind typeKind = decoder.getEnum(Key.KIND, TypeKind.values);
switch (typeKind) {
case TypeKind.INTERFACE:
return new InterfaceType(decoder.getElement(Key.ELEMENT),
decoder.getTypes(Key.TYPE_ARGUMENTS, isOptional: true));
case TypeKind.FUNCTION:
// TODO(johnniwinther): Support decoding of `type.element`.
return new FunctionType.synthesized(
decoder.getType(Key.RETURN_TYPE),
decoder.getTypes(Key.PARAMETER_TYPES, isOptional: true),
decoder.getTypes(Key.OPTIONAL_PARAMETER_TYPES, isOptional: true),
decoder.getStrings(Key.NAMED_PARAMETERS, isOptional: true),
decoder.getTypes(Key.NAMED_PARAMETER_TYPES, isOptional: true));
case TypeKind.TYPE_VARIABLE:
TypeVariableElement element = decoder.getElement(Key.ELEMENT);
if (decoder.getBool(Key.IS_METHOD_TYPE_VARIABLE_TYPE)) {
return new MethodTypeVariableType(element);
}
return new TypeVariableType(element);
case TypeKind.TYPEDEF:
return new TypedefType(decoder.getElement(Key.ELEMENT),
decoder.getTypes(Key.TYPE_ARGUMENTS, isOptional: true));
case TypeKind.STATEMENT:
throw new UnsupportedError("Unexpected type kind '${typeKind}.");
case TypeKind.MALFORMED_TYPE:
// TODO(johnniwinther): Do we need the 'userProvidedBadType' or maybe
// just a toString of it?
return new MalformedType(decoder.getElement(Key.ELEMENT), null);
case TypeKind.DYNAMIC:
return const DynamicType();
case TypeKind.VOID:
return const VoidType();
}
}
}