| 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 7aef3a3cb2d2453b75a82d80ab0b89abe6d12db4..5d5afe69ade4becffae1e4663635be1076f7d1b7 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
|
| @@ -4,65 +4,49 @@
|
|
|
| library dart2js.js_emitter.program_builder;
|
|
|
| -import '../js_emitter.dart' show
|
| - ClassStubGenerator,
|
| - CodeEmitterTask,
|
| - computeMixinClass,
|
| - Emitter,
|
| - InterceptorStubGenerator,
|
| - MainCallStubGenerator,
|
| - ParameterStubGenerator,
|
| - RuntimeTypeGenerator,
|
| - TypeTestProperties;
|
| +import '../js_emitter.dart'
|
| + show
|
| + ClassStubGenerator,
|
| + CodeEmitterTask,
|
| + computeMixinClass,
|
| + Emitter,
|
| + InterceptorStubGenerator,
|
| + MainCallStubGenerator,
|
| + ParameterStubGenerator,
|
| + RuntimeTypeGenerator,
|
| + TypeTestProperties;
|
| import '../model.dart';
|
|
|
| -import '../../closure.dart' show
|
| - ClosureFieldElement;
|
| +import '../../closure.dart' show ClosureFieldElement;
|
| import '../../common.dart';
|
| -import '../../common/names.dart' show
|
| - Names,
|
| - Selectors;
|
| -import '../../compiler.dart' show
|
| - Compiler;
|
| -import '../../constants/values.dart' show
|
| - ConstantValue,
|
| - InterceptorConstantValue;
|
| -import '../../core_types.dart' show
|
| - CoreClasses;
|
| -import '../../dart_types.dart' show
|
| - DartType,
|
| - FunctionType,
|
| - TypedefType;
|
| -import '../../elements/elements.dart' show
|
| - ClassElement,
|
| - Element,
|
| - Elements,
|
| - FieldElement,
|
| - FunctionElement,
|
| - FunctionSignature,
|
| - GetterElement,
|
| - LibraryElement,
|
| - MethodElement,
|
| - Name,
|
| - ParameterElement,
|
| - TypedefElement,
|
| - VariableElement;
|
| +import '../../common/names.dart' show Names, Selectors;
|
| +import '../../compiler.dart' show Compiler;
|
| +import '../../constants/values.dart'
|
| + show ConstantValue, InterceptorConstantValue;
|
| +import '../../core_types.dart' show CoreClasses;
|
| +import '../../dart_types.dart' show DartType, FunctionType, TypedefType;
|
| +import '../../elements/elements.dart'
|
| + show
|
| + ClassElement,
|
| + Element,
|
| + Elements,
|
| + FieldElement,
|
| + FunctionElement,
|
| + FunctionSignature,
|
| + GetterElement,
|
| + LibraryElement,
|
| + MethodElement,
|
| + Name,
|
| + ParameterElement,
|
| + TypedefElement,
|
| + VariableElement;
|
| import '../../js/js.dart' as js;
|
| -import '../../js_backend/backend_helpers.dart' show
|
| - BackendHelpers;
|
| -import '../../js_backend/js_backend.dart' show
|
| - Namer,
|
| - JavaScriptBackend,
|
| - JavaScriptConstantCompiler,
|
| - StringBackedName;
|
| -import '../../universe/selector.dart' show
|
| - Selector;
|
| -import '../../universe/universe.dart' show
|
| - Universe,
|
| - SelectorConstraints;
|
| -import '../../deferred_load.dart' show
|
| - DeferredLoadTask,
|
| - OutputUnit;
|
| +import '../../js_backend/backend_helpers.dart' show BackendHelpers;
|
| +import '../../js_backend/js_backend.dart'
|
| + show Namer, JavaScriptBackend, JavaScriptConstantCompiler, StringBackedName;
|
| +import '../../universe/selector.dart' show Selector;
|
| +import '../../universe/universe.dart' show Universe, SelectorConstraints;
|
| +import '../../deferred_load.dart' show DeferredLoadTask, OutputUnit;
|
|
|
| part 'collector.dart';
|
| part 'registry.dart';
|
| @@ -87,11 +71,8 @@ class ProgramBuilder {
|
| /// True if the program should store function types in the metadata.
|
| bool _storeFunctionTypesInMetadata = false;
|
|
|
| - ProgramBuilder(Compiler compiler,
|
| - Namer namer,
|
| - this._task,
|
| - Emitter emitter,
|
| - Set<ClassElement> rtiNeededClasses)
|
| + ProgramBuilder(Compiler compiler, Namer namer, this._task, Emitter emitter,
|
| + Set<ClassElement> rtiNeededClasses)
|
| : this._compiler = compiler,
|
| this.namer = namer,
|
| this.collector =
|
| @@ -130,13 +111,13 @@ class ProgramBuilder {
|
| // Note: In rare cases (mostly tests) output units can be empty. This
|
| // happens when the deferred code is dead-code eliminated but we still need
|
| // to check that the library has been loaded.
|
| - _compiler.deferredLoadTask.allOutputUnits.forEach(
|
| - _registry.registerOutputUnit);
|
| + _compiler.deferredLoadTask.allOutputUnits
|
| + .forEach(_registry.registerOutputUnit);
|
| collector.outputClassLists.forEach(_registry.registerElements);
|
| collector.outputStaticLists.forEach(_registry.registerElements);
|
| collector.outputConstantLists.forEach(_registerConstants);
|
| - collector.outputStaticNonFinalFieldLists.forEach(
|
| - _registry.registerElements);
|
| + collector.outputStaticNonFinalFieldLists
|
| + .forEach(_registry.registerElements);
|
|
|
| // We always add the current isolate holder.
|
| _registerStaticStateHolder();
|
| @@ -144,7 +125,8 @@ class ProgramBuilder {
|
| // We need to run the native-preparation before we build the output. The
|
| // preparation code, in turn needs the classes to be set up.
|
| // We thus build the classes before building their containers.
|
| - collector.outputClassLists.forEach((OutputUnit _, List<ClassElement> classes) {
|
| + collector.outputClassLists
|
| + .forEach((OutputUnit _, List<ClassElement> classes) {
|
| classes.forEach(_buildClass);
|
| });
|
|
|
| @@ -169,9 +151,9 @@ class ProgramBuilder {
|
| Set<ClassElement> classesModifiedByEmitRTISupport =
|
| _task.typeTestRegistry.computeClassesModifiedByEmitRuntimeTypeSupport();
|
|
|
| -
|
| _unneededNativeClasses = _task.nativeEmitter.prepareNativeClasses(
|
| - nativeClasses, interceptorClassesNeededByConstants,
|
| + nativeClasses,
|
| + interceptorClassesNeededByConstants,
|
| classesModifiedByEmitRTISupport);
|
|
|
| _addJsInteropStubs(_registry.mainLibrariesMap);
|
| @@ -199,14 +181,8 @@ class ProgramBuilder {
|
| finalizers.add(namingFinalizer);
|
| }
|
|
|
| - return new Program(
|
| - fragments,
|
| - holders,
|
| - _buildLoadMap(),
|
| - _symbolsMap,
|
| - _buildTypeToInterceptorMap(),
|
| - _task.metadataCollector,
|
| - finalizers,
|
| + return new Program(fragments, holders, _buildLoadMap(), _symbolsMap,
|
| + _buildTypeToInterceptorMap(), _task.metadataCollector, finalizers,
|
| needsNativeSupport: needsNativeSupport,
|
| outputContainsConstantList: collector.outputContainsConstantList,
|
| hasIsolateSupport: _compiler.hasIsolateSupport);
|
| @@ -238,7 +214,7 @@ class ProgramBuilder {
|
| // Construct the main output from the libraries and the registered holders.
|
| MainFragment result = new MainFragment(
|
| librariesMap.outputUnit,
|
| - "", // The empty string is the name for the main output file.
|
| + "", // The empty string is the name for the main output file.
|
| _buildInvokeMain(),
|
| _buildLibraries(librariesMap),
|
| _buildStaticNonFinalFields(librariesMap),
|
| @@ -260,7 +236,7 @@ class ProgramBuilder {
|
| DeferredFragment result = new DeferredFragment(
|
| librariesMap.outputUnit,
|
| backend.deferredPartFileName(librariesMap.name, addExtension: false),
|
| - librariesMap.name,
|
| + librariesMap.name,
|
| _buildLibraries(librariesMap),
|
| _buildStaticNonFinalFields(librariesMap),
|
| _buildStaticLazilyInitializedFields(librariesMap),
|
| @@ -273,18 +249,17 @@ class ProgramBuilder {
|
| List<ConstantValue> constantValues =
|
| collector.outputConstantLists[librariesMap.outputUnit];
|
| if (constantValues == null) return const <Constant>[];
|
| - return constantValues.map((ConstantValue value) => _constants[value])
|
| + return constantValues
|
| + .map((ConstantValue value) => _constants[value])
|
| .toList(growable: false);
|
| }
|
|
|
| List<StaticField> _buildStaticNonFinalFields(LibrariesMap librariesMap) {
|
| List<VariableElement> staticNonFinalFields =
|
| - collector.outputStaticNonFinalFieldLists[librariesMap.outputUnit];
|
| + collector.outputStaticNonFinalFieldLists[librariesMap.outputUnit];
|
| if (staticNonFinalFields == null) return const <StaticField>[];
|
|
|
| - return staticNonFinalFields
|
| - .map(_buildStaticField)
|
| - .toList(growable: false);
|
| + return staticNonFinalFields.map(_buildStaticField).toList(growable: false);
|
| }
|
|
|
| StaticField _buildStaticField(Element element) {
|
| @@ -292,8 +267,8 @@ class ProgramBuilder {
|
| ConstantValue initialValue = handler.getInitialValueFor(element);
|
| // TODO(zarah): The holder should not be registered during building of
|
| // a static field.
|
| - _registry.registerHolder(
|
| - namer.globalObjectForConstant(initialValue), isConstantsHolder: true);
|
| + _registry.registerHolder(namer.globalObjectForConstant(initialValue),
|
| + isConstantsHolder: true);
|
| js.Expression code = _task.emitter.constantReference(initialValue);
|
| js.Name name = namer.globalPropertyName(element);
|
| bool isFinal = false;
|
| @@ -303,9 +278,8 @@ class ProgramBuilder {
|
| // building a static field. (Note that the static-state holder was
|
| // already registered earlier, and that we just call the register to get
|
| // the holder-instance.
|
| - return new StaticField(element,
|
| - name, _registerStaticStateHolder(), code,
|
| - isFinal, isLazy);
|
| + return new StaticField(
|
| + element, name, _registerStaticStateHolder(), code, isFinal, isLazy);
|
| }
|
|
|
| List<StaticField> _buildStaticLazilyInitializedFields(
|
| @@ -316,9 +290,10 @@ class ProgramBuilder {
|
| .getLazilyInitializedFieldsForEmission()
|
| .where((element) =>
|
| loadTask.outputUnitForElement(element) == librariesMap.outputUnit);
|
| - return Elements.sortedByPosition(lazyFields)
|
| + return Elements
|
| + .sortedByPosition(lazyFields)
|
| .map(_buildLazyField)
|
| - .where((field) => field != null) // Happens when the field was unused.
|
| + .where((field) => field != null) // Happens when the field was unused.
|
| .toList(growable: false);
|
| }
|
|
|
| @@ -336,9 +311,8 @@ class ProgramBuilder {
|
| // building a static field. (Note that the static-state holder was
|
| // already registered earlier, and that we just call the register to get
|
| // the holder-instance.
|
| - return new StaticField(element,
|
| - name, _registerStaticStateHolder(), code,
|
| - isFinal, isLazy);
|
| + return new StaticField(
|
| + element, name, _registerStaticStateHolder(), code, isFinal, isLazy);
|
| }
|
|
|
| List<Library> _buildLibraries(LibrariesMap librariesMap) {
|
| @@ -356,8 +330,7 @@ class ProgramBuilder {
|
| // TODO(jacobr): register toString as used so that it is always accessible
|
| // from JavaScript.
|
| _classes[_compiler.coreClasses.objectClass].callStubs.add(
|
| - _buildStubMethod(
|
| - new StringBackedName("toString"),
|
| + _buildStubMethod(new StringBackedName("toString"),
|
| js.js('function() { return this.#(this) }', toStringInvocation)));
|
| }
|
|
|
| @@ -382,10 +355,8 @@ class ProgramBuilder {
|
| for (var selector in selectors.keys) {
|
| var stubName = namer.invocationName(selector);
|
| if (stubNames.add(stubName.key)) {
|
| - interceptorClass.callStubs.add(_buildStubMethod(
|
| - stubName,
|
| - js.js(
|
| - 'function(obj) { return obj.# }', [member.name]),
|
| + interceptorClass.callStubs.add(_buildStubMethod(stubName,
|
| + js.js('function(obj) { return obj.# }', [member.name]),
|
| element: member));
|
| }
|
| }
|
| @@ -422,8 +393,8 @@ class ProgramBuilder {
|
| if (returnType.isFunctionType) {
|
| functionType = returnType;
|
| } else if (returnType.treatAsDynamic ||
|
| - _compiler.types.isSubtype(returnType,
|
| - backend.coreTypes.functionType)) {
|
| + _compiler.types.isSubtype(
|
| + returnType, backend.coreTypes.functionType)) {
|
| if (returnType.isTypedef) {
|
| TypedefType typedef = returnType;
|
| // TODO(jacobr): can we just use typdef.unaliased instead?
|
| @@ -464,8 +435,8 @@ class ProgramBuilder {
|
| if (argumentCount > maxArgs) break;
|
| var stubName = namer.invocationName(selector);
|
| if (!stubNames.add(stubName.key)) break;
|
| - var parameters = new List<String>.generate(argumentCount,
|
| - (i) => 'p$i');
|
| + var parameters =
|
| + new List<String>.generate(argumentCount, (i) => 'p$i');
|
|
|
| // We intentionally generate the same stub method for direct
|
| // calls and call-throughs of getters so that calling a
|
| @@ -514,8 +485,8 @@ class ProgramBuilder {
|
| bool visitStatics = true;
|
| List<Field> staticFieldsForReflection = _buildFields(library, visitStatics);
|
|
|
| - return new Library(library, uri, statics, classes,
|
| - staticFieldsForReflection);
|
| + return new Library(
|
| + library, uri, statics, classes, staticFieldsForReflection);
|
| }
|
|
|
| /// HACK for Incremental Compilation.
|
| @@ -563,7 +534,6 @@ class ProgramBuilder {
|
| Map<Selector, SelectorConstraints> selectors =
|
| _compiler.codegenWorld.invocationsByName(member.name);
|
| if (selectors != null && !selectors.isEmpty) {
|
| -
|
| Map<js.Name, js.Expression> callStubsForMember =
|
| classStubGenerator.generateCallStubsForGetter(member, selectors);
|
| callStubsForMember.forEach((js.Name name, js.Expression code) {
|
| @@ -588,9 +558,8 @@ class ProgramBuilder {
|
| if (backend.symbolsUsed.contains(selectorName)) {
|
| _symbolsMap[name] = selectorName;
|
| }
|
| - noSuchMethodStubs
|
| - .add(classStubGenerator.generateStubForNoSuchMethod(name,
|
| - selector));
|
| + noSuchMethodStubs.add(
|
| + classStubGenerator.generateStubForNoSuchMethod(name, selector));
|
| });
|
| }
|
|
|
| @@ -615,17 +584,16 @@ class ProgramBuilder {
|
| List<Field> staticFieldsForReflection =
|
| onlyForRti ? const <Field>[] : _buildFields(element, true);
|
|
|
| - TypeTestProperties typeTests =
|
| - runtimeTypeGenerator.generateIsTests(
|
| - element,
|
| - storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata);
|
| + TypeTestProperties typeTests = runtimeTypeGenerator.generateIsTests(element,
|
| + storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata);
|
|
|
| List<StubMethod> checkedSetters = <StubMethod>[];
|
| List<StubMethod> isChecks = <StubMethod>[];
|
| if (backend.isJsInterop(element)) {
|
| typeTests.properties.forEach((js.Name name, js.Node code) {
|
| - _classes[helpers.jsInterceptorClass].isChecks.add(
|
| - _buildStubMethod(name, code));
|
| + _classes[helpers.jsInterceptorClass]
|
| + .isChecks
|
| + .add(_buildStubMethod(name, code));
|
| });
|
| } else {
|
| for (Field field in instanceFields) {
|
| @@ -657,30 +625,36 @@ class ProgramBuilder {
|
| assert(!backend.isNative(element));
|
| assert(methods.isEmpty);
|
|
|
| - result = new MixinApplication(element,
|
| - name, holder,
|
| - instanceFields,
|
| - staticFieldsForReflection,
|
| - callStubs,
|
| - typeVariableReaderStubs,
|
| - checkedSetters,
|
| - isChecks,
|
| - typeTests.functionTypeIndex,
|
| - isDirectlyInstantiated: isInstantiated,
|
| - onlyForRti: onlyForRti);
|
| + result = new MixinApplication(
|
| + element,
|
| + name,
|
| + holder,
|
| + instanceFields,
|
| + staticFieldsForReflection,
|
| + callStubs,
|
| + typeVariableReaderStubs,
|
| + checkedSetters,
|
| + isChecks,
|
| + typeTests.functionTypeIndex,
|
| + isDirectlyInstantiated: isInstantiated,
|
| + onlyForRti: onlyForRti);
|
| } else {
|
| - result = new Class(element,
|
| - name, holder, methods, instanceFields,
|
| - staticFieldsForReflection,
|
| - callStubs,
|
| - typeVariableReaderStubs,
|
| - noSuchMethodStubs,
|
| - checkedSetters,
|
| - isChecks,
|
| - typeTests.functionTypeIndex,
|
| - isDirectlyInstantiated: isInstantiated,
|
| - onlyForRti: onlyForRti,
|
| - isNative: backend.isNative(element));
|
| + result = new Class(
|
| + element,
|
| + name,
|
| + holder,
|
| + methods,
|
| + instanceFields,
|
| + staticFieldsForReflection,
|
| + callStubs,
|
| + typeVariableReaderStubs,
|
| + noSuchMethodStubs,
|
| + checkedSetters,
|
| + isChecks,
|
| + typeTests.functionTypeIndex,
|
| + isDirectlyInstantiated: isInstantiated,
|
| + onlyForRti: onlyForRti,
|
| + isNative: backend.isNative(element));
|
| }
|
| _classes[element] = result;
|
| return result;
|
| @@ -762,7 +736,7 @@ class ProgramBuilder {
|
| canTearOff = universe.hasInvokedGetter(element, _compiler.world) ||
|
| (canBeReflected && !element.isOperator);
|
| assert(canTearOff ||
|
| - !universe.methodsNeedingSuperGetter.contains(element));
|
| + !universe.methodsNeedingSuperGetter.contains(element));
|
| tearOffName = namer.getterForElement(element);
|
| }
|
| }
|
| @@ -809,9 +783,12 @@ class ProgramBuilder {
|
|
|
| return new InstanceMethod(element, name, code,
|
| _generateParameterStubs(element, canTearOff), callName,
|
| - needsTearOff: canTearOff, tearOffName: tearOffName,
|
| - isClosureCallMethod: isClosureCallMethod, aliasName: aliasName,
|
| - canBeApplied: canBeApplied, canBeReflected: canBeReflected,
|
| + needsTearOff: canTearOff,
|
| + tearOffName: tearOffName,
|
| + isClosureCallMethod: isClosureCallMethod,
|
| + aliasName: aliasName,
|
| + canBeApplied: canBeApplied,
|
| + canBeReflected: canBeReflected,
|
| requiredParameterCount: requiredParameterCount,
|
| optionalParameterDefaultValues: optionalParameterDefaultValues,
|
| functionType: functionType);
|
| @@ -827,9 +804,8 @@ class ProgramBuilder {
|
| }
|
| }
|
|
|
| - List<ParameterStubMethod> _generateParameterStubs(MethodElement element,
|
| - bool canTearOff) {
|
| -
|
| + List<ParameterStubMethod> _generateParameterStubs(
|
| + MethodElement element, bool canTearOff) {
|
| if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[];
|
|
|
| ParameterStubGenerator generator =
|
| @@ -841,8 +817,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,
|
| - {Element element}) {
|
| + Method _buildStubMethod(js.Name name, js.Expression code, {Element element}) {
|
| return new StubMethod(name, code, element: element);
|
| }
|
|
|
| @@ -881,13 +856,9 @@ class ProgramBuilder {
|
|
|
| List<Field> _buildFields(Element holder, bool visitStatics) {
|
| List<Field> fields = <Field>[];
|
| - new FieldVisitor(_compiler, namer).visitFields(
|
| - holder, visitStatics, (VariableElement field,
|
| - js.Name name,
|
| - js.Name accessorName,
|
| - bool needsGetter,
|
| - bool needsSetter,
|
| - bool needsCheckedSetter) {
|
| + new FieldVisitor(_compiler, namer).visitFields(holder, visitStatics,
|
| + (VariableElement field, js.Name name, js.Name accessorName,
|
| + bool needsGetter, bool needsSetter, bool needsCheckedSetter) {
|
| assert(invariant(field, field.isDeclaration));
|
|
|
| int getterFlags = 0;
|
| @@ -917,9 +888,8 @@ class ProgramBuilder {
|
| }
|
| }
|
|
|
| - fields.add(new Field(field, name, accessorName,
|
| - getterFlags, setterFlags,
|
| - needsCheckedSetter));
|
| + fields.add(new Field(field, name, accessorName, getterFlags, setterFlags,
|
| + needsCheckedSetter));
|
| });
|
|
|
| return fields;
|
| @@ -957,7 +927,6 @@ class ProgramBuilder {
|
| js.Name tearOffName =
|
| needsTearOff ? namer.staticClosureName(element) : null;
|
|
|
| -
|
| js.Name callName = null;
|
| if (needsTearOff) {
|
| Selector callSelector =
|
| @@ -983,22 +952,19 @@ class ProgramBuilder {
|
|
|
| // TODO(floitsch): we shouldn't update the registry in the middle of
|
| // building a static method.
|
| - return new StaticDartMethod(element,
|
| - name, _registry.registerHolder(holder), code,
|
| - _generateParameterStubs(element, needsTearOff),
|
| - callName,
|
| - needsTearOff: needsTearOff,
|
| - tearOffName: tearOffName,
|
| - canBeApplied: canBeApplied,
|
| - canBeReflected: canBeReflected,
|
| - requiredParameterCount: requiredParameterCount,
|
| - optionalParameterDefaultValues:
|
| - optionalParameterDefaultValues,
|
| - functionType: functionType);
|
| - }
|
| -
|
| - void _registerConstants(OutputUnit outputUnit,
|
| - Iterable<ConstantValue> constantValues) {
|
| + return new StaticDartMethod(element, name, _registry.registerHolder(holder),
|
| + code, _generateParameterStubs(element, needsTearOff), callName,
|
| + needsTearOff: needsTearOff,
|
| + tearOffName: tearOffName,
|
| + canBeApplied: canBeApplied,
|
| + canBeReflected: canBeReflected,
|
| + requiredParameterCount: requiredParameterCount,
|
| + optionalParameterDefaultValues: optionalParameterDefaultValues,
|
| + functionType: functionType);
|
| + }
|
| +
|
| + void _registerConstants(
|
| + OutputUnit outputUnit, Iterable<ConstantValue> constantValues) {
|
| // `constantValues` is null if an outputUnit doesn't contain any constants.
|
| if (constantValues == null) return;
|
| for (ConstantValue constantValue in constantValues) {
|
| @@ -1014,7 +980,7 @@ class ProgramBuilder {
|
| }
|
|
|
| Holder _registerStaticStateHolder() {
|
| - return _registry.registerHolder(
|
| - namer.staticStateHolder, isStaticStateHolder: true);
|
| + return _registry.registerHolder(namer.staticStateHolder,
|
| + isStaticStateHolder: true);
|
| }
|
| }
|
|
|