blob: c5f68c848f3fdf76fde99bba3fb3c6e9929190fc [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 '../elements/resolution_types.dart';
import '../elements/elements.dart';
import 'keys.dart';
import 'serialization.dart';
/// Visitor that serializes a [ResolutionDartType] by encoding it into an
/// [ObjectEncoder].
///
/// This class is called from the [Serializer] when a [ResolutionDartType] needs
/// serialization. The [ObjectEncoder] ensures that any [Element], and other
/// [ResolutionDartType] that the serialized [ResolutionDartType] depends upon
/// are also serialized.
class TypeSerializer extends DartTypeVisitor<dynamic, ObjectEncoder> {
const TypeSerializer();
void visitType(ResolutionDartType type, ObjectEncoder encoder) {
throw new UnsupportedError('Unsupported type: $type');
}
void visitVoidType(ResolutionVoidType type, ObjectEncoder encoder) {}
void visitTypeVariableType(
ResolutionTypeVariableType type, ObjectEncoder encoder) {
encoder.setElement(Key.ELEMENT, type.element);
encoder.setBool(
Key.IS_METHOD_TYPE_VARIABLE_TYPE, type is MethodTypeVariableType);
}
void visitFunctionType(ResolutionFunctionType 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(ResolutionInterfaceType type, ObjectEncoder encoder) {
encoder.setElement(Key.ELEMENT, type.element);
encoder.setTypes(Key.TYPE_ARGUMENTS, type.typeArguments);
}
void visitTypedefType(ResolutionTypedefType type, ObjectEncoder encoder) {
encoder.setElement(Key.ELEMENT, type.element);
encoder.setTypes(Key.TYPE_ARGUMENTS, type.typeArguments);
}
void visitDynamicType(ResolutionDynamicType type, ObjectEncoder encoder) {}
}
/// Utility class for deserializing [ResolutionDartType]s.
///
/// This is used by the [Deserializer].
class TypeDeserializer {
/// Deserializes a [ResolutionDartType] from an [ObjectDecoder].
///
/// The class is called from the [Deserializer] when a [ResolutionDartType]
/// needs deserialization. The [ObjectDecoder] ensures that any [Element],
/// other [ResolutionDartType] that the deserialized [ResolutionDartType]
/// depends upon are available.
static ResolutionDartType deserialize(ObjectDecoder decoder) {
ResolutionTypeKind typeKind =
decoder.getEnum(Key.KIND, ResolutionTypeKind.values);
switch (typeKind) {
case ResolutionTypeKind.INTERFACE:
return new ResolutionInterfaceType(decoder.getElement(Key.ELEMENT),
decoder.getTypes(Key.TYPE_ARGUMENTS, isOptional: true));
case ResolutionTypeKind.FUNCTION:
// TODO(johnniwinther): Support decoding of `type.element`.
return new ResolutionFunctionType.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 ResolutionTypeKind.TYPE_VARIABLE:
TypeVariableElement element = decoder.getElement(Key.ELEMENT);
if (decoder.getBool(Key.IS_METHOD_TYPE_VARIABLE_TYPE)) {
return new MethodTypeVariableType(element);
}
return new ResolutionTypeVariableType(element);
case ResolutionTypeKind.TYPEDEF:
return new ResolutionTypedefType(decoder.getElement(Key.ELEMENT),
decoder.getTypes(Key.TYPE_ARGUMENTS, isOptional: true));
case ResolutionTypeKind.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 ResolutionTypeKind.DYNAMIC:
return const ResolutionDynamicType();
case ResolutionTypeKind.VOID:
return const ResolutionVoidType();
}
}
}