diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart index 0c7edc97a9f6..86d62ea491d0 100644 --- a/pkg/compiler/lib/src/common_elements.dart +++ b/pkg/compiler/lib/src/common_elements.dart @@ -1329,9 +1329,12 @@ abstract class ElementEnvironment { /// `Object`. DartType getTypeVariableBound(TypeVariableEntity typeVariable); - /// Returns the type if [function]. + /// Returns the type of [function]. FunctionType getFunctionType(FunctionEntity function); + /// Returns the type of [field]. + DartType getFieldType(FieldEntity field); + /// Returns the type of the [local] function. FunctionType getLocalFunctionType(Local local); diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart index ee71c76bc0a5..245d50be5fb4 100644 --- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart +++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart @@ -48,7 +48,7 @@ class Collector { /// This flag is updated in [computeNeededConstants]. bool outputContainsConstantList = false; - final List nativeClassesAndSubclasses = []; + final List nativeClassesAndSubclasses = []; List typedefsNeededForReflection; @@ -88,7 +88,7 @@ class Collector { */ Function computeClassFilter() { if (_mirrorsData.isTreeShakingDisabled) { - return (ClassElement cls) => true; + return (ClassEntity cls) => true; } Set unneededClasses = new Set(); @@ -136,17 +136,24 @@ class Collector { if (_mirrorsData.mustRetainMetadata) { // TODO(floitsch): verify that we don't run through the same elements // multiple times. - for (MemberElement element in _generatedCode.keys) { + for (MemberEntity element in _generatedCode.keys) { if (_mirrorsData.isMemberAccessibleByReflection(element)) { _mirrorsData.retainMetadataOfMember(element); } } - for (ClassElement cls in neededClasses) { + for (ClassEntity cls in neededClasses) { final onlyForRti = classesOnlyNeededForRti.contains(cls); if (!onlyForRti) { _mirrorsData.retainMetadataOfClass(cls); - new FieldVisitor(_options, _elementEnvironment, _worldBuilder, - _nativeData, _mirrorsData, _namer, _closedWorld) + new FieldVisitor( + _options, + _elementEnvironment, + _commonElements, + _worldBuilder, + _nativeData, + _mirrorsData, + _namer, + _closedWorld) .visitFields((FieldEntity member, js.Name name, js.Name accessorName, diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart index f85f1a38c801..39c0107c529f 100644 --- a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart +++ b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart @@ -28,6 +28,7 @@ typedef void AcceptField(FieldEntity member, js.Name name, js.Name accessorName, class FieldVisitor { final CompilerOptions _options; final ElementEnvironment _elementEnvironment; + final CommonElements _commonElements; final CodegenWorldBuilder _codegenWorldBuilder; final NativeData _nativeData; final MirrorsData _mirrorsData; @@ -37,6 +38,7 @@ class FieldVisitor { FieldVisitor( this._options, this._elementEnvironment, + this._commonElements, this._codegenWorldBuilder, this._nativeData, this._mirrorsData, @@ -46,13 +48,13 @@ class FieldVisitor { /** * Invokes [f] for each of the fields of [element]. * - * [element] must be a [ClassElement] or a [LibraryElement]. + * [element] must be a [ClassEntity] or a [LibraryEntity]. * - * If [element] is a [ClassElement], the static fields of the class are + * If [element] is a [ClassEntity], the static fields of the class are * visited if [visitStatics] is true and the instance fields are visited if * [visitStatics] is false. * - * If [element] is a [LibraryElement], [visitStatics] must be true. + * If [element] is a [LibraryEntity], [visitStatics] must be true. * * When visiting the instance fields of a class, the fields of its superclass * are also visited if the class is instantiated. @@ -79,8 +81,8 @@ class FieldVisitor { isLibrary = true; assert(visitStatics, failedAt(library)); } else { - failedAt(NO_LOCATION_SPANNABLE, - 'Expected a ClassElement or a LibraryElement.'); + failedAt( + NO_LOCATION_SPANNABLE, 'Expected a ClassEntity or a LibraryEntity.'); } void visitField(FieldEntity field, {ClassEntity holder}) { @@ -175,10 +177,10 @@ class FieldVisitor { field is ClosureFieldElement; } - bool canAvoidGeneratedCheckedSetter(FieldElement member) { + bool canAvoidGeneratedCheckedSetter(FieldEntity member) { // We never generate accessors for top-level/static fields. if (!member.isInstanceMember) return true; - ResolutionDartType type = member.type; - return type.treatAsDynamic || type.isObject; + DartType type = _elementEnvironment.getFieldType(member); + return type.treatAsDynamic || type == _commonElements.objectType; } } diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart index e50a7d7ee1ea..f0290b08eb0f 100644 --- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart +++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart @@ -15,16 +15,8 @@ import '../../constants/values.dart' import '../../common_elements.dart' show CommonElements, ElementEnvironment; import '../../deferred_load.dart' show DeferredLoadTask, OutputUnit; import '../../elements/elements.dart' - show - ClassElement, - FieldElement, - FunctionSignature, - LibraryElement, - MemberElement, - MethodElement, - ParameterElement; + show ClassElement, FieldElement, LibraryElement, MethodElement; import '../../elements/entities.dart'; -import '../../elements/resolution_types.dart' show ResolutionDartType; import '../../elements/types.dart'; import '../../js/js.dart' as js; import '../../js_backend/backend.dart' show SuperMemberData; @@ -192,7 +184,7 @@ class ProgramBuilder { /// /// Also contains classes that are not tracked by the profile run (like /// interceptors, ...). - Set _notSoftDeferred; + Set _notSoftDeferred; Program buildProgram({bool storeFunctionTypesInMetadata: false}) { collector.collect(); @@ -326,16 +318,17 @@ class ProgramBuilder { String data = new File(allocatedClassesPath).readAsStringSync(); Set allocatedClassesKeys = JSON.decode(data).keys.toSet(); - Set allocatedClasses = new Set(); + Set allocatedClasses = new Set(); // Collects all super and mixin classes of a class. - void collect(ClassElement element) { + void collect(ClassEntity element) { allocatedClasses.add(element); - if (element.isMixinApplication) { + if (_elementEnvironment.isMixinApplication(element)) { collect(_elementEnvironment.getEffectiveMixinClass(element)); } - if (element.superclass != null) { - collect(element.superclass); + ClassEntity superclass = _elementEnvironment.getSuperClass(element); + if (superclass != null) { + collect(superclass); } } @@ -343,7 +336,7 @@ class ProgramBuilder { // collect its dependencies (supers and mixins) and mark them as // not-soft-deferrable. collector.outputClassLists.forEach((_, List elements) { - for (ClassElement element in elements) { + for (ClassEntity element in elements) { // TODO(29574): share the encoding of the element with the code // that emits the profile-run. var key = "${element.library.canonicalUri}:${element.name}"; @@ -562,7 +555,7 @@ class ProgramBuilder { if (member.isFunction) { MethodElement fn = member; - functionType = fn.type; + functionType = _elementEnvironment.getFunctionType(fn); } else if (member.isGetter) { if (_options.trustTypeAnnotations) { DartType returnType = @@ -786,7 +779,7 @@ class ProgramBuilder { for (Field field in instanceFields) { if (field.needsCheckedSetter) { assert(!field.needsUncheckedSetter); - FieldElement element = field.element; + FieldEntity element = field.element; js.Expression code = _generatedCode[element]; assert(code != null); js.Name name = _namer.deriveSetterName(field.accessorName); @@ -863,23 +856,28 @@ class ProgramBuilder { _closedWorld.getMightBePassedToApply(method); } - /* Map | List */ _computeParameterDefaultValues(FunctionSignature signature) { + /* Map | List */ _computeParameterDefaultValues(FunctionEntity method) { var /* Map | List */ optionalParameterDefaultValues; - if (signature.optionalParametersAreNamed) { + ParameterStructure parameterStructure = method.parameterStructure; + if (parameterStructure.namedParameters.isNotEmpty) { optionalParameterDefaultValues = new Map(); - signature.forEachOptionalParameter((_parameter) { - ParameterElement parameter = _parameter; - ConstantValue def = - _constantHandler.getConstantValue(parameter.constant); - optionalParameterDefaultValues[parameter.name] = def; + _worldBuilder.forEachParameter(method, + (DartType type, String name, ConstantValue defaultValue) { + if (parameterStructure.namedParameters.contains(name)) { + assert(defaultValue != null); + optionalParameterDefaultValues[name] = defaultValue; + } }); } else { optionalParameterDefaultValues = []; - signature.forEachOptionalParameter((_parameter) { - ParameterElement parameter = _parameter; - ConstantValue def = - _constantHandler.getConstantValue(parameter.constant); - optionalParameterDefaultValues.add(def); + int index = 0; + _worldBuilder.forEachParameter(method, + (DartType type, String name, ConstantValue defaultValue) { + if (index >= parameterStructure.requiredParameters) { + assert(defaultValue != null); + optionalParameterDefaultValues.add(defaultValue); + } + index++; }); } return optionalParameterDefaultValues; @@ -945,11 +943,10 @@ class ProgramBuilder { var /* List | Map */ optionalParameterDefaultValues; if (canBeApplied || canBeReflected) { // TODO(redemption): Handle function entities. - MethodElement method = element; - FunctionSignature signature = method.functionSignature; - requiredParameterCount = signature.requiredParameterCount; - optionalParameterDefaultValues = - _computeParameterDefaultValues(signature); + FunctionEntity method = element; + ParameterStructure parameterStructure = method.parameterStructure; + requiredParameterCount = parameterStructure.requiredParameters; + optionalParameterDefaultValues = _computeParameterDefaultValues(method); } return new InstanceMethod(element, name, code, @@ -995,7 +992,7 @@ class ProgramBuilder { /// Stub methods may have an element that can be used for code-size /// attribution. Method _buildStubMethod(js.Name name, js.Expression code, - {MemberElement element}) { + {MemberEntity element}) { return new StubMethod(name, code, element: element); } @@ -1085,8 +1082,15 @@ class ProgramBuilder { needsCheckedSetter)); } - FieldVisitor visitor = new FieldVisitor(_options, _elementEnvironment, - _worldBuilder, _nativeData, _mirrorsData, _namer, _closedWorld); + FieldVisitor visitor = new FieldVisitor( + _options, + _elementEnvironment, + _commonElements, + _worldBuilder, + _nativeData, + _mirrorsData, + _namer, + _closedWorld); visitor.visitFields(visitField, visitStatics: visitStatics, library: library, cls: cls); @@ -1152,11 +1156,10 @@ class ProgramBuilder { var /* List | Map */ optionalParameterDefaultValues; if (canBeApplied || canBeReflected) { // TODO(redemption): Support entities; - MethodElement method = element; - FunctionSignature signature = method.functionSignature; - requiredParameterCount = signature.requiredParameterCount; - optionalParameterDefaultValues = - _computeParameterDefaultValues(signature); + FunctionEntity method = element; + ParameterStructure parameterStructure = method.parameterStructure; + requiredParameterCount = parameterStructure.requiredParameters; + optionalParameterDefaultValues = _computeParameterDefaultValues(method); } // TODO(floitsch): we shouldn't update the registry in the middle of diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/registry.dart b/pkg/compiler/lib/src/js_emitter/program_builder/registry.dart index b0266dc08693..b448c7ad804e 100644 --- a/pkg/compiler/lib/src/js_emitter/program_builder/registry.dart +++ b/pkg/compiler/lib/src/js_emitter/program_builder/registry.dart @@ -12,7 +12,7 @@ class LibraryContents { /// Maps [LibraryEntity]s to their [ClassEntity]s and [MemberEntity]s. /// /// Fundamentally, this class nicely encapsulates a -/// `Map, List>>`. +/// `Map, List>>`. /// /// There exists exactly one instance per [OutputUnit]. class LibrariesMap { diff --git a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart index 363164c0b613..20ec76ae9113 100644 --- a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart +++ b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart @@ -6,9 +6,7 @@ library dart2js.js_emitter.type_test_registry; import '../common.dart'; import '../common_elements.dart'; -import '../elements/elements.dart' show MethodElement; import '../elements/entities.dart'; -import '../elements/types.dart' show DartType; import '../elements/types.dart'; import '../js_backend/runtime_types.dart' show @@ -168,9 +166,8 @@ class TypeTestRegistry { liveMembers.where((MemberEntity element) { return canBeReflectedAsFunction(element) && canBeReified(element); }).forEach((_function) { - // TODO(redemption): Support entities. - MethodElement function = _function; - FunctionType type = function.type; + FunctionEntity function = _function; + FunctionType type = _elementEnvironment.getFunctionType(function); for (ClassEntity cls in _rtiChecks.getReferencedClasses(type)) { while (cls != null) { _rtiNeededClasses.add(cls); diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart index 153853ac9dc1..16cfea58c6bd 100644 --- a/pkg/compiler/lib/src/js_model/closure.dart +++ b/pkg/compiler/lib/src/js_model/closure.dart @@ -508,6 +508,12 @@ class ClosureFunctionData extends ClosureMemberData implements FunctionData { class ClosureFieldData extends ClosureMemberData implements FieldData { ClosureFieldData(MemberDefinition definition) : super(definition); + @override + DartType getFieldType(KernelToElementMap elementMap) { + // A closure field doesn't have a Dart type. + return null; + } + @override ConstantExpression getFieldConstant( KernelToElementMap elementMap, FieldEntity field) { diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart index 614fd9cce3e5..380853e75be6 100644 --- a/pkg/compiler/lib/src/kernel/element_map_impl.dart +++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart @@ -619,6 +619,12 @@ abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin { return data.getFunctionType(this); } + DartType _getFieldType(IndexedField field) { + assert(checkFamily(field)); + FieldData data = _memberData[field.memberIndex]; + return data.getFieldType(this); + } + ClassEntity _getAppliedMixin(IndexedClass cls) { assert(checkFamily(cls)); ClassData data = _classData[cls.classIndex]; @@ -1336,6 +1342,11 @@ class KernelElementEnvironment implements ElementEnvironment { return elementMap._getFunctionType(function); } + @override + DartType getFieldType(FieldEntity field) { + return elementMap._getFieldType(field); + } + @override FunctionType getLocalFunctionType(covariant KLocalFunction function) { return function.functionType; diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart index af566a0e9ab1..845feeec36a7 100644 --- a/pkg/compiler/lib/src/kernel/env.dart +++ b/pkg/compiler/lib/src/kernel/env.dart @@ -563,11 +563,14 @@ class ConstructorDataImpl extends FunctionDataImpl implements ConstructorData { } abstract class FieldData extends MemberData { + DartType getFieldType(KernelToElementMap elementMap); + ConstantExpression getFieldConstant( KernelToElementMapBase elementMap, FieldEntity field); } class FieldDataImpl extends MemberDataImpl implements FieldData { + DartType _type; ConstantExpression _constant; FieldDataImpl(ir.Field node, MemberDefinition definition) @@ -575,6 +578,10 @@ class FieldDataImpl extends MemberDataImpl implements FieldData { ir.Field get node => super.node; + DartType getFieldType(covariant KernelToElementMapBase elementMap) { + return _type ??= elementMap.getDartType(node.type); + } + ConstantExpression getFieldConstant( KernelToElementMapBase elementMap, FieldEntity field) { if (_constant == null) { diff --git a/pkg/compiler/lib/src/resolution/resolution_strategy.dart b/pkg/compiler/lib/src/resolution/resolution_strategy.dart index 62b23ea93cd4..ee21ec0397a2 100644 --- a/pkg/compiler/lib/src/resolution/resolution_strategy.dart +++ b/pkg/compiler/lib/src/resolution/resolution_strategy.dart @@ -667,6 +667,12 @@ class _CompilerElementEnvironment implements ElementEnvironment { return type; } + @override + DartType getFieldType(covariant FieldElement field) { + field.computeType(_resolution); + return field.type; + } + @override ResolutionFunctionType getLocalFunctionType( covariant LocalFunctionElement function) { diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart index 5b544b34be2f..bf6e754e4d98 100644 --- a/pkg/compiler/lib/src/ssa/optimize.dart +++ b/pkg/compiler/lib/src/ssa/optimize.dart @@ -9,8 +9,7 @@ import '../compiler.dart' show Compiler; import '../constants/constant_system.dart'; import '../constants/values.dart'; import '../common_elements.dart' show CommonElements; -import '../elements/elements.dart' - show ClassElement, FieldElement, MethodElement; +import '../elements/elements.dart' show ClassElement, MethodElement; import '../elements/entities.dart'; import '../elements/resolution_types.dart'; import '../elements/types.dart'; @@ -1031,8 +1030,7 @@ class SsaInstructionSimplifier extends HBaseVisitor HInstruction value = node.inputs.last; if (_options.enableTypeAssertions) { // TODO(redemption): Support field entities. - FieldElement element = field; - DartType type = element.type; + DartType type = _closedWorld.elementEnvironment.getFieldType(field); if (!type.treatAsRaw || type.isTypeVariable || type.unaliased.isFunctionType) {