blob: 34549ec2a00dd6588cc98ff3a19995c2cc5e8bb6 [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 '../constants/constructors.dart';
import '../constants/expressions.dart';
import '../elements/resolution_types.dart';
import '../elements/common.dart';
import '../elements/elements.dart';
import '../elements/entities.dart';
import '../elements/modelx.dart' show FunctionSignatureX;
import '../elements/names.dart';
import '../elements/visitor.dart';
import '../io/source_file.dart';
import '../ordered_typeset.dart';
import '../resolution/class_members.dart' as class_members;
import '../resolution/scope.dart' show Scope;
import '../resolution/tree_elements.dart' show TreeElements;
import '../script.dart';
import '../serialization/constant_serialization.dart';
import 'package:front_end/src/fasta/scanner.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('buildScope');
@override
ClassElement get enclosingClass => null;
@override
LibraryElement get implementationLibrary => library;
@override
bool get isAbstract => false;
@override
bool get isClassMember => false;
@override
bool get isClosure => false;
@override
bool get isConst => false;
@override
bool get isDeferredLoaderGetter => false;
@override
bool get isFinal => false;
@override
bool get isInstanceMember => false;
@override
bool get isLocal => false;
@override
bool get isMixinApplication => false;
@override
bool get isOperator => false;
@override
bool get isStatic => false;
@override
bool get isSynthesized => false;
@override
bool get isTopLevel => false;
@override
Iterable<MetadataAnnotation> get metadata => const <MetadataAnnotation>[];
@override
Token get position => _unsupported('position');
}
abstract class DeserializedElementZ extends ElementZ {
ObjectDecoder _decoder;
List<MetadataAnnotation> _metadata;
DeserializedElementZ(this._decoder);
@override
String get name => _decoder.getString(Key.NAME);
// TODO(johnniwinther): Should this be cached?
@override
int get sourceOffset => _decoder.getInt(Key.OFFSET, isOptional: true);
@override
SourceSpan get sourcePosition {
// TODO(johnniwinther): Should this be cached?
int offset = sourceOffset;
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);
}
@override
Iterable<MetadataAnnotation> get metadata {
if (_metadata == null) {
_metadata = <MetadataAnnotation>[];
ListDecoder list = _decoder.getList(Key.METADATA, isOptional: true);
if (list != null) {
for (int index = 0; index < list.length; index++) {
ObjectDecoder object = list.getObject(index);
Element element = object.getElement(Key.ELEMENT);
Uri uri = object.getUri(Key.URI);
int offset = object.getInt(Key.OFFSET);
int length = object.getInt(Key.LENGTH);
ConstantExpression constant = object.getConstant(Key.CONSTANT);
_metadata.add(new MetadataAnnotationZ(
element, new SourceSpan(uri, offset, offset + length), constant));
}
}
}
return _metadata;
}
}
/// 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;
SetterElement 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.isDeferredLoaderGetter) {
// Store directly.
// TODO(johnniwinther): Should modelx be normalized to put `loadLibrary`
// in an [AbstractFieldElement] instead?
_lookupMap[name] = element;
} else 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 AstElementMixinZ<N extends Node>
implements AstElement, ElementZ {
ResolvedAst _resolvedAst;
// TODO(johnniwinther): This is needed for the token invariant assertion. Find
// another way to bypass the test for modelz.
@override
bool get hasNode => false;
@override
bool get hasResolvedAst => _resolvedAst != null;
@override
N get node => _unsupported('node');
@override
ResolvedAst get resolvedAst {
assert(_resolvedAst != null,
failedAt(this, "ResolvedAst has not been set for $this."));
return _resolvedAst;
}
void set resolvedAst(ResolvedAst value) {
assert(_resolvedAst == null,
failedAt(this, "ResolvedAst has already been set for $this."));
_resolvedAst = value;
}
}
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
with AbstractFieldElementCommon
implements AbstractFieldElement {
final String name;
final GetterElementZ getter;
final SetterElementZ setter;
factory AbstractFieldElementZ(
String name, GetterElement getter, SetterElement setter) {
if (getter?.abstractField != null) {
return getter.abstractField;
} else if (setter?.abstractField != null) {
return setter.abstractField;
} else {
return new AbstractFieldElementZ._(name, getter, setter);
}
}
AbstractFieldElementZ._(this.name, this.getter, this.setter) {
if (getter != null) {
getter.abstractField = this;
getter.setter = setter;
}
if (setter != null) {
setter.abstractField = this;
setter.getter = getter;
}
}
FunctionElement get _canonicalElement => getter != null ? getter : setter;
@override
ElementKind get kind => ElementKind.ABSTRACT_FIELD;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitAbstractFieldElement(this, arg);
}
@override
LibraryElement get library => _canonicalElement.library;
@override
CompilationUnitElement get compilationUnit {
return _canonicalElement.compilationUnit;
}
@override
Element get enclosingElement => _canonicalElement.enclosingElement;
@override
int get sourceOffset => _canonicalElement.sourceOffset;
@override
SourceSpan get sourcePosition => _canonicalElement.sourcePosition;
@override
ClassElement get enclosingClass => _canonicalElement.enclosingClass;
@override
bool get isClassMember => _canonicalElement.isClassMember;
@override
bool get isInstanceMember => _canonicalElement.isInstanceMember;
@override
bool get isStatic => _canonicalElement.isStatic;
@override
bool get isTopLevel => _canonicalElement.isTopLevel;
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
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<Element, List<ImportElement>> _importsFor;
LibraryElementZ(ObjectDecoder decoder) : super(decoder);
@override
ElementKind get kind => ElementKind.LIBRARY;
@override
Element get enclosingElement => null;
@override
SourceSpan get sourcePosition => entryCompilationUnit.sourcePosition;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitLibraryElement(this, arg);
}
@override
LibraryElement get library => this;
@override
CompilationUnitElement get compilationUnit => entryCompilationUnit;
@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, isOptional: true));
}
}
@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
Element findExported(String elementName) {
_ensureExports();
return _exportsMap.lookup(elementName);
}
void _ensureImports() {
if (_importsMap == null) {
_importsMap = new ListedContainer(
_decoder.getElements(Key.IMPORT_SCOPE, isOptional: true));
_importsFor = <Element, List<ImportElement>>{};
ListDecoder importsDecoder = _decoder.getList(Key.IMPORTS_FOR);
for (int index = 0; index < importsDecoder.length; index++) {
ObjectDecoder objectDecoder = importsDecoder.getObject(index);
Element key = objectDecoder.getElement(Key.ELEMENT);
List<ImportElement> imports =
objectDecoder.getElements(Key.IMPORTS, isOptional: true);
// Imports are mapped to [AbstractFieldElement] which are not serialized
// so we use getter (or setter if there is no getter) as the key.
Element importedElement = key;
if (key.isDeferredLoaderGetter) {
// Use as [importedElement].
} else if (key.isAccessor) {
AccessorElement accessor = key;
importedElement = accessor.abstractField;
}
_importsFor[importedElement] = imports;
}
}
}
@override
void forEachImport(f(Element element)) {
_ensureImports();
_importsMap.forEach(f);
}
@override
Iterable<ImportElement> getImportsFor(Element element) {
_ensureImports();
return _importsFor[element] ?? const <ImportElement>[];
}
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;
SourceFile _file;
bool _isSynthesized = false;
ScriptZ(this.resourceUri);
@override
Script copyWithFile(SourceFile file) {
throw new UnsupportedError('ScriptZ.copyWithFile');
}
@override
SourceFile get file {
if (_file == null) {
throw new UnsupportedError('ScriptZ.file');
}
return _file;
}
void set file(SourceFile value) {
_file = value;
}
// TODO(johnniwinther): Decide if it is meaningful to serialize erroneous
// elements.
@override
bool get isSynthesized => _isSynthesized;
void set isSynthesized(bool value) {
_isSynthesized = value;
}
@override
String get name {
if (_file != null) {
return _file.filename;
}
return resourceUri.toString();
}
// TODO(johnniwinther): Support the distinction between [readableUri] and
// [resourceUri]; needed for platform libraries.
@override
Uri get readableUri => resourceUri;
@override
String get text {
if (_file != null) {
return _file.slowText();
}
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
Element get enclosingElement => library;
@override
SourceSpan get sourcePosition => new SourceSpan(script.resourceUri, 0, 0);
@override
bool get isTopLevel => false;
@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;
CompilationUnitElement _compilationUnit;
@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 {
if (_compilationUnit == null) {
_compilationUnit =
_decoder.getElement(Key.COMPILATION_UNIT, isOptional: true);
if (_compilationUnit == null) {
_compilationUnit = enclosingClass.compilationUnit;
}
}
return _compilationUnit;
}
}
abstract class InstanceMemberMixin implements DeserializedElementZ {
@override
bool get isTopLevel => false;
@override
bool get isStatic => false;
@override
bool get isInstanceMember => true;
@override
bool get isClassMember => true;
}
abstract class StaticMemberMixin implements DeserializedElementZ {
@override
bool get isTopLevel => false;
@override
bool get isStatic => true;
@override
bool get isClassMember => true;
}
abstract class TypedElementMixin<T extends ResolutionDartType>
implements DeserializedElementZ, TypedElement {
T _type;
@override
T get type {
if (_type == null) {
_type = _decoder.getType(Key.TYPE);
}
return _type;
}
@override
T 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<Element> orderedOptionalParameters = [];
int requiredParameterCount = 0;
int optionalParameterCount = 0;
bool optionalParametersAreNamed = false;
List<ResolutionDartType> parameterTypes = <ResolutionDartType>[];
List<ResolutionDartType> optionalParameterTypes = <ResolutionDartType>[];
for (ParameterElement parameter in parameters) {
if (parameter.isOptional) {
optionalParameterCount++;
optionalParameters.add(parameter);
orderedOptionalParameters.add(parameter);
if (parameter.isNamed) {
optionalParametersAreNamed = true;
} else {
optionalParameterTypes.add(parameter.type);
}
} else {
requiredParameterCount++;
requiredParameters.add(parameter);
parameterTypes.add(parameter.type);
}
}
List<String> namedParameters = const <String>[];
List<ResolutionDartType> namedParameterTypes =
const <ResolutionDartType>[];
if (optionalParametersAreNamed) {
namedParameters = <String>[];
namedParameterTypes = <ResolutionDartType>[];
orderedOptionalParameters.sort((Element a, Element b) {
return a.name.compareTo(b.name);
});
for (ParameterElement parameter in orderedOptionalParameters) {
namedParameters.add(parameter.name);
namedParameterTypes.add(parameter.type);
}
}
List<ResolutionDartType> typeVariables =
_decoder.getTypes(Key.TYPE_VARIABLES, isOptional: true);
ResolutionFunctionType type = new ResolutionFunctionType(
this,
_decoder.getType(Key.RETURN_TYPE),
parameterTypes,
optionalParameterTypes,
namedParameters,
namedParameterTypes);
_functionSignature = new FunctionSignatureX(
typeVariables: typeVariables,
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;
}
ParameterStructure get parameterStructure =>
functionSignature.parameterStructure;
}
abstract class FunctionTypedElementMixin
implements FunctionElement, DeserializedElementZ {
@override
FunctionElement asFunctionElement() => this;
@override
bool get isExternal {
return _decoder.getBool(Key.IS_EXTERNAL,
isOptional: true, defaultValue: false);
}
@override
List<ResolutionDartType> get typeVariables => functionSignature.typeVariables;
}
abstract class ClassElementMixin
implements ElementZ, ClassElement, class_members.ClassMemberMixin {
bool _isResolved = false;
ResolutionInterfaceType _createType(List<ResolutionDartType> typeArguments) {
return new ResolutionInterfaceType(this, typeArguments);
}
@override
ElementKind get kind => ElementKind.CLASS;
@override
bool get hasConstructor => _unsupported('hasConstructor');
@override
bool get hasIncompleteHierarchy => _unsupported('hasIncompleteHierarchy');
@override
bool get hasLocalScopeMembers => _unsupported('hasLocalScopeMembers');
@override
bool get isEnumClass => false;
@override
ConstructorElement lookupDefaultConstructor() {
ConstructorElement constructor = lookupConstructor("");
if (constructor != null &&
constructor.functionSignature.requiredParameterCount == 0) {
return constructor;
}
return null;
}
@override
ClassElement get superclass => supertype != null ? supertype.element : null;
@override
void ensureResolved(Resolution resolution) {
if (!_isResolved) {
_isResolved = true;
// TODO(johnniwinther): Avoid eager computation of all members. `call` is
// always needed, but the remaining should be computed on-demand or on
// type instantiation.
class_members.MembersCreator.computeAllClassMembers(resolution, this);
resolution.registerClass(this);
}
}
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class ClassElementZ extends DeserializedElementZ
with
AnalyzableElementMixin,
AstElementMixinZ,
ClassElementCommon,
class_members.ClassMemberMixin,
ContainerMixin,
LibraryMemberMixin,
TypeDeclarationMixin,
ClassElementMixin
implements ClassElement {
bool _isObject;
ResolutionInterfaceType _supertype;
OrderedTypeSet _allSupertypesAndSelf;
Link<ResolutionDartType> _interfaces;
ResolutionFunctionType _callType;
ClassElementZ(ObjectDecoder decoder) : super(decoder);
@override
List<ResolutionDartType> _getTypeVariables() {
return _decoder.getTypes(Key.TYPE_VARIABLES, isOptional: true);
}
void _ensureSuperHierarchy() {
if (_interfaces == null) {
ResolutionInterfaceType supertype =
_decoder.getType(Key.SUPERTYPE, isOptional: true);
if (supertype == null) {
_isObject = true;
_allSupertypesAndSelf = new OrderedTypeSet.singleton(thisType);
_interfaces = const Link<ResolutionDartType>();
} else {
_isObject = false;
_interfaces =
toLink(_decoder.getTypes(Key.INTERFACES, isOptional: true));
List<ResolutionInterfaceType> mixins =
_decoder.getTypes(Key.MIXINS, isOptional: true);
for (ResolutionInterfaceType mixin in mixins) {
MixinApplicationElement mixinElement =
new UnnamedMixinApplicationElementZ(this, supertype, mixin);
supertype = mixinElement.thisType
.subst(typeVariables, mixinElement.typeVariables);
}
_supertype = supertype;
_allSupertypesAndSelf = new ResolutionOrderedTypeSetBuilder(this)
.createOrderedTypeSet(_supertype, _interfaces);
_callType = _decoder.getType(Key.CALL_TYPE, isOptional: true);
}
}
}
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitClassElement(this, arg);
}
@override
ResolutionDartType get supertype {
_ensureSuperHierarchy();
return _supertype;
}
@override
bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
@override
bool get isObject {
_ensureSuperHierarchy();
return _isObject;
}
@override
OrderedTypeSet get allSupertypesAndSelf {
_ensureSuperHierarchy();
return _allSupertypesAndSelf;
}
@override
Link<ResolutionDartType> get interfaces {
_ensureSuperHierarchy();
return _interfaces;
}
@override
bool get isProxy => _decoder.getBool(Key.IS_PROXY);
@override
bool get isInjected => _decoder.getBool(Key.IS_INJECTED);
@override
bool get isUnnamedMixinApplication => false;
@override
ResolutionFunctionType get callType {
_ensureSuperHierarchy();
// TODO(johnniwinther): Why can't this always be computed in ensureResolved?
return _callType;
}
ResolutionInterfaceType get thisType => super.thisType;
ResolutionInterfaceType get rawType => super.rawType;
}
abstract class MixinApplicationElementMixin
implements ElementZ, MixinApplicationElement {
@override
bool get isMixinApplication => true;
@override
ClassElement get mixin => mixinType.element;
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class NamedMixinApplicationElementZ extends ClassElementZ
with MixinApplicationElementMixin {
Link<Element> _constructors;
ResolutionInterfaceType _mixinType;
NamedMixinApplicationElementZ(ObjectDecoder decoder) : super(decoder);
@override
ResolutionInterfaceType get mixinType =>
_mixinType ??= _decoder.getType(Key.MIXIN);
@override
ClassElement get subclass => null;
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class UnnamedMixinApplicationElementZ extends ElementZ
with
ClassElementCommon,
ClassElementMixin,
class_members.ClassMemberMixin,
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_MIXIN
TypeDeclarationMixin,
AnalyzableElementMixin,
AstElementMixinZ,
MixinApplicationElementCommon,
MixinApplicationElementMixin {
final String name;
final ClassElement subclass;
final ResolutionInterfaceType _supertypeBase;
final ResolutionInterfaceType _mixinBase;
ResolutionInterfaceType _supertype;
Link<ResolutionDartType> _interfaces;
OrderedTypeSet _allSupertypesAndSelf;
Link<ConstructorElement> _constructors;
UnnamedMixinApplicationElementZ(this.subclass,
ResolutionInterfaceType supertype, ResolutionInterfaceType mixin)
: this._supertypeBase = supertype,
this._mixinBase = mixin,
this.name = "${supertype.name}+${mixin.name}";
@override
CompilationUnitElement get compilationUnit => subclass.compilationUnit;
@override
bool get isTopLevel => true;
@override
bool get isAbstract => true;
@override
bool get isUnnamedMixinApplication => true;
Link<ConstructorElement> get constructors {
if (_constructors == null) {
LinkBuilder<ConstructorElement> builder =
new LinkBuilder<ConstructorElement>();
for (ConstructorElement definingConstructor in superclass.constructors) {
if (definingConstructor.isGenerativeConstructor &&
definingConstructor.memberName.isAccessibleFrom(library)) {
ForwardingConstructorElementZ constructor =
new ForwardingConstructorElementZ(this, definingConstructor);
constructor.resolvedAst = new SynthesizedResolvedAst(
constructor, ResolvedAstKind.FORWARDING_CONSTRUCTOR);
builder.addLast(constructor);
}
}
_constructors = builder.toLink();
}
return _constructors;
}
@override
List<ResolutionDartType> _getTypeVariables() {
// Create synthetic type variables for the mixin application.
List<ResolutionDartType> typeVariables = <ResolutionDartType>[];
int index = 0;
for (ResolutionTypeVariableType type in subclass.typeVariables) {
SyntheticTypeVariableElementZ typeVariableElement =
new SyntheticTypeVariableElementZ(this, index, type.name);
ResolutionTypeVariableType typeVariable =
new ResolutionTypeVariableType(typeVariableElement);
typeVariables.add(typeVariable);
index++;
}
// Setup bounds on the synthetic type variables.
for (ResolutionTypeVariableType type in subclass.typeVariables) {
ResolutionTypeVariableType typeVariable =
typeVariables[type.element.index];
SyntheticTypeVariableElementZ typeVariableElement = typeVariable.element;
typeVariableElement._type = typeVariable;
typeVariableElement._bound =
type.element.bound.subst(typeVariables, subclass.typeVariables);
}
return typeVariables;
}
@override
ResolutionInterfaceType get supertype {
if (_supertype == null) {
// Substitute the type variables in [_supertypeBase] provided by
// [_subclass] with the type variables in this unnamed mixin application.
//
// For instance
// class S<S.T> {}
// class M<M.T> {}
// class C<C.T> extends S<C.T> with M<C.T> {}
// the unnamed mixin application should be
// abstract class S+M<S+M.T> extends S<S+M.T> implements M<S+M.T> {}
// but the supertype is provided as S<C.T> and we need to substitute S+M.T
// for C.T.
_supertype = _supertypeBase.subst(typeVariables, subclass.typeVariables);
}
return _supertype;
}
@override
Link<ResolutionDartType> get interfaces {
if (_interfaces == null) {
// Substitute the type variables in [_mixinBase] provided by
// [_subclass] with the type variables in this unnamed mixin application.
//
// For instance
// class S<S.T> {}
// class M<M.T> {}
// class C<C.T> extends S<C.T> with M<C.T> {}
// the unnamed mixin application should be
// abstract class S+M<S+M.T> extends S<S+M.T> implements M<S+M.T> {}
// but the mixin is provided as M<C.T> and we need to substitute S+M.T
// for C.T.
_interfaces = const Link<ResolutionDartType>()
.prepend(_mixinBase.subst(typeVariables, subclass.typeVariables));
}
return _interfaces;
}
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitMixinApplicationElement(this, arg);
}
@override
OrderedTypeSet get allSupertypesAndSelf {
if (_allSupertypesAndSelf == null) {
_allSupertypesAndSelf = new ResolutionOrderedTypeSetBuilder(this)
.createOrderedTypeSet(supertype, interfaces);
}
return _allSupertypesAndSelf;
}
@override
Element get enclosingElement => subclass.enclosingElement;
@override
bool get isObject => false;
@override
bool get isProxy => false;
@override
LibraryElement get library => enclosingElement.library;
@override
ResolutionInterfaceType get mixinType => interfaces.head;
@override
int get sourceOffset => subclass.sourceOffset;
@override
SourceSpan get sourcePosition => subclass.sourcePosition;
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class EnumClassElementZ extends ClassElementZ implements EnumClassElement {
List<FieldElement> _enumValues;
EnumClassElementZ(ObjectDecoder decoder) : super(decoder);
@override
bool get isEnumClass => true;
@override
List<EnumConstantElement> get enumValues {
if (_enumValues == null) {
_enumValues = _decoder.getElements(Key.FIELDS);
}
return _enumValues;
}
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
abstract class ConstructorElementZ extends DeserializedElementZ
with
AnalyzableElementMixin,
AstElementMixinZ<FunctionExpression>,
ClassMemberMixin,
FunctionTypedElementMixin,
ParametersMixin,
TypedElementMixin<ResolutionFunctionType>,
MemberElementMixin,
ConstructorElementCommon
implements
ConstructorElement,
// TODO(johnniwinther): Sort out whether a constructor is a method.
MethodElement {
ConstantConstructor _constantConstructor;
ConstructorElement _effectiveTarget;
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);
@override
bool get isMarkedExternal => isExternal;
@override
bool get isDefaultConstructor => false;
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 => AsyncMarker.SYNC;
@override
ConstructorElement get definingConstructor => null;
@override
bool get hasEffectiveTarget => true;
@override
ConstructorElement get effectiveTarget {
if (_effectiveTarget == null) {
_effectiveTarget =
_decoder.getElement(Key.EFFECTIVE_TARGET, isOptional: true);
if (_effectiveTarget == null) {
_effectiveTarget = this;
}
}
return _effectiveTarget;
}
@override
ConstructorElement get immediateRedirectionTarget => null;
// TODO(johnniwinther): Should serialization support erroneous element
// relations?
@override
bool get isEffectiveTargetMalformed => false;
@override
bool get isCyclicRedirection => false;
@override
bool get isRedirectingFactory => false;
@override
bool get isRedirectingGenerative => false;
@override
PrefixElement get redirectionDeferredPrefix => null;
@override
ResolutionDartType computeEffectiveTargetType(
ResolutionInterfaceType newType) =>
newType;
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class GenerativeConstructorElementZ extends ConstructorElementZ {
GenerativeConstructorElementZ(ObjectDecoder decoder) : super(decoder);
@override
ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
@override
bool get isRedirectingGenerative => _decoder.getBool(Key.IS_REDIRECTING);
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class DefaultConstructorElementZ extends ConstructorElementZ {
DefaultConstructorElementZ(ObjectDecoder decoder) : super(decoder);
@override
ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
@override
bool get isSynthesized => true;
@override
bool get isDefaultConstructor => true;
@override
ConstructorElement get definingConstructor {
return enclosingClass.superclass.lookupConstructor('');
}
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class FactoryConstructorElementZ extends ConstructorElementZ {
FactoryConstructorElementZ(ObjectDecoder decoder) : super(decoder);
@override
ElementKind get kind => ElementKind.FACTORY_CONSTRUCTOR;
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class RedirectingFactoryConstructorElementZ extends ConstructorElementZ {
ResolutionDartType _effectiveTargetType;
ConstructorElement _immediateRedirectionTarget;
PrefixElement _redirectionDeferredPrefix;
bool _effectiveTargetIsMalformed;
RedirectingFactoryConstructorElementZ(ObjectDecoder decoder) : super(decoder);
@override
ElementKind get kind => ElementKind.FACTORY_CONSTRUCTOR;
@override
bool get isRedirectingFactory => true;
void _ensureEffectiveTarget() {
if (_effectiveTarget == null) {
_effectiveTarget =
_decoder.getElement(Key.EFFECTIVE_TARGET, isOptional: true);
if (_effectiveTarget == null) {
_effectiveTarget = this;
_effectiveTargetType = enclosingClass.thisType;
_effectiveTargetIsMalformed = false;
} else {
_effectiveTargetType = _decoder.getType(Key.EFFECTIVE_TARGET_TYPE);
_effectiveTargetIsMalformed =
_decoder.getBool(Key.EFFECTIVE_TARGET_IS_MALFORMED);
}
}
}
bool get isEffectiveTargetMalformed {
_ensureEffectiveTarget();
return _effectiveTargetIsMalformed;
}
@override
ConstructorElement get effectiveTarget {
_ensureEffectiveTarget();
return _effectiveTarget;
}
@override
ResolutionDartType computeEffectiveTargetType(
ResolutionInterfaceType newType) {
_ensureEffectiveTarget();
return _effectiveTargetType.substByContext(newType);
}
void _ensureRedirection() {
if (_immediateRedirectionTarget == null) {
_immediateRedirectionTarget =
_decoder.getElement(Key.IMMEDIATE_REDIRECTION_TARGET);
_redirectionDeferredPrefix =
_decoder.getElement(Key.PREFIX, isOptional: true);
}
}
@override
ConstructorElement get immediateRedirectionTarget {
_ensureRedirection();
return _immediateRedirectionTarget;
}
@override
PrefixElement get redirectionDeferredPrefix {
_ensureRedirection();
return _redirectionDeferredPrefix;
}
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class ForwardingConstructorElementZ extends ElementZ
with
AnalyzableElementMixin,
AstElementMixinZ<FunctionExpression>
implements
ConstructorElement,
// TODO(johnniwinther): Sort out whether a constructor is a method.
MethodElement {
final MixinApplicationElement enclosingClass;
final ConstructorElement definingConstructor;
ForwardingConstructorElementZ(this.enclosingClass, this.definingConstructor);
@override
CompilationUnitElement get compilationUnit => enclosingClass.compilationUnit;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitConstructorElement(this, arg);
}
@override
AsyncMarker get asyncMarker => AsyncMarker.SYNC;
@override
ResolutionDartType computeEffectiveTargetType(
ResolutionInterfaceType newType) {
return enclosingClass.thisType.substByContext(newType);
}
@override
ResolutionDartType computeType(Resolution resolution) => type;
@override
bool get isConst => false;
@override
bool get isClassMember => true;
@override
bool get isDefaultConstructor => false;
@override
ConstantConstructor get constantConstructor => null;
@override
bool get hasEffectiveTarget => true;
@override
ConstructorElement get effectiveTarget => this;
@override
Element get enclosingElement => enclosingClass;
@override
FunctionSignature get functionSignature {
// TODO(johnniwinther): Ensure that the function signature (and with it the
// function type) substitutes type variables correctly.
return definingConstructor.functionSignature;
}
@override
ParameterStructure get parameterStructure {
return functionSignature.parameterStructure;
}
@override
bool get hasFunctionSignature {
return _unsupported('hasFunctionSignature');
}
@override
ConstructorElement get immediateRedirectionTarget => null;
@override
bool get isCyclicRedirection => false;
@override
bool get isEffectiveTargetMalformed => false;
@override
bool get isExternal => false;
@override
bool get isMarkedExternal => false;
@override
bool get isFromEnvironmentConstructor => false;
@override
bool get isIntFromEnvironmentConstructor => false;
@override
bool get isBoolFromEnvironmentConstructor => false;
@override
bool get isStringFromEnvironmentConstructor => false;
@override
bool get isRedirectingFactory => false;
@override
bool get isRedirectingGenerative => false;
@override
bool get isSynthesized => true;
@override
ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
@override
LibraryElement get library => enclosingClass.library;
@override
MemberElement get memberContext => this;
@override
Name get memberName => definingConstructor.memberName;
@override
String get name => definingConstructor.name;
@override
List<MethodElement> get nestedClosures => const <MethodElement>[];
@override
List<ParameterElement> get parameters {
// TODO(johnniwinther): We need to create synthetic parameters that
// substitute type variables.
return definingConstructor.parameters;
}
// TODO: implement redirectionDeferredPrefix
@override
PrefixElement get redirectionDeferredPrefix => null;
@override
int get sourceOffset => enclosingClass.sourceOffset;
@override
SourceSpan get sourcePosition => enclosingClass.sourcePosition;
@override
ResolutionFunctionType get type {
// TODO(johnniwinther): Ensure that the function type substitutes type
// variables correctly.
return definingConstructor.type;
}
@override
List<ResolutionDartType> get typeVariables => _unsupported("typeVariables");
}
abstract class MemberElementMixin
implements DeserializedElementZ, MemberElement {
final List<MethodElement> nestedClosures = <MethodElement>[];
@override
MemberElement get memberContext => this;
@override
Name get memberName => new Name(name, library);
@override
bool get isInjected => _decoder.getBool(Key.IS_INJECTED);
}
abstract class FieldElementZ extends DeserializedElementZ
with
AnalyzableElementMixin,
AstElementMixinZ<VariableDefinitions>,
TypedElementMixin,
MemberElementMixin
implements FieldElement {
bool _isConst;
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);
void _ensureConstant() {
if (_isConst == null) {
_isConst = _decoder.getBool(Key.IS_CONST);
_constant = _decoder.getConstant(Key.CONSTANT, isOptional: true);
}
}
@override
bool get isConst {
_ensureConstant();
return _isConst;
}
@override
bool get hasConstant => true;
@override
ConstantExpression get constant {
_ensureConstant();
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);
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class EnumConstantElementZ extends StaticFieldElementZ
implements EnumConstantElement {
EnumConstantElementZ(ObjectDecoder decoder) : super(decoder);
int get index => _decoder.getInt(Key.INDEX);
}
class InstanceFieldElementZ extends FieldElementZ
with ClassMemberMixin, InstanceMemberMixin {
InstanceFieldElementZ(ObjectDecoder decoder) : super(decoder);
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
abstract class FunctionElementZ extends DeserializedElementZ
with
AnalyzableElementMixin,
AstElementMixinZ<FunctionExpression>,
ParametersMixin,
FunctionTypedElementMixin,
TypedElementMixin<ResolutionFunctionType>,
MemberElementMixin
implements MethodElement {
FunctionElementZ(ObjectDecoder decoder) : super(decoder);
@override
ElementKind get kind => ElementKind.FUNCTION;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitMethodElement(this, arg);
}
@override
AsyncMarker get asyncMarker {
return _decoder.getEnum(Key.ASYNC_MARKER, AsyncMarker.values);
}
@override
bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
@override
bool get isOperator => _decoder.getBool(Key.IS_OPERATOR);
@override
bool get isMarkedExternal => isExternal;
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class TopLevelFunctionElementZ extends FunctionElementZ
with LibraryMemberMixin {
TopLevelFunctionElementZ(ObjectDecoder decoder) : super(decoder);
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class StaticFunctionElementZ extends FunctionElementZ
with ClassMemberMixin, StaticMemberMixin {
StaticFunctionElementZ(ObjectDecoder decoder) : super(decoder);
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class InstanceFunctionElementZ extends FunctionElementZ
with ClassMemberMixin, InstanceMemberMixin {
InstanceFunctionElementZ(ObjectDecoder decoder) : super(decoder);
}
abstract class LocalExecutableMixin
implements DeserializedElementZ, ExecutableElement, LocalElement {
ExecutableElement _executableContext;
@override
Element get enclosingElement => executableContext;
@override
ClassElementZ get enclosingClass => memberContext.enclosingClass;
@override
ExecutableElement get executableContext {
if (_executableContext == null) {
_executableContext = _decoder.getElement(Key.EXECUTABLE_CONTEXT);
}
return _executableContext;
}
@override
MemberElement get memberContext => executableContext.memberContext;
@override
bool get isLocal => true;
@override
LibraryElement get library => memberContext.library;
@override
CompilationUnitElement get compilationUnit {
return memberContext.compilationUnit;
}
@override
bool get hasTreeElements => memberContext.hasTreeElements;
@override
TreeElements get treeElements => memberContext.treeElements;
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class LocalFunctionElementZ extends DeserializedElementZ
with
LocalExecutableMixin,
AstElementMixinZ<FunctionExpression>,
ParametersMixin,
FunctionTypedElementMixin,
TypedElementMixin<ResolutionFunctionType>
implements LocalFunctionElement {
LocalFunctionElementZ(ObjectDecoder decoder) : super(decoder);
MethodElement callMethod;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitLocalFunctionElement(this, arg);
}
@override
ElementKind get kind => ElementKind.FUNCTION;
@override
AsyncMarker get asyncMarker {
return _decoder.getEnum(Key.ASYNC_MARKER, AsyncMarker.values);
}
@override
bool get isMarkedExternal => false;
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
abstract class GetterElementZ extends DeserializedElementZ
with
AnalyzableElementMixin,
AstElementMixinZ<FunctionExpression>,
FunctionTypedElementMixin,
ParametersMixin,
TypedElementMixin<ResolutionFunctionType>,
MemberElementMixin
implements GetterElement {
AbstractFieldElement abstractField;
SetterElement setter;
GetterElementZ(ObjectDecoder decoder) : super(decoder);
@override
ElementKind get kind => ElementKind.GETTER;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitGetterElement(this, arg);
}
@override
bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
@override
bool get isMarkedExternal => isExternal;
@override
AsyncMarker get asyncMarker {
return _decoder.getEnum(Key.ASYNC_MARKER, AsyncMarker.values);
}
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class TopLevelGetterElementZ extends GetterElementZ with LibraryMemberMixin {
TopLevelGetterElementZ(ObjectDecoder decoder) : super(decoder);
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class StaticGetterElementZ extends GetterElementZ
with ClassMemberMixin, StaticMemberMixin {
StaticGetterElementZ(ObjectDecoder decoder) : super(decoder);
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class InstanceGetterElementZ extends GetterElementZ
with ClassMemberMixin, InstanceMemberMixin {
InstanceGetterElementZ(ObjectDecoder decoder) : super(decoder);
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
abstract class SetterElementZ extends DeserializedElementZ
with
AnalyzableElementMixin,
AstElementMixinZ<FunctionExpression>,
FunctionTypedElementMixin,
ParametersMixin,
TypedElementMixin<ResolutionFunctionType>,
MemberElementMixin
implements SetterElement {
AbstractFieldElement abstractField;
GetterElement getter;
SetterElementZ(ObjectDecoder decoder) : super(decoder);
@override
ElementKind get kind => ElementKind.SETTER;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitSetterElement(this, arg);
}
@override
bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
@override
bool get isMarkedExternal => isExternal;
@override
AsyncMarker get asyncMarker => AsyncMarker.SYNC;
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class TopLevelSetterElementZ extends SetterElementZ with LibraryMemberMixin {
TopLevelSetterElementZ(ObjectDecoder decoder) : super(decoder);
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class StaticSetterElementZ extends SetterElementZ
with ClassMemberMixin, StaticMemberMixin {
StaticSetterElementZ(ObjectDecoder decoder) : super(decoder);
}
// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
class InstanceSetterElementZ extends SetterElementZ
with ClassMemberMixin, InstanceMemberMixin {
InstanceSetterElementZ(ObjectDecoder decoder) : super(decoder);
}
abstract class TypeDeclarationMixin
implements ElementZ, TypeDeclarationElement {
List<ResolutionDartType> _typeVariables;
GenericType _rawType;
GenericType _thisType;
Name _memberName;
Name get memberName {
if (_memberName == null) {
_memberName = new Name(name, library);
}
return _memberName;
}
List<ResolutionDartType> _getTypeVariables();
void _ensureTypes() {
if (_typeVariables == null) {
_typeVariables = _getTypeVariables();
_rawType = _createType(new List<ResolutionDartType>.filled(
_typeVariables.length, const ResolutionDynamicType()));
_thisType = _createType(_typeVariables);
}
}
GenericType _createType(List<ResolutionDartType> typeArguments);
@override
List<ResolutionDartType> get typeVariables {
_ensureTypes();
return _typeVariables;
}
@override
GenericType get rawType {
_ensureTypes();
return _rawType;
}
@override
GenericType get thisType {
_ensureTypes();
return _thisType;
}
@override
GenericType computeType(Resolution resolution) => thisType;
@override
bool get isResolved => true;
}
class TypedefElementZ extends DeserializedElementZ
with
AnalyzableElementMixin,
AstElementMixinZ<Node>,
LibraryMemberMixin,
ParametersMixin,
TypeDeclarationMixin
implements TypedefElement {
ResolutionDartType _alias;
TypedefElementZ(ObjectDecoder decoder) : super(decoder);
ResolutionTypedefType _createType(List<ResolutionDartType> typeArguments) {
return new ResolutionTypedefType(this, typeArguments);
}
@override
List<ResolutionDartType> _getTypeVariables() {
return _decoder.getTypes(Key.TYPE_VARIABLES, isOptional: true);
}
@override
ElementKind get kind => ElementKind.TYPEDEF;
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitTypedefElement(this, arg);
}
@override
ResolutionDartType get alias {
if (_alias == null) {
_alias = _decoder.getType(Key.ALIAS);
}
return _alias;
}
@override
void ensureResolved(Resolution resolution) {}
@override
void checkCyclicReference(Resolution resolution) {}
ResolutionTypedefType get thisType => super.thisType;
ResolutionTypedefType get rawType => super.rawType;
}
class TypeVariableElementZ extends DeserializedElementZ
with
AnalyzableElementMixin,
AstElementMixinZ<Node>,
TypedElementMixin<ResolutionTypeVariableType>
implements TypeVariableElement {
GenericElement _typeDeclaration;
ResolutionTypeVariableType _type;
ResolutionDartType _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
ClassElementZ get enclosingClass => typeDeclaration;
@override
int get index => _decoder.getInt(Key.INDEX);
@override
GenericElement get typeDeclaration {
if (_typeDeclaration == null) {
_typeDeclaration = _decoder.getElement(Key.TYPE_DECLARATION);
}
return _typeDeclaration;
}
ResolutionDartType get bound {
if (_bound == null) {
_bound = _decoder.getType(Key.BOUND);
}
return _bound;
}
@override
LibraryElement get library => typeDeclaration.library;
}
class SyntheticTypeVariableElementZ extends ElementZ
with AnalyzableElementMixin, AstElementMixinZ<Node>
implements TypeVariableElement {
final TypeDeclarationElement typeDeclaration;
final int index;
final String name;
ResolutionTypeVariableType _type;
ResolutionDartType _bound;
Name _memberName;
SyntheticTypeVariableElementZ(this.typeDeclaration, this.index, this.name);
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
ResolutionTypeVariableType get type {
assert(_type != null,
failedAt(this, "Type variable type has not been set on $this."));
return _type;
}
@override
ResolutionTypeVariableType computeType(Resolution resolution) => type;
@override
Element get enclosingElement => typeDeclaration;
@override
ClassElementZ get enclosingClass => typeDeclaration;
ResolutionDartType get bound {
assert(_bound != null,
failedAt(this, "Type variable bound has not been set on $this."));
return _bound;
}
@override
LibraryElement get library => typeDeclaration.library;
@override
int get sourceOffset => typeDeclaration.sourceOffset;
@override
SourceSpan get sourcePosition => typeDeclaration.sourcePosition;
}
abstract class ParameterElementZ extends DeserializedElementZ
with
AnalyzableElementMixin,
AstElementMixinZ<VariableDefinitions>,
TypedElementMixin
implements ParameterElement {
FunctionElement _functionDeclaration;
ConstantExpression _constant;
ResolutionDartType _type;
ParameterElementZ(ObjectDecoder decoder) : super(decoder);
@override
bool get isFinal => _decoder.getBool(Key.IS_FINAL);
@override
bool get isConst => false;
@override
bool get hasConstant => true;
@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');
// TODO(johnniwinther): Remove [initializer] and [node] on
// [ParameterElementZ] when the inference does need these.
@override
Expression initializer;
@override
VariableDefinitions node;
@override
bool get isNamed => _decoder.getBool(Key.IS_NAMED);
@override
bool get isOptional => _decoder.getBool(Key.IS_OPTIONAL);
@override
LibraryElement get library => executableContext.library;
@override
MemberElement get memberContext => executableContext.memberContext;
@override
List<ResolutionDartType> get typeVariables => functionSignature.typeVariables;
}
class LocalParameterElementZ extends ParameterElementZ
implements LocalParameterElement {
LocalParameterElementZ(ObjectDecoder decoder) : super(decoder);
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitParameterElement(this, arg);
}
@override
bool get isLocal => true;
@override
ElementKind get kind => ElementKind.PARAMETER;
@override
bool get isUnnamed => false;
}
class InitializingFormalElementZ extends LocalParameterElementZ
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;
@override
bool get isLocal => true;
ConstructorElementZ get functionDeclaration => super.functionDeclaration;
}
class LocalVariableElementZ extends DeserializedElementZ
with
AnalyzableElementMixin,
AstElementMixinZ<VariableDefinitions>,
LocalExecutableMixin,
TypedElementMixin
implements LocalVariableElement {
bool _isConst;
ConstantExpression _constant;
LocalVariableElementZ(ObjectDecoder decoder) : super(decoder);
@override
accept(ElementVisitor visitor, arg) {
return visitor.visitLocalVariableElement(this, arg);
}
@override
ElementKind get kind => ElementKind.VARIABLE;
@override
bool get isFinal => _decoder.getBool(Key.IS_FINAL);
@override
bool get isConst {
if (_isConst == null) {
_constant = _decoder.getConstant(Key.CONSTANT, isOptional: true);
_isConst = _constant != null;
}
return _isConst;
}
@override
bool get hasConstant => true;
@override
ConstantExpression get constant {
if (isConst) {
return _constant;
}
return null;
}
@override
Expression get initializer => _unsupported('initializer');
}
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);
}
}
LibraryElement get enclosingLibrary => library;
@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;
GetterElement _loadLibrary;
ListedContainer _members;
PrefixElementZ(ObjectDecoder decoder) : super(decoder);
@override
accept(ElementVisitor visitor, arg) => visitor.visitPrefixElement(this, arg);
@override
bool get isTopLevel => false;
void _ensureDeferred() {
if (_isDeferred == null) {
_isDeferred = _decoder.getBool(Key.IS_DEFERRED);
if (_isDeferred) {
_deferredImport = _decoder.getElement(Key.IMPORT);
_loadLibrary = _decoder.getElement(Key.GETTER);
}
}
}
@override
ImportElement get deferredImport {
_ensureDeferred();
return _deferredImport;
}
@override
bool get isDeferred {
_ensureDeferred();
return _isDeferred;
}
@override
GetterElement get loadLibrary {
return _loadLibrary;
}
@override
ElementKind get kind => ElementKind.PREFIX;
void _ensureMembers() {
if (_members == null) {
_members = new ListedContainer(
_decoder.getElements(Key.MEMBERS, isOptional: true));
}
}
@override
Element lookupLocalMember(String memberName) {
_ensureMembers();
return _members.lookup(memberName);
}
@override
void forEachLocalMember(void f(Element member)) {
_ensureMembers();
_members.forEach(f);
}
}
class MetadataAnnotationZ implements MetadataAnnotation {
final Element annotatedElement;
final SourceSpan sourcePosition;
final ConstantExpression constant;
MetadataAnnotationZ(
this.annotatedElement, this.sourcePosition, this.constant);
@override
MetadataAnnotation ensureResolved(Resolution resolution) {
// Do nothing.
return this;
}
@override
Node get node => throw new UnsupportedError('${this}.node');
@override
bool get hasNode => false;
String toString() => 'MetadataAnnotationZ(${constant.toDartText()})';
}