| Index: pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
|
| 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 9871ca59dd2a96b5eb10cfa3f27cad8dca902f24..f5cb90a481760829614dc988cde932bbe2f1c908 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
|
| @@ -17,6 +17,7 @@ import '../../deferred_load.dart' show DeferredLoadTask, OutputUnit;
|
| import '../../elements/elements.dart'
|
| show
|
| ClassElement,
|
| + ConstructorBodyElement,
|
| Element,
|
| Elements,
|
| FieldElement,
|
| @@ -517,8 +518,10 @@ class ProgramBuilder {
|
| var stubNames = new Set<String>();
|
| librariesMap
|
| .forEach((LibraryEntity library, List<ClassEntity> classElements, _) {
|
| - for (ClassElement e in classElements) {
|
| - if (_nativeData.isJsInteropClass(e)) {
|
| + for (ClassEntity cls in classElements) {
|
| + if (_nativeData.isJsInteropClass(cls)) {
|
| + // TODO(johnniwinther): Handle class entities.
|
| + ClassElement e = cls;
|
| e.declaration.forEachMember((_, Element member) {
|
| var jsName = _nativeData.computeUnescapedJSInteropName(member.name);
|
| if (!member.isInstanceMember) return;
|
| @@ -663,19 +666,19 @@ class ProgramBuilder {
|
| library, uri, statics, classes, staticFieldsForReflection);
|
| }
|
|
|
| - bool _isSoftDeferred(ClassElement element) {
|
| + bool _isSoftDeferred(ClassEntity element) {
|
| return _notSoftDeferred != null && !_notSoftDeferred.contains(element);
|
| }
|
|
|
| - Class _buildClass(ClassElement element) {
|
| - bool onlyForRti = collector.classesOnlyNeededForRti.contains(element);
|
| - bool hasRtiField = _rtiNeed.classNeedsRtiField(element);
|
| - if (_nativeData.isJsInteropClass(element)) {
|
| + Class _buildClass(ClassEntity cls) {
|
| + bool onlyForRti = collector.classesOnlyNeededForRti.contains(cls);
|
| + bool hasRtiField = _rtiNeed.classNeedsRtiField(cls);
|
| + if (_nativeData.isJsInteropClass(cls)) {
|
| // TODO(jacobr): check whether the class has any active static fields
|
| // if it does not we can suppress it completely.
|
| onlyForRti = true;
|
| }
|
| - bool isClosureBaseClass = element == _commonElements.closureClass;
|
| + bool isClosureBaseClass = cls == _commonElements.closureClass;
|
|
|
| List<Method> methods = [];
|
| List<StubMethod> callStubs = <StubMethod>[];
|
| @@ -695,11 +698,10 @@ class ProgramBuilder {
|
| _rtiSubstitutions,
|
| _jsInteropAnalysis);
|
|
|
| - void visitMember(ClassElement enclosing, MemberElement member) {
|
| - assert(member.isDeclaration, failedAt(element));
|
| - assert(element == enclosing, failedAt(element));
|
| + void visitMember(ClassEntity declarer, MemberEntity member) {
|
| + if (cls != declarer) return;
|
|
|
| - if (Elements.isNonAbstractInstanceMember(member)) {
|
| + if (member.isInstanceMember && !member.isAbstract && !member.isField) {
|
| // TODO(herhut): Remove once _buildMethod can no longer return null.
|
| Method method = _buildMethod(member);
|
| if (method != null) methods.add(method);
|
| @@ -719,7 +721,8 @@ class ProgramBuilder {
|
|
|
| List<StubMethod> noSuchMethodStubs = <StubMethod>[];
|
|
|
| - if (_backendUsage.isNoSuchMethodUsed && element.isObject) {
|
| + if (_backendUsage.isNoSuchMethodUsed &&
|
| + cls == _commonElements.objectClass) {
|
| Map<js.Name, Selector> selectors =
|
| classStubGenerator.computeSelectorsForNsmHandlers();
|
| selectors.forEach((js.Name name, Selector selector) {
|
| @@ -741,33 +744,36 @@ class ProgramBuilder {
|
| callStubs.add(_buildStubMethod(name, function));
|
| }
|
|
|
| - ClassElement implementation = element.implementation;
|
| -
|
| // MixinApplications run through the members of their mixin. Here, we are
|
| // only interested in direct members.
|
| - if (!onlyForRti && !element.isMixinApplication) {
|
| - implementation.forEachMember(visitMember, includeBackendMembers: true);
|
| + if (!onlyForRti && !_elementEnvironment.isUnnamedMixinApplication(cls)) {
|
| + _elementEnvironment.forEachClassMember(cls, visitMember);
|
| + if (cls is ClassElement) {
|
| + // TODO(johnniwinther): Support constructor bodies for entities.
|
| + cls.forEachConstructorBody((ConstructorBodyElement constructorBody) =>
|
| + visitMember(cls, constructorBody));
|
| + }
|
| }
|
| - bool isInterceptedClass = _interceptorData.isInterceptedClass(element);
|
| + bool isInterceptedClass = _interceptorData.isInterceptedClass(cls);
|
| List<Field> instanceFields = onlyForRti
|
| ? const <Field>[]
|
| : _buildFields(
|
| - cls: element,
|
| + cls: cls,
|
| visitStatics: false,
|
| isHolderInterceptedClass: isInterceptedClass);
|
| List<Field> staticFieldsForReflection = onlyForRti
|
| ? const <Field>[]
|
| : _buildFields(
|
| - cls: element,
|
| + cls: cls,
|
| visitStatics: true,
|
| isHolderInterceptedClass: isInterceptedClass);
|
|
|
| - TypeTestProperties typeTests = runtimeTypeGenerator.generateIsTests(element,
|
| + TypeTestProperties typeTests = runtimeTypeGenerator.generateIsTests(cls,
|
| storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata);
|
|
|
| List<StubMethod> checkedSetters = <StubMethod>[];
|
| List<StubMethod> isChecks = <StubMethod>[];
|
| - if (_nativeData.isJsInteropClass(element)) {
|
| + if (_nativeData.isJsInteropClass(cls)) {
|
| typeTests.properties.forEach((js.Name name, js.Node code) {
|
| _classes[_commonElements.jsInterceptorClass]
|
| .isChecks
|
| @@ -790,22 +796,22 @@ class ProgramBuilder {
|
| });
|
| }
|
|
|
| - js.Name name = _namer.className(element);
|
| - String holderName = _namer.globalObjectForClass(element);
|
| + js.Name name = _namer.className(cls);
|
| + String holderName = _namer.globalObjectForClass(cls);
|
| // TODO(floitsch): we shouldn't update the registry in the middle of
|
| // building a class.
|
| Holder holder = _registry.registerHolder(holderName);
|
| - bool isInstantiated = !_nativeData.isJsInteropClass(element) &&
|
| - _worldBuilder.directlyInstantiatedClasses.contains(element);
|
| + bool isInstantiated = !_nativeData.isJsInteropClass(cls) &&
|
| + _worldBuilder.directlyInstantiatedClasses.contains(cls);
|
|
|
| Class result;
|
| - if (element.isMixinApplication && !onlyForRti) {
|
| - assert(!_nativeData.isNativeClass(element));
|
| + if (_elementEnvironment.isUnnamedMixinApplication(cls) && !onlyForRti) {
|
| + assert(!_nativeData.isNativeClass(cls));
|
| assert(methods.isEmpty);
|
| assert(!isClosureBaseClass);
|
|
|
| result = new MixinApplication(
|
| - element,
|
| + cls,
|
| name,
|
| holder,
|
| instanceFields,
|
| @@ -819,7 +825,7 @@ class ProgramBuilder {
|
| onlyForRti: onlyForRti);
|
| } else {
|
| result = new Class(
|
| - element,
|
| + cls,
|
| name,
|
| holder,
|
| methods,
|
| @@ -833,11 +839,11 @@ class ProgramBuilder {
|
| isDirectlyInstantiated: isInstantiated,
|
| hasRtiField: hasRtiField,
|
| onlyForRti: onlyForRti,
|
| - isNative: _nativeData.isNativeClass(element),
|
| + isNative: _nativeData.isNativeClass(cls),
|
| isClosureBaseClass: isClosureBaseClass,
|
| - isSoftDeferred: _isSoftDeferred(element));
|
| + isSoftDeferred: _isSoftDeferred(cls));
|
| }
|
| - _classes[element] = result;
|
| + _classes[cls] = result;
|
| return result;
|
| }
|
|
|
| @@ -874,8 +880,8 @@ class ProgramBuilder {
|
| return optionalParameterDefaultValues;
|
| }
|
|
|
| - DartMethod _buildMethod(MethodElement element) {
|
| - assert(element.isDeclaration);
|
| + DartMethod _buildMethod(FunctionEntity element) {
|
| + assert(!(element is MethodElement && !element.isDeclaration));
|
| js.Name name = _namer.methodPropertyName(element);
|
| js.Expression code = _generatedCode[element];
|
|
|
| @@ -885,7 +891,8 @@ class ProgramBuilder {
|
| bool canTearOff = false;
|
| js.Name tearOffName;
|
| bool isClosureCallMethod = false;
|
| - bool isNotApplyTarget = !element.isFunction || element.isAccessor;
|
| + bool isNotApplyTarget =
|
| + !element.isFunction || element.isGetter || element.isSetter;
|
|
|
| bool canBeReflected = _methodCanBeReflected(element);
|
| bool canBeApplied = _methodCanBeApplied(element);
|
| @@ -903,7 +910,7 @@ class ProgramBuilder {
|
| } else {
|
| // Careful with operators.
|
| canTearOff = _worldBuilder.hasInvokedGetter(element, _closedWorld) ||
|
| - (canBeReflected && !element.isOperator);
|
| + (canBeReflected && !Selector.isOperatorName(element.name));
|
| assert(canTearOff ||
|
| !_worldBuilder.methodsNeedingSuperGetter.contains(element));
|
| tearOffName = _namer.getterForElement(element);
|
| @@ -911,9 +918,8 @@ class ProgramBuilder {
|
| }
|
|
|
| if (canTearOff) {
|
| - assert(!element.isGenerativeConstructor, failedAt(element));
|
| - assert(!element.isGenerativeConstructorBody, failedAt(element));
|
| - assert(!element.isConstructor, failedAt(element));
|
| + assert(element is! ConstructorEntity, failedAt(element));
|
| + assert(element is! ConstructorBodyElement, failedAt(element));
|
| }
|
|
|
| js.Name callName = null;
|
| @@ -923,27 +929,19 @@ class ProgramBuilder {
|
| callName = _namer.invocationName(callSelector);
|
| }
|
|
|
| - ResolutionDartType memberType;
|
| - if (element.isGenerativeConstructorBody) {
|
| - // TODO(herhut): Why does this need to be normalized away? We never need
|
| - // this information anyway as they cannot be torn off or
|
| - // reflected.
|
| - var body = element;
|
| - memberType = body.constructor.type;
|
| - } else {
|
| - memberType = element.type;
|
| - }
|
| -
|
| + DartType memberType = _elementEnvironment.getFunctionType(element);
|
| js.Expression functionType;
|
| if (canTearOff || canBeReflected) {
|
| - OutputUnit outputUnit = _deferredLoadTask.outputUnitForElement(element);
|
| + OutputUnit outputUnit = _deferredLoadTask.outputUnitForMember(element);
|
| functionType = _generateFunctionType(memberType, outputUnit);
|
| }
|
|
|
| int requiredParameterCount;
|
| var /* List | Map */ optionalParameterDefaultValues;
|
| if (canBeApplied || canBeReflected) {
|
| - FunctionSignature signature = element.functionSignature;
|
| + // TODO(johnniwinther): Handle function entities.
|
| + MethodElement method = element;
|
| + FunctionSignature signature = method.functionSignature;
|
| requiredParameterCount = signature.requiredParameterCount;
|
| optionalParameterDefaultValues =
|
| _computeParameterDefaultValues(signature);
|
|
|