blob: 1fb29de49ae8149dcafd05c27718f8b2db5d582c [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/implementation/elements/elements.dart' as dart2js;
import 'package:compiler/implementation/elements/modelx.dart' as modelx;
import 'package:compiler/implementation/util/util.dart' as util;
import 'package:compiler/implementation/dart_types.dart';
import 'package:analyzer/src/generated/element.dart' as analyzer;
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;
});
}
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) {
return new TopLevelFunctionElementY(converter, input);
}
}
/// Base [dart2js.Element] implementation for converted analyzer elements.
class ElementY extends dart2js.Element {
final ElementConverter converter;
final analyzer.Element element;
@override
String get name => element.name;
ElementY(this.converter, this.element);
@override
dart2js.LibraryElement get implementationLibrary => library;
@override
dart2js.Element get origin => this;
@override
dart2js.Element get patch => null;
@override
dart2js.Element get declaration => this;
@override
dart2js.Element get implementation => this;
@override
bool get isPatch => false;
@override
bool get isPatched => false;
@override
dart2js.LibraryElement get library {
return converter.convertElement(element.library);
}
unsupported(String method) {
throw new UnsupportedError(
"'$method' is unsupported on $this ($runtimeType)");
}
@override
bool get isFinal => unsupported('isFinal');
@override
bool get isStatic => unsupported('isStatic');
@override
bool isForeign(_) => unsupported('isForeign');
@override
bool get impliesType => unsupported('impliesType');
@override
bool get isOperator => unsupported('impliesType');
@override
get position => unsupported('position');
@override
computeType(_) => unsupported('computeType');
@override
get enclosingElement => unsupported('enclosingElement');
@override
accept(_) => unsupported('accept');
@override
void addMetadata(_) => unsupported('addMetadata');
@override
get analyzableElement => unsupported('analyzableElement');
@override
asFunctionElement() => unsupported('asFunctionElement');
@override
buildScope() => unsupported('buildScope');
@override
get compilationUnit => unsupported('compilationUnit');
@override
get contextClass => unsupported('contextClass');
@override
void diagnose(context, listener) => unsupported('diagnose');
@override
get enclosingClass => unsupported('enclosingClass');
@override
get enclosingClassOrCompilationUnit {
return unsupported('enclosingClassOrCompilationUnit');
}
@override
String get fixedBackendName => unsupported('fixedBackendName');
@override
bool get hasFixedBackendName => unsupported('hasFixedBackendName');
@override
bool get isAbstract => unsupported('isAbstract');
@override
bool get isAssignable => unsupported('isAssignable');
@override
bool get isClassMember => unsupported('isClassMember');
@override
bool get isClosure => unsupported('isClosure');
@override
bool get isConst => unsupported('isConst');
@override
bool get isDeclaration => unsupported('isDeclaration');
@override
bool get isDeferredLoaderGetter => unsupported('isDeferredLoaderGetter');
@override
bool get isFactoryConstructor => unsupported('isFactoryConstructor');
@override
bool get isForwardingConstructor => unsupported('isForwardingConstructor');
@override
bool get isImplementation => unsupported('isImplementation');
@override
bool get isInjected => unsupported('isInjected');
@override
bool get isInstanceMember => unsupported('isInstanceMember');
@override
bool get isMixinApplication => unsupported('isMixinApplication');
@override
bool get isNative => unsupported('isNative');
@override
bool get isSynthesized => unsupported('isSynthesized');
@override
bool get isTopLevel => unsupported('isTopLevel');
@override
get kind => unsupported('kind');
@override
get metadata => unsupported('metadata');
@override
get outermostEnclosingMemberOrTopLevel {
return unsupported('outermostEnclosingMemberOrTopLevel');
}
@override
void setFixedBackendName(String name) => unsupported('setFixedBackendName');
@override
void setNative(String name) => unsupported('setNative');
}
class LibraryElementY extends ElementY implements dart2js.LibraryElement {
analyzer.LibraryElement get element => super.element;
@override
dart2js.ElementKind get kind => dart2js.ElementKind.LIBRARY;
// TODO(johnniwinther): Ensure the correct semantics of this.
@override
bool get isInternalLibrary => isPlatformLibrary && element.isPrivate;
// TODO(johnniwinther): Ensure the correct semantics of this.
@override
bool get isPlatformLibrary => element.isInSdk;
@override
bool get isDartCore => element.isDartCore;
LibraryElementY(ElementConverter converter, analyzer.LibraryElement element)
: super(converter, element);
@override
void addCompilationUnit(_) => unsupported('addCompilationUnit');
@override
void addImport(element, import, listener) => unsupported('addImport');
@override
void addMember(element, listener) => unsupported('addMember');
@override
void addTag(tag, listener) => unsupported('addTag');
@override
void addToScope(element, listener) => unsupported('addToScope');
@override
void set canUseNative(bool value) => unsupported('canUseNative');
@override
bool get canUseNative => unsupported('canUseNative');
@override
Uri get canonicalUri => unsupported('canonicalUri');
@override
int compareTo(other) => unsupported('compareTo');
@override
get compilationUnits => unsupported('compilationUnits');
@override
get entryCompilationUnit => unsupported('entryCompilationUnit');
@override
get exports => unsupported('exports');
@override
bool get exportsHandled => unsupported('exportsHandled');
@override
find(String elementName) => unsupported('find');
@override
findExported(String elementName) => unsupported('findExported');
@override
findLocal(String elementName) => unsupported('findLocal');
@override
void forEachExport(_) => unsupported('forEachExport');
@override
void forEachLocalMember(_) => unsupported('forEachLocalMember');
@override
getImportsFor(element) => unsupported('getImportsFor');
@override
getLibraryFromTag(tag) => unsupported('getLibraryFromTag');
@override
String getLibraryName() => unsupported('getLibraryName');
@override
String getLibraryOrScriptName() => unsupported('getLibraryOrScriptName');
@override
getNonPrivateElementsInScope() => unsupported('getNonPrivateElementsInScope');
@override
bool hasLibraryName() => unsupported('hasLibraryName');
@override
bool get hasTreeElements => unsupported('hasTreeElements');
@override
bool get isPackageLibrary => unsupported('isPackageLibrary');
@override
get libraryTag => unsupported('libraryTag');
@override
void set libraryTag(value) => unsupported('libraryTag');
@override
localLookup(elementName) => unsupported('localLookup');
@override
void recordResolvedTag(tag, library) => unsupported('recordResolvedTag');
@override
void setExports(exportedElements) => unsupported('setExports');
@override
get tags => unsupported('tags');
@override
get treeElements => unsupported('treeElements');
}
class TopLevelFunctionElementY extends ElementY
implements dart2js.FunctionElement {
analyzer.FunctionElement get element => super.element;
final dart2js.FunctionSignature functionSignature =
new modelx.FunctionSignatureX(
const util.Link<dart2js.Element>(),
const util.Link<dart2js.Element>(),
0, 0, false, const <dart2js.Element>[],
new FunctionType.synthesized());
// TODO(johnniwinther): Ensure the correct semantics of this.
@override
bool get isFactoryConstructor => false;
@override
bool get isStatic {
// Semantic difference: Analyzer considers top-level and static class
// members to be static, dart2js only considers static class members to be
// static.
return false;
}
// TODO(johnniwinther): Ensure the correct semantics of this.
@override
bool get isAbstract => false;
@override
dart2js.ElementKind get kind => dart2js.ElementKind.FUNCTION;
@override
bool get isClassMember => false;
@override
bool get isInstanceMember => false;
@override
bool get isTopLevel => true;
TopLevelFunctionElementY(ElementConverter converter,
analyzer.FunctionElement element)
: super(converter, element);
@override
get abstractField => unsupported('abstractField');
@override
computeSignature(_) => unsupported('computeSignature');
@override
bool get hasNode => unsupported('hasNode');
@override
bool get hasResolvedAst => unsupported('hasResolvedAst');
@override
bool get hasTreeElements => unsupported('hasTreeElements');
@override
get memberContext => unsupported('memberContext');
@override
get node => unsupported('node');
@override
get resolvedAst => unsupported('resolvedAst');
@override
get treeElements => unsupported('treeElements');
@override
FunctionType get type => functionSignature.type;
}