mirror of
https://github.com/dart-lang/sdk
synced 2024-09-21 07:21:29 +00:00
Remove use of Element in ResolutionEnqueuerListener.
This makes ResolutionEnqueuerListener reusable for kernel-based elements. R=efortuna@google.com Review-Url: https://codereview.chromium.org/2797173004 .
This commit is contained in:
parent
12615de38f
commit
7108d7b7a4
|
@ -8,6 +8,7 @@ library dart2js.type_system;
|
|||
import 'common/names.dart' show Uris;
|
||||
import 'elements/types.dart';
|
||||
import 'elements/entities.dart';
|
||||
import 'universe/call_structure.dart';
|
||||
|
||||
/// The common elements and types in Dart.
|
||||
abstract class CommonElements {
|
||||
|
@ -284,6 +285,17 @@ abstract class ElementEnvironment {
|
|||
|
||||
/// Returns `true` if [a] is a subtype of [b].
|
||||
bool isSubtype(DartType a, DartType b);
|
||||
|
||||
/// Returns the type if [function].
|
||||
FunctionType getFunctionType(FunctionEntity function);
|
||||
|
||||
/// Returns the [CallStructure] corresponding to calling [entity] with all
|
||||
/// arguments, both required and optional.
|
||||
CallStructure getCallStructure(FunctionEntity entity);
|
||||
|
||||
/// Returns `true` if [member] a the synthetic getter `loadLibrary` injected
|
||||
/// on deferred libraries.
|
||||
bool isDeferredLoadLibraryGetter(MemberEntity member);
|
||||
}
|
||||
|
||||
class CommonElementsImpl implements CommonElements {
|
||||
|
|
|
@ -37,6 +37,7 @@ import 'elements/resolution_types.dart'
|
|||
show
|
||||
ResolutionDartType,
|
||||
ResolutionDynamicType,
|
||||
ResolutionFunctionType,
|
||||
ResolutionInterfaceType,
|
||||
Types;
|
||||
import 'enqueue.dart' show Enqueuer, EnqueueTask, ResolutionEnqueuer;
|
||||
|
@ -1972,4 +1973,25 @@ class _CompilerElementEnvironment implements ElementEnvironment {
|
|||
}
|
||||
return library;
|
||||
}
|
||||
|
||||
@override
|
||||
CallStructure getCallStructure(MethodElement method) {
|
||||
ResolutionFunctionType type = method.computeType(_resolution);
|
||||
return new CallStructure(
|
||||
type.parameterTypes.length +
|
||||
type.optionalParameterTypes.length +
|
||||
type.namedParameterTypes.length,
|
||||
type.namedParameters);
|
||||
}
|
||||
|
||||
@override
|
||||
bool isDeferredLoadLibraryGetter(MemberElement member) {
|
||||
return member.isDeferredLoaderGetter;
|
||||
}
|
||||
|
||||
@override
|
||||
ResolutionFunctionType getFunctionType(MethodElement method) {
|
||||
method.computeType(_resolution);
|
||||
return method.type;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,10 @@ abstract class Entity implements Spannable {
|
|||
///
|
||||
/// Currently only [LibraryElement] but later also kernel based Dart classes
|
||||
/// and/or Dart-in-JS classes.
|
||||
abstract class LibraryEntity extends Entity {}
|
||||
abstract class LibraryEntity extends Entity {
|
||||
/// Return the canonical uri that identifies this library.
|
||||
Uri get canonicalUri;
|
||||
}
|
||||
|
||||
/// Stripped down super interface for class like entities.
|
||||
///
|
||||
|
@ -83,7 +86,10 @@ abstract class MemberEntity extends Entity {
|
|||
/// Whether this member is assignable, i.e. a non-final field.
|
||||
bool get isAssignable;
|
||||
|
||||
/// The enclosing class if this is a constuctor, instance member or
|
||||
/// Whether this member is constant, i.e. a constant field or constructor.
|
||||
bool get isConst;
|
||||
|
||||
/// The enclosing class if this is a constructor, instance member or
|
||||
/// static member of a class.
|
||||
ClassEntity get enclosingClass;
|
||||
|
||||
|
|
|
@ -59,6 +59,9 @@ abstract class DartType {
|
|||
|
||||
/// Is `true` if this type is a malformed type.
|
||||
bool get isMalformed => false;
|
||||
|
||||
/// Whether this type contains a type variable.
|
||||
bool get containsTypeVariables => false;
|
||||
}
|
||||
|
||||
class InterfaceType extends DartType {
|
||||
|
@ -67,6 +70,9 @@ class InterfaceType extends DartType {
|
|||
|
||||
InterfaceType(this.element, this.typeArguments);
|
||||
|
||||
bool get containsTypeVariables =>
|
||||
typeArguments.any((type) => type.containsTypeVariables);
|
||||
|
||||
int get hashCode {
|
||||
int hash = element.hashCode;
|
||||
for (DartType argument in typeArguments) {
|
||||
|
@ -108,6 +114,8 @@ class TypeVariableType extends DartType {
|
|||
|
||||
bool get isTypeVariable => true;
|
||||
|
||||
bool get containsTypeVariables => true;
|
||||
|
||||
int get hashCode => 17 * element.hashCode;
|
||||
|
||||
bool operator ==(other) {
|
||||
|
@ -161,6 +169,13 @@ class FunctionType extends DartType {
|
|||
this.namedParameters,
|
||||
this.namedParameterTypes);
|
||||
|
||||
bool get containsTypeVariables {
|
||||
return returnType.containsTypeVariables ||
|
||||
parameterTypes.any((type) => type.containsTypeVariables) ||
|
||||
optionalParameterTypes.any((type) => type.containsTypeVariables) ||
|
||||
namedParameterTypes.any((type) => type.containsTypeVariables);
|
||||
}
|
||||
|
||||
bool get isFunctionType => true;
|
||||
|
||||
int get hashCode {
|
||||
|
|
|
@ -7,8 +7,9 @@ import '../common/resolution.dart';
|
|||
import '../common_elements.dart';
|
||||
import '../constants/constant_system.dart';
|
||||
import '../constants/values.dart';
|
||||
import '../elements/resolution_types.dart';
|
||||
import '../elements/elements.dart';
|
||||
import '../elements/entities.dart';
|
||||
import '../elements/resolution_types.dart';
|
||||
import '../universe/call_structure.dart';
|
||||
import '../universe/use.dart' show ConstantUse, StaticUse;
|
||||
import '../universe/world_impact.dart'
|
||||
|
@ -74,7 +75,7 @@ abstract class CustomElementsAnalysisBase {
|
|||
join.instantiatedClasses.add(classElement);
|
||||
}
|
||||
|
||||
void registerStaticUse(Element element) {
|
||||
void registerStaticUse(MemberEntity element) {
|
||||
assert(element != null);
|
||||
if (element == _helpers.findIndexForNativeSubclassType) {
|
||||
join.demanded = true;
|
||||
|
|
|
@ -9,7 +9,6 @@ import '../common/names.dart' show Identifiers, Uris;
|
|||
import '../common_elements.dart' show CommonElements, ElementEnvironment;
|
||||
import '../constants/values.dart';
|
||||
import '../deferred_load.dart';
|
||||
import '../elements/elements.dart';
|
||||
import '../elements/entities.dart';
|
||||
import '../elements/types.dart';
|
||||
import '../enqueue.dart' show Enqueuer, EnqueuerListener;
|
||||
|
@ -90,19 +89,21 @@ class ResolutionEnqueuerListener extends EnqueuerListener {
|
|||
_backendUsage.processBackendImpact(impact);
|
||||
}
|
||||
|
||||
void _addInterceptors(ClassElement cls, WorldImpactBuilder impactBuilder) {
|
||||
void _addInterceptors(ClassEntity cls, WorldImpactBuilder impactBuilder) {
|
||||
_interceptorData.addInterceptors(cls);
|
||||
impactBuilder.registerTypeUse(new TypeUse.instantiation(cls.rawType));
|
||||
impactBuilder.registerTypeUse(
|
||||
new TypeUse.instantiation(_elementEnvironment.getRawType(cls)));
|
||||
_backendUsage.registerBackendClassUse(cls);
|
||||
}
|
||||
|
||||
@override
|
||||
WorldImpact registerClosurizedMember(MemberElement element) {
|
||||
WorldImpact registerClosurizedMember(FunctionEntity element) {
|
||||
WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
|
||||
_backendUsage.processBackendImpact(_impacts.memberClosure);
|
||||
impactBuilder
|
||||
.addImpact(_impacts.memberClosure.createImpact(_elementEnvironment));
|
||||
if (element.type.containsTypeVariables) {
|
||||
FunctionType type = _elementEnvironment.getFunctionType(element);
|
||||
if (type.containsTypeVariables) {
|
||||
impactBuilder.addImpact(_registerComputeSignature());
|
||||
}
|
||||
return impactBuilder;
|
||||
|
@ -132,7 +133,7 @@ class ResolutionEnqueuerListener extends EnqueuerListener {
|
|||
|
||||
/// Called to enable support for isolates. Any backend specific [WorldImpact]
|
||||
/// of this is returned.
|
||||
WorldImpact _enableIsolateSupport(MethodElement mainMethod) {
|
||||
WorldImpact _enableIsolateSupport(FunctionEntity mainMethod) {
|
||||
WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
|
||||
// TODO(floitsch): We should also ensure that the class IsolateMessage is
|
||||
// instantiated. Currently, just enabling isolate support works.
|
||||
|
@ -155,14 +156,16 @@ class ResolutionEnqueuerListener extends EnqueuerListener {
|
|||
}
|
||||
|
||||
/// Computes the [WorldImpact] of calling [mainMethod] as the entry point.
|
||||
WorldImpact _computeMainImpact(MethodElement mainMethod) {
|
||||
WorldImpact _computeMainImpact(FunctionEntity mainMethod) {
|
||||
WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl();
|
||||
if (mainMethod.parameters.isNotEmpty) {
|
||||
CallStructure callStructure =
|
||||
_elementEnvironment.getCallStructure(mainMethod);
|
||||
if (callStructure.argumentCount > 0) {
|
||||
_impacts.mainWithArguments
|
||||
.registerImpact(mainImpact, _elementEnvironment);
|
||||
_backendUsage.processBackendImpact(_impacts.mainWithArguments);
|
||||
mainImpact.registerStaticUse(
|
||||
new StaticUse.staticInvoke(mainMethod, CallStructure.TWO_ARGS));
|
||||
new StaticUse.staticInvoke(mainMethod, callStructure));
|
||||
// If the main method takes arguments, this compilation could be the
|
||||
// target of Isolate.spawnUri. Strictly speaking, that can happen also if
|
||||
// main takes no arguments, but in this case the spawned isolate can't
|
||||
|
@ -258,10 +261,10 @@ class ResolutionEnqueuerListener extends EnqueuerListener {
|
|||
} else if (constant.isInterceptor) {
|
||||
// An interceptor constant references the class's prototype chain.
|
||||
InterceptorConstantValue interceptor = constant;
|
||||
ClassElement cls = interceptor.cls;
|
||||
_computeImpactForInstantiatedConstantType(cls.thisType, impactBuilder);
|
||||
InterfaceType type = _elementEnvironment.getThisType(interceptor.cls);
|
||||
_computeImpactForInstantiatedConstantType(type, impactBuilder);
|
||||
} else if (constant.isType) {
|
||||
MethodElement helper = _helpers.createRuntimeType;
|
||||
FunctionEntity helper = _helpers.createRuntimeType;
|
||||
impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
|
||||
// TODO(johnniwinther): Find the right [CallStructure].
|
||||
helper,
|
||||
|
@ -296,21 +299,23 @@ class ResolutionEnqueuerListener extends EnqueuerListener {
|
|||
}
|
||||
|
||||
@override
|
||||
WorldImpact registerUsedElement(MemberElement member) {
|
||||
WorldImpact registerUsedElement(MemberEntity member) {
|
||||
WorldImpactBuilderImpl worldImpact = new WorldImpactBuilderImpl();
|
||||
_mirrorsDataBuilder.registerUsedMember(member);
|
||||
_customElementsAnalysis.registerStaticUse(member);
|
||||
|
||||
if (member.isFunction && member.isInstanceMember) {
|
||||
MethodElement method = member;
|
||||
ClassElement cls = method.enclosingClass;
|
||||
if (method.name == Identifiers.call && !cls.typeVariables.isEmpty) {
|
||||
FunctionEntity method = member;
|
||||
ClassEntity cls = method.enclosingClass;
|
||||
|
||||
if (method.name == Identifiers.call &&
|
||||
_elementEnvironment.getThisType(cls).typeArguments.isNotEmpty) {
|
||||
worldImpact.addImpact(_registerComputeSignature());
|
||||
}
|
||||
}
|
||||
_backendUsage.registerUsedMember(member);
|
||||
|
||||
if (member.isDeferredLoaderGetter) {
|
||||
if (_elementEnvironment.isDeferredLoadLibraryGetter(member)) {
|
||||
// TODO(sigurdm): Create a function registerLoadLibraryAccess.
|
||||
if (!_isLoadLibraryFunctionResolved) {
|
||||
_isLoadLibraryFunctionResolved = true;
|
||||
|
@ -322,7 +327,7 @@ class ResolutionEnqueuerListener extends EnqueuerListener {
|
|||
// library, or timers for the async library. We exclude constant fields,
|
||||
// which are ending here because their initializing expression is
|
||||
// compiled.
|
||||
LibraryElement library = member.library;
|
||||
LibraryEntity library = member.library;
|
||||
if (!_backendUsage.isIsolateInUse && !(member.isField && member.isConst)) {
|
||||
Uri uri = library.canonicalUri;
|
||||
if (uri == Uris.dart_isolate) {
|
||||
|
@ -361,9 +366,9 @@ class ResolutionEnqueuerListener extends EnqueuerListener {
|
|||
return _impacts.runtimeTypeSupport.createImpact(_elementEnvironment);
|
||||
}
|
||||
|
||||
WorldImpact _processClass(ClassElement cls) {
|
||||
WorldImpact _processClass(ClassEntity cls) {
|
||||
WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
|
||||
if (!cls.typeVariables.isEmpty) {
|
||||
if (_elementEnvironment.getThisType(cls).typeArguments.isNotEmpty) {
|
||||
_typeVariableResolutionAnalysis.registerClassWithTypeVariables(cls);
|
||||
}
|
||||
// TODO(johnniwinther): Extract an `implementationClassesOf(...)` function
|
||||
|
|
|
@ -11,8 +11,9 @@ class KLibrary implements LibraryEntity {
|
|||
/// Library index used for fast lookup in [KernelWorldBuilder].
|
||||
final int libraryIndex;
|
||||
final String name;
|
||||
final Uri canonicalUri;
|
||||
|
||||
KLibrary(this.libraryIndex, this.name);
|
||||
KLibrary(this.libraryIndex, this.name, this.canonicalUri);
|
||||
|
||||
String toString() => 'library($name)';
|
||||
}
|
||||
|
@ -33,12 +34,15 @@ class KClass implements ClassEntity {
|
|||
}
|
||||
|
||||
abstract class KMember implements MemberEntity {
|
||||
/// Member index used for fast lookup in [KernelWorldBuilder].
|
||||
final int memberIndex;
|
||||
final KLibrary library;
|
||||
final KClass enclosingClass;
|
||||
final Name _name;
|
||||
final bool _isStatic;
|
||||
|
||||
KMember(this.library, this.enclosingClass, this._name, {bool isStatic: false})
|
||||
KMember(this.memberIndex, this.library, this.enclosingClass, this._name,
|
||||
{bool isStatic: false})
|
||||
: _isStatic = isStatic;
|
||||
|
||||
String get name => _name.text;
|
||||
|
@ -46,6 +50,9 @@ abstract class KMember implements MemberEntity {
|
|||
@override
|
||||
bool get isAssignable => false;
|
||||
|
||||
@override
|
||||
bool get isConst => false;
|
||||
|
||||
@override
|
||||
bool get isSetter => false;
|
||||
|
||||
|
@ -79,18 +86,17 @@ abstract class KMember implements MemberEntity {
|
|||
abstract class KFunction extends KMember implements FunctionEntity {
|
||||
final bool isExternal;
|
||||
|
||||
KFunction(KLibrary library, KClass enclosingClass, Name name,
|
||||
KFunction(int memberIndex, KLibrary library, KClass enclosingClass, Name name,
|
||||
{bool isStatic: false, this.isExternal: false})
|
||||
: super(library, enclosingClass, name, isStatic: isStatic);
|
||||
: super(memberIndex, library, enclosingClass, name, isStatic: isStatic);
|
||||
}
|
||||
|
||||
abstract class KConstructor extends KFunction implements ConstructorEntity {
|
||||
/// Constructor index used for fast lookup in [KernelWorldBuilder].
|
||||
final int constructorIndex;
|
||||
final bool isConst;
|
||||
|
||||
KConstructor(this.constructorIndex, KClass enclosingClass, Name name,
|
||||
{bool isExternal})
|
||||
: super(enclosingClass.library, enclosingClass, name,
|
||||
KConstructor(int memberIndex, KClass enclosingClass, Name name,
|
||||
{bool isExternal, this.isConst})
|
||||
: super(memberIndex, enclosingClass.library, enclosingClass, name,
|
||||
isExternal: isExternal);
|
||||
|
||||
@override
|
||||
|
@ -110,8 +116,9 @@ abstract class KConstructor extends KFunction implements ConstructorEntity {
|
|||
|
||||
class KGenerativeConstructor extends KConstructor {
|
||||
KGenerativeConstructor(int constructorIndex, KClass enclosingClass, Name name,
|
||||
{bool isExternal})
|
||||
: super(constructorIndex, enclosingClass, name, isExternal: isExternal);
|
||||
{bool isExternal, bool isConst})
|
||||
: super(constructorIndex, enclosingClass, name,
|
||||
isExternal: isExternal, isConst: isConst);
|
||||
|
||||
@override
|
||||
bool get isFactoryConstructor => false;
|
||||
|
@ -121,9 +128,10 @@ class KGenerativeConstructor extends KConstructor {
|
|||
}
|
||||
|
||||
class KFactoryConstructor extends KConstructor {
|
||||
KFactoryConstructor(int constructorIndex, KClass enclosingClass, Name name,
|
||||
{bool isExternal})
|
||||
: super(constructorIndex, enclosingClass, name, isExternal: isExternal);
|
||||
KFactoryConstructor(int memberIndex, KClass enclosingClass, Name name,
|
||||
{bool isExternal, bool isConst})
|
||||
: super(memberIndex, enclosingClass, name,
|
||||
isExternal: isExternal, isConst: isConst);
|
||||
|
||||
@override
|
||||
bool get isFactoryConstructor => true;
|
||||
|
@ -133,9 +141,9 @@ class KFactoryConstructor extends KConstructor {
|
|||
}
|
||||
|
||||
class KMethod extends KFunction {
|
||||
KMethod(KLibrary library, KClass enclosingClass, Name name,
|
||||
KMethod(int memberIndex, KLibrary library, KClass enclosingClass, Name name,
|
||||
{bool isStatic, bool isExternal})
|
||||
: super(library, enclosingClass, name,
|
||||
: super(memberIndex, library, enclosingClass, name,
|
||||
isStatic: isStatic, isExternal: isExternal);
|
||||
|
||||
@override
|
||||
|
@ -145,9 +153,9 @@ class KMethod extends KFunction {
|
|||
}
|
||||
|
||||
class KGetter extends KFunction {
|
||||
KGetter(KLibrary library, KClass enclosingClass, Name name,
|
||||
KGetter(int memberIndex, KLibrary library, KClass enclosingClass, Name name,
|
||||
{bool isStatic, bool isExternal})
|
||||
: super(library, enclosingClass, name,
|
||||
: super(memberIndex, library, enclosingClass, name,
|
||||
isStatic: isStatic, isExternal: isExternal);
|
||||
|
||||
@override
|
||||
|
@ -157,9 +165,9 @@ class KGetter extends KFunction {
|
|||
}
|
||||
|
||||
class KSetter extends KFunction {
|
||||
KSetter(KLibrary library, KClass enclosingClass, Name name,
|
||||
KSetter(int memberIndex, KLibrary library, KClass enclosingClass, Name name,
|
||||
{bool isStatic, bool isExternal})
|
||||
: super(library, enclosingClass, name,
|
||||
: super(memberIndex, library, enclosingClass, name,
|
||||
isStatic: isStatic, isExternal: isExternal);
|
||||
|
||||
@override
|
||||
|
@ -172,13 +180,12 @@ class KSetter extends KFunction {
|
|||
}
|
||||
|
||||
class KField extends KMember implements FieldEntity {
|
||||
/// Field index used for fast lookup in [KernelWorldBuilder].
|
||||
final int fieldIndex;
|
||||
final bool isAssignable;
|
||||
final bool isConst;
|
||||
|
||||
KField(this.fieldIndex, KLibrary library, KClass enclosingClass, Name name,
|
||||
{bool isStatic, this.isAssignable})
|
||||
: super(library, enclosingClass, name, isStatic: isStatic);
|
||||
KField(int memberIndex, KLibrary library, KClass enclosingClass, Name name,
|
||||
{bool isStatic, this.isAssignable, this.isConst})
|
||||
: super(memberIndex, library, enclosingClass, name, isStatic: isStatic);
|
||||
|
||||
@override
|
||||
bool get isField => true;
|
||||
|
|
|
@ -23,6 +23,7 @@ import '../js_backend/constant_system_javascript.dart';
|
|||
import '../js_backend/no_such_method_registry.dart';
|
||||
import '../native/native.dart' as native;
|
||||
import '../native/resolver.dart';
|
||||
import '../universe/call_structure.dart';
|
||||
import 'element_adapter.dart';
|
||||
import 'elements.dart';
|
||||
|
||||
|
@ -55,19 +56,17 @@ class KernelWorldBuilder extends KernelElementAdapterMixin {
|
|||
Map<ir.TypeParameter, KTypeVariable> _typeVariableMap =
|
||||
<ir.TypeParameter, KTypeVariable>{};
|
||||
|
||||
// TODO(johnniwinther): Change this to a list of 'KMemberData' class if we
|
||||
// need more data for members.
|
||||
List<ir.Member> _memberList = <ir.Member>[];
|
||||
|
||||
Map<ir.Member, KConstructor> _constructorMap = <ir.Member, KConstructor>{};
|
||||
// TODO(johnniwinther): Change this to a list of 'KConstructorData' class
|
||||
// holding the [ConstantConstructor] if we need more data for constructors.
|
||||
List<ir.Member> _constructorList = <ir.Member>[];
|
||||
Map<KConstructor, ConstantConstructor> _constructorConstantMap =
|
||||
<KConstructor, ConstantConstructor>{};
|
||||
|
||||
Map<ir.Procedure, KFunction> _methodMap = <ir.Procedure, KFunction>{};
|
||||
|
||||
Map<ir.Field, KField> _fieldMap = <ir.Field, KField>{};
|
||||
// TODO(johnniwinther): Change this to a list of 'KFieldData' class
|
||||
// holding the [ConstantExpression] if we need more data for fields.
|
||||
List<ir.Field> _fieldList = <ir.Field>[];
|
||||
Map<KField, ConstantExpression> _fieldConstantMap =
|
||||
<KField, ConstantExpression>{};
|
||||
|
||||
|
@ -112,14 +111,15 @@ class KernelWorldBuilder extends KernelElementAdapterMixin {
|
|||
|
||||
KLibrary _getLibrary(ir.Library node, [KLibraryEnv libraryEnv]) {
|
||||
return _libraryMap.putIfAbsent(node, () {
|
||||
_libraryEnvs.add(libraryEnv ?? _env.lookupLibrary(node.importUri));
|
||||
Uri canonicalUri = node.importUri;
|
||||
_libraryEnvs.add(libraryEnv ?? _env.lookupLibrary(canonicalUri));
|
||||
String name = node.name;
|
||||
if (name == null) {
|
||||
// Use the file name as script name.
|
||||
String path = node.importUri.path;
|
||||
String path = canonicalUri.path;
|
||||
name = path.substring(path.lastIndexOf('/') + 1);
|
||||
}
|
||||
return new KLibrary(_libraryMap.length, name);
|
||||
return new KLibrary(_libraryMap.length, name, canonicalUri);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -194,27 +194,31 @@ class KernelWorldBuilder extends KernelElementAdapterMixin {
|
|||
|
||||
KConstructor _getConstructor(ir.Member node) {
|
||||
return _constructorMap.putIfAbsent(node, () {
|
||||
int constructorIndex = _constructorList.length;
|
||||
int memberIndex = _memberList.length;
|
||||
KConstructor constructor;
|
||||
KClass enclosingClass = _getClass(node.enclosingClass);
|
||||
Name name = getName(node.name);
|
||||
bool isExternal = node.isExternal;
|
||||
if (node is ir.Constructor) {
|
||||
constructor = new KGenerativeConstructor(
|
||||
constructorIndex, enclosingClass, name,
|
||||
isExternal: isExternal);
|
||||
memberIndex, enclosingClass, name,
|
||||
isExternal: isExternal, isConst: node.isConst);
|
||||
} else if (node is ir.Procedure) {
|
||||
constructor = new KFactoryConstructor(memberIndex, enclosingClass, name,
|
||||
isExternal: isExternal, isConst: node.isConst);
|
||||
} else {
|
||||
constructor = new KFactoryConstructor(
|
||||
constructorIndex, enclosingClass, name,
|
||||
isExternal: isExternal);
|
||||
// TODO(johnniwinther): Convert `node.location` to a [SourceSpan].
|
||||
throw new SpannableAssertionFailure(
|
||||
NO_LOCATION_SPANNABLE, "Unexpected constructor node: ${node}.");
|
||||
}
|
||||
_constructorList.add(node);
|
||||
_memberList.add(node);
|
||||
return constructor;
|
||||
});
|
||||
}
|
||||
|
||||
KFunction _getMethod(ir.Procedure node) {
|
||||
return _methodMap.putIfAbsent(node, () {
|
||||
int memberIndex = _memberList.length;
|
||||
KLibrary library;
|
||||
KClass enclosingClass;
|
||||
if (node.enclosingClass != null) {
|
||||
|
@ -226,26 +230,33 @@ class KernelWorldBuilder extends KernelElementAdapterMixin {
|
|||
Name name = getName(node.name);
|
||||
bool isStatic = node.isStatic;
|
||||
bool isExternal = node.isExternal;
|
||||
KFunction function;
|
||||
switch (node.kind) {
|
||||
case ir.ProcedureKind.Factory:
|
||||
throw new UnsupportedError("Cannot create method from factory.");
|
||||
case ir.ProcedureKind.Getter:
|
||||
return new KGetter(library, enclosingClass, name,
|
||||
function = new KGetter(memberIndex, library, enclosingClass, name,
|
||||
isStatic: isStatic, isExternal: isExternal);
|
||||
break;
|
||||
case ir.ProcedureKind.Method:
|
||||
case ir.ProcedureKind.Operator:
|
||||
return new KMethod(library, enclosingClass, name,
|
||||
function = new KMethod(memberIndex, library, enclosingClass, name,
|
||||
isStatic: isStatic, isExternal: isExternal);
|
||||
break;
|
||||
case ir.ProcedureKind.Setter:
|
||||
return new KSetter(library, enclosingClass, getName(node.name).setter,
|
||||
function = new KSetter(
|
||||
memberIndex, library, enclosingClass, getName(node.name).setter,
|
||||
isStatic: isStatic, isExternal: isExternal);
|
||||
break;
|
||||
}
|
||||
_memberList.add(node);
|
||||
return function;
|
||||
});
|
||||
}
|
||||
|
||||
KField _getField(ir.Field node) {
|
||||
return _fieldMap.putIfAbsent(node, () {
|
||||
int fieldIndex = _fieldList.length;
|
||||
int memberIndex = _memberList.length;
|
||||
KLibrary library;
|
||||
KClass enclosingClass;
|
||||
if (node.enclosingClass != null) {
|
||||
|
@ -256,9 +267,11 @@ class KernelWorldBuilder extends KernelElementAdapterMixin {
|
|||
}
|
||||
Name name = getName(node.name);
|
||||
bool isStatic = node.isStatic;
|
||||
_fieldList.add(node);
|
||||
return new KField(fieldIndex, library, enclosingClass, name,
|
||||
isStatic: isStatic, isAssignable: node.isMutable);
|
||||
_memberList.add(node);
|
||||
return new KField(memberIndex, library, enclosingClass, name,
|
||||
isStatic: isStatic,
|
||||
isAssignable: node.isMutable,
|
||||
isConst: node.isConst);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -400,7 +413,7 @@ class KernelWorldBuilder extends KernelElementAdapterMixin {
|
|||
|
||||
ConstantConstructor _getConstructorConstant(KConstructor constructor) {
|
||||
return _constructorConstantMap.putIfAbsent(constructor, () {
|
||||
ir.Member node = _constructorList[constructor.constructorIndex];
|
||||
ir.Member node = _memberList[constructor.memberIndex];
|
||||
if (node is ir.Constructor && node.isConst) {
|
||||
return new Constantifier(this).computeConstantConstructor(node);
|
||||
}
|
||||
|
@ -413,7 +426,7 @@ class KernelWorldBuilder extends KernelElementAdapterMixin {
|
|||
|
||||
ConstantExpression _getFieldConstant(KField field) {
|
||||
return _fieldConstantMap.putIfAbsent(field, () {
|
||||
ir.Field node = _fieldList[field.fieldIndex];
|
||||
ir.Field node = _memberList[field.memberIndex];
|
||||
if (node.isConst) {
|
||||
return new Constantifier(this).visit(node.initializer);
|
||||
}
|
||||
|
@ -555,6 +568,11 @@ class KernelElementEnvironment implements ElementEnvironment {
|
|||
throw new UnimplementedError('KernelElementEnvironment.isSubtype');
|
||||
}
|
||||
|
||||
@override
|
||||
FunctionType getFunctionType(KFunction function) {
|
||||
throw new UnimplementedError('KernelElementEnvironment.getFunctionType');
|
||||
}
|
||||
|
||||
@override
|
||||
ConstructorEntity lookupConstructor(ClassEntity cls, String name,
|
||||
{bool required: false}) {
|
||||
|
@ -627,6 +645,30 @@ class KernelElementEnvironment implements ElementEnvironment {
|
|||
}
|
||||
return library;
|
||||
}
|
||||
|
||||
@override
|
||||
CallStructure getCallStructure(KFunction function) {
|
||||
ir.Member member = worldBuilder._memberList[function.memberIndex];
|
||||
ir.FunctionNode functionNode;
|
||||
if (member is ir.Procedure) {
|
||||
functionNode = member.function;
|
||||
} else if (member is ir.Constructor) {
|
||||
functionNode = member.function;
|
||||
} else {
|
||||
throw new SpannableAssertionFailure(
|
||||
function, "Unexpected function node ${member} for $function.");
|
||||
}
|
||||
return new CallStructure(
|
||||
functionNode.positionalParameters.length +
|
||||
functionNode.namedParameters.length,
|
||||
functionNode.namedParameters.map((d) => d.name).toList());
|
||||
}
|
||||
|
||||
@override
|
||||
bool isDeferredLoadLibraryGetter(KMember member) {
|
||||
// TODO(johnniwinther): Support these.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Visitor that converts kernel dart types into [DartType].
|
||||
|
|
Loading…
Reference in a new issue