blob: 666124e52f5a4cc9f06b1e9676b779e78d041fc2 [file] [log] [blame]
// Copyright (c) 2014, 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.
/// Convertion of elements between the analyzer element model and the dart2js
/// element model.
library analyzer2dart.element_converter;
import 'package:compiler/src/elements/elements.dart' as dart2js;
import 'package:compiler/src/util/util.dart' as util;
import 'package:compiler/src/dart_types.dart' as dart2js;
import 'package:analyzer/src/generated/element.dart' as analyzer;
import 'package:analyzer/src/generated/utilities_dart.dart';
part 'modely.dart';
class ElementConverter {
/// Map from analyzer elements to their equivalent dart2js elements.
Map<analyzer.Element, dart2js.Element> conversionMap =
<analyzer.Element, dart2js.Element>{};
/// Map from dart2js elements to their equivalent analyzer elements.
Map<dart2js.Element, analyzer.Element> inversionMap =
<dart2js.Element, analyzer.Element>{};
ElementConverterVisitor visitor;
ElementConverter() {
visitor = new ElementConverterVisitor(this);
}
dart2js.Element convertElement(analyzer.Element input) {
return conversionMap.putIfAbsent(input, () {
dart2js.Element output = convertElementInternal(input);
inversionMap[output] = input;
return output;
});
}
dart2js.FunctionType convertFunctionType(analyzer.FunctionType input) {
dart2js.DartType returnType = convertType(input.returnType);
List<dart2js.DartType> requiredParameterTypes =
input.normalParameterTypes.map(convertType).toList();
List<dart2js.DartType> positionalParameterTypes =
input.optionalParameterTypes.map(convertType).toList();
List<String> namedParameters =
input.namedParameterTypes.keys.toList()..sort();
List<dart2js.DartType> namedParameterTypes =
namedParameters.map((String name) {
return convertType(input.namedParameterTypes[name]);
}).toList();
return new dart2js.FunctionType.synthesized(
returnType,
requiredParameterTypes,
positionalParameterTypes,
namedParameters,
namedParameterTypes);
}
dart2js.DartType convertType(analyzer.DartType input) {
if (input.isVoid) {
return const dart2js.VoidType();
} else if (input.isDynamic) {
return const dart2js.DynamicType();
} else if (input is analyzer.TypeParameterType) {
return new dart2js.TypeVariableType(convertElement(input.element));
} else if (input is analyzer.InterfaceType) {
List<dart2js.DartType> typeArguments =
input.typeArguments.map(convertType).toList();
return new dart2js.InterfaceType(
convertElement(input.element), typeArguments);
} else if (input is analyzer.FunctionType) {
if (input.element is analyzer.FunctionTypeAliasElement) {
List<dart2js.DartType> typeArguments =
input.typeArguments.map(convertType).toList();
return new dart2js.ResolvedTypedefType(
convertElement(input.element),
typeArguments,
convertFunctionType(input));
} else {
assert(input.typeArguments.isEmpty);
return convertFunctionType(input);
}
}
throw new UnsupportedError(
"Conversion of $input (${input.runtimeType}) is not supported.");
}
analyzer.Element invertElement(dart2js.Element input) {
return inversionMap[input];
}
dart2js.Element convertElementInternal(analyzer.Element input) {
dart2js.Element output = input.accept(visitor);
if (output != null) return output;
throw new UnsupportedError(
"Conversion of $input (${input.runtimeType}) is not supported.");
}
}
/// Visitor that converts analyzer elements to dart2js elements.
class ElementConverterVisitor
extends analyzer.SimpleElementVisitor<dart2js.Element> {
final ElementConverter converter;
ElementConverterVisitor(this.converter);
@override
dart2js.LibraryElement visitLibraryElement(analyzer.LibraryElement input) {
return new LibraryElementY(converter, input);
}
@override
dart2js.FunctionElement visitFunctionElement(analyzer.FunctionElement input) {
if (input.isStatic) {
return new TopLevelFunctionElementY(converter, input);
} else {
return new LocalFunctionElementY(converter, input);
}
}
@override
dart2js.ParameterElement visitParameterElement(
analyzer.ParameterElement input) {
return new ParameterElementY(converter, input);
}
@override
dart2js.ClassElement visitClassElement(analyzer.ClassElement input) {
return new ClassElementY(converter, input);
}
@override
dart2js.TypedefElement visitFunctionTypeAliasElement(
analyzer.FunctionTypeAliasElement input) {
return new TypedefElementY(converter, input);
}
@override
dart2js.FieldElement visitTopLevelVariableElement(
analyzer.TopLevelVariableElement input) {
return new TopLevelVariableElementY(converter, input);
}
@override
dart2js.Element visitPropertyAccessorElement(
analyzer.PropertyAccessorElement input) {
if (input.isSynthetic) {
return input.variable.accept(this);
}
return null;
}
@override
dart2js.Element visitLocalVariableElement(
analyzer.LocalVariableElement input) {
return new LocalVariableElementY(converter, input);
}
@override
dart2js.ConstructorElement visitConstructorElement(
analyzer.ConstructorElement input) {
return new ConstructorElementY(converter, input);
}
@override
dart2js.MethodElement visitMethodElement(analyzer.MethodElement input) {
return new InstanceMethodElementY(converter, input);
}
}