blob: c31ee4af34453b02aca007908edcfc8a73862ca8 [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.
/// Implementation of the element model used for deserialiation.
///
/// These classes are created by [ElementDeserializer] triggered by the
/// [Deserializer].
library dart2js.serialization.modelz;
import '../common.dart';
import '../common/resolution.dart' show
Resolution;
import '../compiler.dart'
show Compiler;
import '../constants/constructors.dart';
import '../constants/expressions.dart';
import '../core_types.dart';
import '../dart_types.dart';
import '../elements/elements.dart';
import '../elements/modelx.dart' show
FunctionSignatureX;
import '../elements/common.dart';
import '../elements/visitor.dart';
import '../io/source_file.dart';
import '../ordered_typeset.dart';
import '../resolution/class_members.dart' as class_members;
import '../resolution/tree_elements.dart' show
TreeElements;
import '../resolution/scope.dart' show
Scope;
import '../script.dart';
import '../serialization/constant_serialization.dart';
import '../tokens/token.dart' show
Token;
import '../tree/tree.dart';
import '../util/util.dart' show
Link,
LinkBuilder;
import 'keys.dart';
import 'serialization.dart';
/// Compute a [Link] from an [Iterable].
Link toLink(Iterable iterable) {
LinkBuilder builder = new LinkBuilder();
for (var element in iterable) {
builder.addLast(element);
}
return builder.toLink();
}
abstract class ElementZ extends Element with ElementCommon {
String toString() {
if (enclosingElement == null || isTopLevel) return 'Z$kind($name)';
return 'Z$kind(${enclosingElement.name}#$name)';
}
_unsupported(text) => throw new UnsupportedError('${this}.$text');
@override
AnalyzableElement get analyzableElement {
Element element = this;
if (element is AnalyzableElement) {
return element;
} else if (enclosingElement != null) {
return enclosingElement.analyzableElement;
}
return null;
}
@override
FunctionElement asFunctionElement() => null;
@override
Scope buildScope() => _unsupported('analyzableElement');
@override
CompilationUnitElement get compilationUnit {
return _unsupported('compilationUnit');
}
@override
ClassElement get contextClass => _unsupported('contextClass');
@override
ClassElement get enclosingClass => null;
@override
Element get enclosingClassOrCompilationUnit {
return _unsupported('enclosingClassOrCompilationUnit');
}
@override
String get fixedBackendName => _unsupported('fixedBackendName');
@override
bool get hasFixedBackendName => _unsupported('hasFixedBackendName');
@override
LibraryElement get implementationLibrary => library;
@override
bool get isAbstract => false;
@override
bool get isAssignable => _unsupported('isAssignable');
@override
bool get isClassMember => false;
@override
bool get isClosure => _unsupported('isClosure');
@override
bool get isConst => _unsupported('isConst');
@override
bool get isDeferredLoaderGetter => false;
@override
bool get isFinal => _unsupported('isFinal');
@override
bool get isInstanceMember => false;
@override
bool get isLocal => false;
@override
bool get isMixinApplication => false;
@override
bool get isNative => false;
@override
bool get isJsInterop => false;
@override
String get jsInteropName => null;
@override
bool get isOperator => false;
@override
bool get isStatic => false;
// TODO(johnniwinther): Find a more precise semantics for this.
@override
bool get isSynthesized => true;
@override
bool get isTopLevel => false;
// TODO(johnniwinther): Support metadata.
@override
Iterable<MetadataAnnotation> get metadata => const <MetadataAnnotation>[];
@override
Element get outermostEnclosingMemberOrTopLevel {
return _unsupported('outermostEnclosingMemberOrTopLevel');
}
@override
Token get position => _unsupported('position');
}
abstract class DeserializedElementZ extends ElementZ {
ObjectDecoder _decoder;
DeserializedElementZ(this._decoder);
@override
String get name => _decoder.getString(Key.NAME);
@override
SourceSpan get sourcePosition {
// TODO(johnniwinther): Should this be cached?
int offset = _decoder.getInt(Key.OFFSET, isOptional: true);
if (offset == null) return null;
Uri uri = _decoder.getUri(Key.URI, isOptional: true);
if (uri == null) {
uri = compilationUnit.script.readableUri;
}
int length = _decoder.getInt(Key.LENGTH, isOptional: true);
if (length == null) {
length = name.length;
}
return new SourceSpan(uri, offset, offset + length);
}
}
/// Deserializer for a collection of member elements serialized as a map from
/// names to element declarations.
///
/// The serialized data contains the declared getters and setters but lookup
/// into the map returns an [AbstractFieldElement] for pairs of corresponding
/// getters and setters.
///
/// The underlying map encoding allows for lazy computation of the members upon
/// query.
class MappedContainer {
Map<String, Element> _lookupCache = {};
Element lookup(String name, MapDecoder members) {
if (_lookupCache.containsKey(name)) {
Element element = _lookupCache[name];
if (element != null) {
return element;
}
}
if (members == null) {
return null;
}
bool hasId = members.containsKey(name);
String setterName = '$name,=';
bool hasSetterId = members.containsKey(setterName);
Element element;
Element setterElement;
if (!hasId && !hasSetterId) {
_lookupCache[name] = null;
return null;
}
bool isAccessor = false;
if (hasId) {
element = members.getElement(name);
isAccessor = element.isGetter;
}
if (hasSetterId) {
setterElement = members.getElement(setterName);
isAccessor = true;
}
if (isAccessor) {
element = new AbstractFieldElementZ(name, element, setterElement);
}
_lookupCache[name] = element;
return element;
}
}
/// Deserializer for a collection of member elements serialized as a list of
/// element declarations.
///
/// The serialized data contains the declared getters and setters but lookup
/// into the map returns an [AbstractFieldElement] for pairs of corresponding
/// getters and setters.
///
/// The underlying list encoding requires the complete lookup map to be computed
/// before query.
class ListedContainer {
final Map<String, Element> _lookupMap = <String, Element>{};
ListedContainer(List<Element> elements) {
Set<String> accessorNames = new Set<String>();
Map<String, Element> getters = <String, Element>{};
Map<String, Element> setters = <String, Element>{};
for (Element element in elements) {
String name = element.name;
if (element.isGetter) {
accessorNames.add(name);
getters[name] = element;
// Inserting [element] here to ensure insert order of [name].
_lookupMap[name] = element;
} else if (element.isSetter) {
accessorNames.add(name);
setters[name] = element;
// Inserting [element] here to ensure insert order of [name].
_lookupMap[name] = element;
} else {
_lookupMap[name] = element;
}
}
for (String name in accessorNames) {
_lookupMap[name] =
new AbstractFieldElementZ(name, getters[name], setters[name]);
}
}
Element lookup(String name) => _lookupMap[name];
void forEach(f(Element element)) => _lookupMap.values.forEach(f);
Iterable<Element> get values => _lookupMap.values;
}
abstract class AnalyzableElementMixin implements AnalyzableElement, ElementZ {
@override
bool get hasTreeElements => _unsupported('hasTreeElements');
@override
TreeElements get treeElements => _unsupported('treeElements');
}
abstract class AstElementMixin implements AstElement, ElementZ {
@override
bool get hasNode => _unsupported('hasNode');
@override
bool get hasResolvedAst => _unsupported('hasResolvedAst');
@override
get node => _unsupported('node');
@override
ResolvedAst get resolvedAst => _unsupported('resolvedAst');
}
abstract class ContainerMixin
implements DeserializedElementZ, ScopeContainerElement {
MappedContainer _membersMap = new MappedContainer();
@override
Element localLookup(String name) {
return _membersMap.lookup(
name, _decoder.getMap(Key.MEMBERS, isOptional: true));
}
@override
void forEachLocalMember(f(Element element)) {
MapDecoder members =
_decoder.getMap(Key.MEMBERS, isOptional: true);
if (members == null) return;
members.forEachKey((String key) {
Element member = members.getElement(key);
if (member != null) {
f(member);
}
});
}
}
class AbstractFieldElementZ extends ElementZ implements AbstractFieldElement {
final String name;
final FunctionElement getter;
final FunctionElement setter;
AbstractFieldElementZ(this.name, this.getter, this.setter);
@override
ElementKind get kind => ElementKind.ABSTRACT_FIELD;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitAbstractFieldElement(this, arg);
}
@override
LibraryElement get library {
return getter != null ? getter.library : setter.library;
}
@override
Element get enclosingElement {
return getter != null ? getter.enclosingElement : setter.enclosingElement;
}
@override
SourceSpan get sourcePosition {
return getter != null ? getter.sourcePosition : setter.sourcePosition;
}
}
class LibraryElementZ extends DeserializedElementZ
with AnalyzableElementMixin,
ContainerMixin,
LibraryElementCommon
implements LibraryElement {
Uri _canonicalUri;
CompilationUnitElement _entryCompilationUnit;
Link<CompilationUnitElement> _compilationUnits;
List<ImportElement> _imports;
List<ExportElement> _exports;
ListedContainer _exportsMap;
ListedContainer _importsMap;
Map<LibraryTag, LibraryElement> _libraryDependencies;
LibraryElementZ(ObjectDecoder decoder)
: super(decoder);
@override
ElementKind get kind => ElementKind.LIBRARY;
@override
Element get enclosingElement => null;
@override
String get name => entryCompilationUnit.name;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitLibraryElement(this, arg);
}
@override
LibraryElement get library => this;
@override
Uri get canonicalUri {
if (_canonicalUri == null) {
_canonicalUri = _decoder.getUri(Key.CANONICAL_URI);
}
return _canonicalUri;
}
@override
CompilationUnitElement get entryCompilationUnit {
if (_entryCompilationUnit == null) {
_entryCompilationUnit = _decoder.getElement(Key.COMPILATION_UNIT);
}
return _entryCompilationUnit;
}
@override
Link<CompilationUnitElement> get compilationUnits {
if (_compilationUnits == null) {
_compilationUnits =
toLink(_decoder.getElements(Key.COMPILATION_UNITS));
}
return _compilationUnits;
}
@override
bool get hasLibraryName {
return libraryName != '';
}
@override
String get libraryName {
return _decoder.getString(Key.LIBRARY_NAME);
}
@override
bool get exportsHandled => true;
void _ensureExports() {
if (_exportsMap == null) {
_exportsMap = new ListedContainer(_decoder.getElements(Key.EXPORT_SCOPE));
}
}
@override
void forEachExport(f(Element element)) {
_ensureExports();
_exportsMap.forEach(f);
}
@override
Element find(String elementName) {
Element element = localLookup(elementName);
if (element == null) {
_ensureImports();
element = _importsMap.lookup(elementName);
}
return element;
}
@override
Element findLocal(String elementName) {
return localLookup(elementName);
}
@override
bool get canUseNative => false;
@override
Element findExported(String elementName) => _unsupported('findExported');
void _ensureImports() {
if (_importsMap == null) {
_importsMap = new ListedContainer(_decoder.getElements(Key.IMPORT_SCOPE));
}
}
@override
void forEachImport(f(Element element)) {
_ensureImports();
_importsMap.forEach(f);
}
@override
Iterable<ImportElement> getImportsFor(Element element) {
return _unsupported('getImportsFor');
}
String toString() {
return 'Zlibrary(${canonicalUri})';
}
@override
Iterable<ExportElement> get exports {
if (_exports == null) {
_exports = _decoder.getElements(Key.EXPORTS, isOptional: true);
}
return _exports;
}
@override
Iterable<ImportElement> get imports {
if (_imports == null) {
_imports = _decoder.getElements(Key.IMPORTS, isOptional: true);
}
return _imports;
}
}
class ScriptZ implements Script {
final Uri resourceUri;
ScriptZ(this.resourceUri);
@override
Script copyWithFile(SourceFile file) {
throw new UnsupportedError('ScriptZ.copyWithFile');
}
@override
SourceFile get file => throw new UnsupportedError('ScriptZ.file');
@override
bool get isSynthesized => throw new UnsupportedError('ScriptZ.isSynthesized');
@override
String get name => resourceUri.toString();
// TODO(johnniwinther): Support the distinction between [readableUri] and
// [resourceUri]; needed for platform libraries.
@override
Uri get readableUri => resourceUri;
@override
String get text => throw new UnsupportedError('ScriptZ.text');
}
class CompilationUnitElementZ extends DeserializedElementZ
with LibraryMemberMixin,
CompilationUnitElementCommon
implements CompilationUnitElement {
List<Element> _members;
Script _script;
CompilationUnitElementZ(ObjectDecoder decoder)
: super(decoder);
@override
ElementKind get kind => ElementKind.COMPILATION_UNIT;
@override
CompilationUnitElement get compilationUnit => this;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitCompilationUnitElement(this, arg);
}
@override
void forEachLocalMember(f(Element element)) {
if (_members == null) {
_members =
_decoder.getElements(Key.ELEMENTS, isOptional: true);
}
_members.forEach(f);
}
@override
Script get script {
if (_script == null) {
Uri resolvedUri = _decoder.getUri(Key.URI);
_script = new ScriptZ(resolvedUri);
}
return _script;
}
@override
String get name => script.name;
}
abstract class LibraryMemberMixin implements DeserializedElementZ {
LibraryElement _library;
CompilationUnitElement _compilationUnit;
@override
LibraryElement get library {
if (_library == null) {
_library = _decoder.getElement(Key.LIBRARY);
}
return _library;
}
@override
CompilationUnitElement get compilationUnit {
if (_compilationUnit == null) {
_compilationUnit = _decoder.getElement(Key.COMPILATION_UNIT);
}
return _compilationUnit;
}
@override
Element get enclosingElement => compilationUnit;
@override
ClassElement get enclosingClass => null;
@override
bool get isTopLevel => true;
@override
bool get isStatic => false;
}
abstract class ClassMemberMixin implements DeserializedElementZ {
ClassElement _class;
@override
Element get enclosingElement => enclosingClass;
@override
ClassElement get enclosingClass {
if (_class == null) {
_class = _decoder.getElement(Key.CLASS);
}
return _class;
}
@override
bool get isClassMember => true;
@override
LibraryElement get library => enclosingClass.library;
@override
CompilationUnitElement get compilationUnit => enclosingClass.compilationUnit;
}
abstract class InstanceMemberMixin implements DeserializedElementZ {
@override
bool get isTopLevel => false;
@override
bool get isStatic => false;
@override
bool get isInstanceMember => true;
}
abstract class StaticMemberMixin implements DeserializedElementZ {
@override
bool get isTopLevel => false;
@override
bool get isStatic => true;
}
abstract class TypedElementMixin
implements DeserializedElementZ, TypedElement {
DartType _type;
@override
DartType get type {
if (_type == null) {
_type = _decoder.getType(Key.TYPE);
}
return _type;
}
@override
DartType computeType(Resolution resolution) => type;
}
abstract class ParametersMixin
implements DeserializedElementZ, FunctionTypedElement {
FunctionSignature _functionSignature;
List<ParameterElement> _parameters;
bool get hasFunctionSignature => true;
@override
FunctionSignature get functionSignature {
if (_functionSignature == null) {
List<Element> requiredParameters = [];
List<Element> optionalParameters = [];
List orderedOptionalParameters = [];
int requiredParameterCount = 0;
int optionalParameterCount = 0;
bool optionalParametersAreNamed = false;
List<DartType> parameterTypes = <DartType>[];
List<DartType> optionalParameterTypes = <DartType>[];
List<String> namedParameters = <String>[];
List<DartType> namedParameterTypes = <DartType>[];
for (ParameterElement parameter in parameters) {
if (parameter.isOptional) {
optionalParameterCount++;
requiredParameters.add(parameter);
orderedOptionalParameters.add(parameter);
if (parameter.isNamed) {
optionalParametersAreNamed = true;
namedParameters.add(parameter.name);
namedParameterTypes.add(parameter.type);
} else {
optionalParameterTypes.add(parameter.type);
}
} else {
requiredParameterCount++;
optionalParameters.add(parameter);
parameterTypes.add(parameter.type);
}
}
if (optionalParametersAreNamed) {
orderedOptionalParameters.sort((Element a, Element b) {
return a.name.compareTo(b.name);
});
}
FunctionType type = new FunctionType(
this,
_decoder.getType(Key.RETURN_TYPE),
parameterTypes,
optionalParameterTypes,
namedParameters,
namedParameterTypes);
_functionSignature = new FunctionSignatureX(
requiredParameters: requiredParameters,
requiredParameterCount: requiredParameterCount,
optionalParameters: optionalParameters,
optionalParameterCount: optionalParameterCount,
optionalParametersAreNamed: optionalParametersAreNamed,
orderedOptionalParameters: orderedOptionalParameters,
type: type);
}
return _functionSignature;
}
List<ParameterElement> get parameters {
if (_parameters == null) {
_parameters = _decoder.getElements(Key.PARAMETERS, isOptional: true);
}
return _parameters;
}
}
abstract class FunctionTypedElementMixin
implements FunctionElement, DeserializedElementZ {
@override
AsyncMarker get asyncMarker => _unsupported('');
@override
bool get isExternal => _unsupported('');
@override
FunctionElement asFunctionElement() => this;
}
class ClassElementZ extends DeserializedElementZ
with AnalyzableElementMixin,
AstElementMixin,
ClassElementCommon,
class_members.ClassMemberMixin,
ContainerMixin,
LibraryMemberMixin,
TypeDeclarationMixin<InterfaceType>
implements ClassElement {
bool _isObject;
DartType _supertype;
OrderedTypeSet _allSupertypesAndSelf;
Link<DartType> _interfaces;
ClassElementZ(ObjectDecoder decoder)
: super(decoder);
InterfaceType _createType(List<DartType> typeArguments) {
return new InterfaceType(this, typeArguments);
}
@override
ElementKind get kind => ElementKind.CLASS;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitClassElement(this, arg);
}
@override
DartType get supertype {
if (_isObject == null) {
_supertype = _decoder.getType(Key.SUPERTYPE, isOptional: true);
_isObject = _supertype == null;
}
return _supertype;
}
@override
bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
@override
bool get isObject {
return supertype == null;
}
@override
void addBackendMember(Element element) => _unsupported('addBackendMember');
@override
OrderedTypeSet get allSupertypesAndSelf {
if (_allSupertypesAndSelf == null) {
ObjectDecoder supertypesDeserializer =
_decoder.getObject(Key.SUPERTYPES);
List<int> offsets = supertypesDeserializer.getInts(Key.OFFSETS);
List<Link<DartType>> levels = new List<Link<DartType>>(offsets.length);
LinkBuilder<DartType> typesBuilder = new LinkBuilder<DartType>();
int offset = 0;
int depth = offsets.length - 1;
for (DartType type in supertypesDeserializer.getTypes(Key.TYPES)) {
Link<DartType> link = typesBuilder.addLast(type);
if (offsets[depth] == offset) {
levels[depth] = link;
depth--;
}
offset++;
}
LinkBuilder<DartType> supertypesBuilder = new LinkBuilder<DartType>();
for (DartType supertype in
supertypesDeserializer.getTypes(Key.SUPERTYPES, isOptional: true)) {
supertypesBuilder.addLast(supertype);
}
Link<DartType> types = typesBuilder.toLink();
Link<DartType> supertypes = supertypesBuilder.toLink();
_allSupertypesAndSelf = new OrderedTypeSet.internal(
levels, types, supertypes);
}
return _allSupertypesAndSelf;
}
@override
void forEachBackendMember(void f(Element member)) {
_unsupported('forEachBackendMember');
}
@override
bool get hasBackendMembers => _unsupported('hasBackendMembers');
@override
bool get hasConstructor => _unsupported('hasConstructor');
@override
bool hasFieldShadowedBy(Element fieldMember) => _unsupported('');
@override
bool get hasIncompleteHierarchy => _unsupported('hasIncompleteHierarchy');
@override
bool get hasLocalScopeMembers => _unsupported('hasLocalScopeMembers');
@override
bool implementsFunction(CoreClasses coreClasses) {
return _unsupported('implementsFunction');
}
@override
Link<DartType> get interfaces {
if (_interfaces == null) {
_interfaces = toLink(
_decoder.getTypes(Key.INTERFACES, isOptional: true));
}
return _interfaces;
}
@override
bool get isEnumClass => false;
@override
bool get isProxy => _unsupported('isProxy');
@override
bool get isUnnamedMixinApplication {
return _unsupported('isUnnamedMixinApplication');
}
@override
Element lookupBackendMember(String memberName) {
return _unsupported('lookupBackendMember');
}
@override
ConstructorElement lookupDefaultConstructor() {
ConstructorElement constructor = lookupConstructor("");
if (constructor != null && constructor.parameters.isEmpty) {
return constructor;
}
return null;
}
@override
String get nativeTagInfo => _unsupported('nativeTagInfo');
@override
void reverseBackendMembers() => _unsupported('reverseBackendMembers');
@override
ClassElement get superclass => supertype != null ? supertype.element : null;
@override
void ensureResolved(Resolution resolution) {
resolution.registerClass(this);
}
}
abstract class ConstructorElementZ extends DeserializedElementZ
with AnalyzableElementMixin,
AstElementMixin,
ClassMemberMixin,
FunctionTypedElementMixin,
ParametersMixin,
TypedElementMixin,
MemberElementMixin
implements ConstructorElement {
ConstantConstructor _constantConstructor;
ConstructorElementZ(ObjectDecoder decoder)
: super(decoder);
accept(ElementVisitor visitor, arg) {
return visitor.visitConstructorElement(this, arg);
}
@override
bool get isConst => _decoder.getBool(Key.IS_CONST);
@override
bool get isExternal => _decoder.getBool(Key.IS_EXTERNAL);
bool get isFromEnvironmentConstructor {
return name == 'fromEnvironment' &&
library.isDartCore &&
(enclosingClass.name == 'bool' ||
enclosingClass.name == 'int' ||
enclosingClass.name == 'String');
}
ConstantConstructor get constantConstructor {
if (isConst && _constantConstructor == null) {
ObjectDecoder data =
_decoder.getObject(Key.CONSTRUCTOR, isOptional: true);
if (data == null) {
assert(isFromEnvironmentConstructor || isExternal);
return null;
}
_constantConstructor = ConstantConstructorDeserializer.deserialize(data);
}
return _constantConstructor;
}
@override
AsyncMarker get asyncMarker => _unsupported('asyncMarker');
@override
InterfaceType computeEffectiveTargetType(InterfaceType newType) {
return _unsupported('computeEffectiveTargetType');
}
@override
ConstructorElement get definingConstructor {
return _unsupported('definingConstructor');
}
@override
ConstructorElement get effectiveTarget {
return _unsupported('effectiveTarget');
}
@override
ConstructorElement get immediateRedirectionTarget {
return _unsupported('immediateRedirectionTarget');
}
@override
bool get isRedirectingFactory => _unsupported('isRedirectingFactory');
@override
bool get isRedirectingGenerative => _unsupported('isRedirectingGenerative');
@override
bool get isCyclicRedirection => _unsupported('isCyclicRedirection');
@override
PrefixElement get redirectionDeferredPrefix {
return _unsupported('redirectionDeferredPrefix');
}
}
class GenerativeConstructorElementZ extends ConstructorElementZ {
GenerativeConstructorElementZ(ObjectDecoder decoder)
: super(decoder);
@override
ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
}
class FactoryConstructorElementZ extends ConstructorElementZ {
FactoryConstructorElementZ(ObjectDecoder decoder)
: super(decoder);
@override
ElementKind get kind => ElementKind.FACTORY_CONSTRUCTOR;
}
abstract class MemberElementMixin
implements DeserializedElementZ, MemberElement {
@override
MemberElement get memberContext => this;
@override
Name get memberName => new Name(name, library);
@override
List<FunctionElement> get nestedClosures => const <FunctionElement>[];
}
abstract class FieldElementZ extends DeserializedElementZ
with AnalyzableElementMixin,
AstElementMixin,
TypedElementMixin,
MemberElementMixin
implements FieldElement {
ConstantExpression _constant;
FieldElementZ(ObjectDecoder decoder)
: super(decoder);
@override
ElementKind get kind => ElementKind.FIELD;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitFieldElement(this, arg);
}
@override
bool get isFinal => _decoder.getBool(Key.IS_FINAL);
@override
bool get isConst => _decoder.getBool(Key.IS_CONST);
@override
ConstantExpression get constant {
if (isConst && _constant == null) {
_constant = _decoder.getConstant(Key.CONSTANT);
}
return _constant;
}
@override
Expression get initializer => _unsupported('initializer');
}
class TopLevelFieldElementZ extends FieldElementZ with LibraryMemberMixin {
TopLevelFieldElementZ(ObjectDecoder decoder)
: super(decoder);
}
class StaticFieldElementZ extends FieldElementZ
with ClassMemberMixin, StaticMemberMixin {
StaticFieldElementZ(ObjectDecoder decoder)
: super(decoder);
}
class InstanceFieldElementZ extends FieldElementZ
with ClassMemberMixin, InstanceMemberMixin {
InstanceFieldElementZ(ObjectDecoder decoder)
: super(decoder);
}
abstract class FunctionElementZ extends DeserializedElementZ
with AnalyzableElementMixin,
AstElementMixin,
ParametersMixin,
FunctionTypedElementMixin,
TypedElementMixin,
MemberElementMixin
implements MethodElement {
FunctionElementZ(ObjectDecoder decoder)
: super(decoder);
@override
ElementKind get kind => ElementKind.FUNCTION;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitFunctionElement(this, arg);
}
@override
bool get isOperator => _decoder.getBool(Key.IS_OPERATOR);
}
class TopLevelFunctionElementZ extends FunctionElementZ
with LibraryMemberMixin {
TopLevelFunctionElementZ(ObjectDecoder decoder)
: super(decoder);
}
class StaticFunctionElementZ extends FunctionElementZ
with ClassMemberMixin, StaticMemberMixin {
StaticFunctionElementZ(ObjectDecoder decoder)
: super(decoder);
}
class InstanceFunctionElementZ extends FunctionElementZ
with ClassMemberMixin, InstanceMemberMixin {
InstanceFunctionElementZ(ObjectDecoder decoder)
: super(decoder);
}
abstract class GetterElementZ extends DeserializedElementZ
with AnalyzableElementMixin,
AstElementMixin,
FunctionTypedElementMixin,
ParametersMixin,
TypedElementMixin,
MemberElementMixin
implements FunctionElement {
GetterElementZ(ObjectDecoder decoder)
: super(decoder);
@override
ElementKind get kind => ElementKind.GETTER;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitFunctionElement(this, arg);
}
}
class TopLevelGetterElementZ extends GetterElementZ with LibraryMemberMixin {
TopLevelGetterElementZ(ObjectDecoder decoder)
: super(decoder);
}
class StaticGetterElementZ extends GetterElementZ
with ClassMemberMixin, StaticMemberMixin {
StaticGetterElementZ(ObjectDecoder decoder)
: super(decoder);
}
class InstanceGetterElementZ extends GetterElementZ
with ClassMemberMixin, InstanceMemberMixin {
InstanceGetterElementZ(ObjectDecoder decoder)
: super(decoder);
}
abstract class SetterElementZ extends DeserializedElementZ
with AnalyzableElementMixin,
AstElementMixin,
FunctionTypedElementMixin,
ParametersMixin,
TypedElementMixin,
MemberElementMixin
implements FunctionElement {
SetterElementZ(ObjectDecoder decoder)
: super(decoder);
@override
ElementKind get kind => ElementKind.SETTER;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitFunctionElement(this, arg);
}
}
class TopLevelSetterElementZ extends SetterElementZ with LibraryMemberMixin {
TopLevelSetterElementZ(ObjectDecoder decoder)
: super(decoder);
}
class StaticSetterElementZ extends SetterElementZ
with ClassMemberMixin, StaticMemberMixin {
StaticSetterElementZ(ObjectDecoder decoder)
: super(decoder);
}
class InstanceSetterElementZ extends SetterElementZ
with ClassMemberMixin, InstanceMemberMixin {
InstanceSetterElementZ(ObjectDecoder decoder)
: super(decoder);
}
abstract class TypeDeclarationMixin<T extends GenericType>
implements DeserializedElementZ, TypeDeclarationElement {
List<DartType> _typeVariables;
T _rawType;
T _thisType;
Name _memberName;
Name get memberName {
if (_memberName == null) {
_memberName = new Name(name, library);
}
return _memberName;
}
void _ensureTypes() {
if (_typeVariables == null) {
_typeVariables = _decoder.getTypes(
Key.TYPE_VARIABLES, isOptional: true);
_rawType = _createType(new List<DartType>.filled(
_typeVariables.length, const DynamicType()));
_thisType = _createType(_typeVariables);
}
}
T _createType(List<DartType> typeArguments);
@override
List<DartType> get typeVariables {
_ensureTypes();
return _typeVariables;
}
@override
T get rawType {
_ensureTypes();
return _rawType;
}
@override
T get thisType {
_ensureTypes();
return _thisType;
}
@override
T computeType(Resolution resolution) => thisType;
@override
bool get isResolved => true;
}
class TypedefElementZ extends DeserializedElementZ
with AnalyzableElementMixin,
AstElementMixin,
LibraryMemberMixin,
ParametersMixin,
TypeDeclarationMixin<TypedefType>
implements TypedefElement {
DartType _alias;
TypedefElementZ(ObjectDecoder decoder)
: super(decoder);
TypedefType _createType(List<DartType> typeArguments) {
return new TypedefType(this, typeArguments);
}
@override
ElementKind get kind => ElementKind.TYPEDEF;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitTypedefElement(this, arg);
}
@override
DartType get alias {
if (_alias == null) {
_alias = _decoder.getType(Key.ALIAS);
}
return _alias;
}
@override
void ensureResolved(Resolution resolution) {}
@override
void checkCyclicReference(Resolution resolution) {}
}
class TypeVariableElementZ extends DeserializedElementZ
with AnalyzableElementMixin,
AstElementMixin,
TypedElementMixin
implements TypeVariableElement {
TypeDeclarationElement _typeDeclaration;
TypeVariableType _type;
DartType _bound;
Name _memberName;
TypeVariableElementZ(ObjectDecoder decoder)
: super(decoder);
Name get memberName {
if (_memberName == null) {
_memberName = new Name(name, library);
}
return _memberName;
}
@override
ElementKind get kind => ElementKind.TYPE_VARIABLE;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitTypeVariableElement(this, arg);
}
@override
CompilationUnitElement get compilationUnit {
return typeDeclaration.compilationUnit;
}
@override
Element get enclosingElement => typeDeclaration;
@override
Element get enclosingClass => typeDeclaration;
@override
int get index => _decoder.getInt(Key.INDEX);
@override
TypeDeclarationElement get typeDeclaration {
if (_typeDeclaration == null) {
_typeDeclaration =
_decoder.getElement(Key.TYPE_DECLARATION);
}
return _typeDeclaration;
}
DartType get bound {
if (_bound == null) {
_bound = _decoder.getType(Key.BOUND);
}
return _bound;
}
@override
LibraryElement get library => typeDeclaration.library;
}
class ParameterElementZ extends DeserializedElementZ
with AnalyzableElementMixin,
AstElementMixin,
TypedElementMixin
implements ParameterElement {
FunctionElement _functionDeclaration;
ConstantExpression _constant;
DartType _type;
ParameterElementZ(ObjectDecoder decoder) : super(decoder);
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitParameterElement(this, arg);
}
@override
ConstantExpression get constant {
if (isOptional) {
if (_constant == null) {
_constant = _decoder.getConstant(Key.CONSTANT);
}
return _constant;
}
return null;
}
@override
CompilationUnitElement get compilationUnit {
return functionDeclaration.compilationUnit;
}
@override
ExecutableElement get executableContext => functionDeclaration;
@override
Element get enclosingElement => functionDeclaration;
@override
FunctionElement get functionDeclaration {
if (_functionDeclaration == null) {
_functionDeclaration = _decoder.getElement(Key.FUNCTION);
}
return _functionDeclaration;
}
@override
FunctionSignature get functionSignature => _unsupported('functionSignature');
@override
Expression get initializer => _unsupported('initializer');
@override
bool get isNamed => _decoder.getBool(Key.IS_NAMED);
@override
bool get isOptional => _decoder.getBool(Key.IS_OPTIONAL);
@override
ElementKind get kind => ElementKind.PARAMETER;
@override
LibraryElement get library => executableContext.library;
@override
MemberElement get memberContext => executableContext.memberContext;
}
class InitializingFormalElementZ extends ParameterElementZ
implements InitializingFormalElement {
FieldElement _fieldElement;
InitializingFormalElementZ(ObjectDecoder decoder)
: super(decoder);
@override
FieldElement get fieldElement {
if (_fieldElement == null) {
_fieldElement = _decoder.getElement(Key.FIELD);
}
return _fieldElement;
}
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitFieldParameterElement(this, arg);
}
@override
ElementKind get kind => ElementKind.INITIALIZING_FORMAL;
}
class ImportElementZ extends DeserializedElementZ
with LibraryMemberMixin implements ImportElement {
bool _isDeferred;
PrefixElement _prefix;
LibraryElement _importedLibrary;
Uri _uri;
ImportElementZ(ObjectDecoder decoder)
: super(decoder);
@override
String get name => '';
@override
accept(ElementVisitor visitor, arg) => visitor.visitImportElement(this, arg);
@override
ElementKind get kind => ElementKind.IMPORT;
@override
LibraryElement get importedLibrary {
if (_importedLibrary == null) {
_importedLibrary = _decoder.getElement(Key.LIBRARY_DEPENDENCY);
}
return _importedLibrary;
}
void _ensurePrefixResolved() {
if (_isDeferred == null) {
_isDeferred = _decoder.getBool(Key.IS_DEFERRED);
_prefix = _decoder.getElement(Key.PREFIX, isOptional: true);
}
}
@override
bool get isDeferred {
_ensurePrefixResolved();
return _isDeferred;
}
@override
PrefixElement get prefix {
_ensurePrefixResolved();
return _prefix;
}
@override
Uri get uri {
if (_uri == null) {
_uri = _decoder.getUri(Key.URI);
}
return _uri;
}
@override
Import get node => _unsupported('node');
String toString() => 'Z$kind($uri)';
}
class ExportElementZ extends DeserializedElementZ
with LibraryMemberMixin implements ExportElement {
LibraryElement _exportedLibrary;
Uri _uri;
ExportElementZ(ObjectDecoder decoder)
: super(decoder);
@override
String get name => '';
@override
accept(ElementVisitor visitor, arg) => visitor.visitExportElement(this, arg);
@override
ElementKind get kind => ElementKind.EXPORT;
@override
LibraryElement get exportedLibrary {
if (_exportedLibrary == null) {
_exportedLibrary = _decoder.getElement(Key.LIBRARY_DEPENDENCY);
}
return _exportedLibrary;
}
@override
Uri get uri {
if (_uri == null) {
_uri = _decoder.getUri(Key.URI);
}
return _uri;
}
@override
Export get node => _unsupported('node');
String toString() => 'Z$kind($uri)';
}
class PrefixElementZ extends DeserializedElementZ
with LibraryMemberMixin implements PrefixElement {
bool _isDeferred;
ImportElement _deferredImport;
PrefixElementZ(ObjectDecoder decoder)
: super(decoder);
@override
accept(ElementVisitor visitor, arg) => visitor.visitPrefixElement(this, arg);
void _ensureDeferred() {
if (_isDeferred == null) {
_isDeferred = _decoder.getBool(Key.IS_DEFERRED);
_deferredImport = _decoder.getElement(Key.IMPORT, isOptional: true);
}
}
@override
ImportElement get deferredImport {
_ensureDeferred();
return _deferredImport;
}
@override
bool get isDeferred {
_ensureDeferred();
return _isDeferred;
}
@override
ElementKind get kind => ElementKind.PREFIX;
@override
Element lookupLocalMember(String memberName) {
return _unsupported('lookupLocalMember');
}
}