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); |
} |
} |