Index: pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart |
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart |
index 334b7462e8518239135b2a111047fc190f7cd8e4..27498505b37e687e9e123ef91802259435bbf18b 100644 |
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart |
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart |
@@ -43,9 +43,11 @@ class OldEmitter implements Emitter { |
=> task.outputClassLists; |
Map<OutputUnit, List<ConstantValue>> get outputConstantLists |
=> task.outputConstantLists; |
- final Map<String, String> mangledFieldNames = <String, String>{}; |
- final Map<String, String> mangledGlobalFieldNames = <String, String>{}; |
- final Set<String> recordedMangledNames = new Set<String>(); |
+ final Map<jsAst.Name, String> mangledFieldNames = |
+ new HashMap<jsAst.Name, String>(); |
+ final Map<jsAst.Name, String> mangledGlobalFieldNames = |
+ new HashMap<jsAst.Name, String>(); |
+ final Set<jsAst.Name> recordedMangledNames = new Set<jsAst.Name>(); |
List<TypedefElement> get typedefsNeededForReflection => |
task.typedefsNeededForReflection; |
@@ -93,7 +95,7 @@ class OldEmitter implements Emitter { |
cachedClassBuilders = compiler.cacheStrategy.newMap(), |
cachedElements = compiler.cacheStrategy.newSet() { |
constantEmitter = new ConstantEmitter( |
- compiler, namer, this.constantReference, makeConstantListTemplate); |
+ compiler, namer, this.constantReference, constantListGenerator); |
containerBuilder.emitter = this; |
classEmitter.emitter = this; |
nsmEmitter.emitter = this; |
@@ -152,7 +154,9 @@ class OldEmitter implements Emitter { |
if (r != 0) return r; |
// Resolve collisions in the long name by using the constant name (i.e. JS |
// name) which is unique. |
- return namer.constantName(a).compareTo(namer.constantName(b)); |
+ // TODO(herhut): Find a better way to resolve collisions. |
+ return namer.constantName(a).hashCode.compareTo( |
+ namer.constantName(b).hashCode); |
} |
@override |
@@ -187,7 +191,8 @@ class OldEmitter implements Emitter { |
=> '${namer.isolateName}.${lazyInitializerProperty}'; |
String get initName => 'init'; |
- String get makeConstListProperty => namer.internalGlobal('makeConstantList'); |
+ jsAst.Name get makeConstListProperty |
+ => namer.internalGlobal('makeConstantList'); |
/// The name of the property that contains all field names. |
/// |
@@ -199,7 +204,7 @@ class OldEmitter implements Emitter { |
/// Contains the global state that is needed to initialize and load a |
/// deferred library. |
- String get globalsHolder => namer.internalGlobal("globalsHolder"); |
+ jsAst.Name get globalsHolder => namer.internalGlobal("globalsHolder"); |
@override |
jsAst.Expression generateEmbeddedGlobalAccess(String global) { |
@@ -212,8 +217,8 @@ class OldEmitter implements Emitter { |
} |
jsAst.PropertyAccess globalPropertyAccess(Element element) { |
- String name = namer.globalPropertyName(element); |
- jsAst.PropertyAccess pa = new jsAst.PropertyAccess.field( |
+ jsAst.Name name = namer.globalPropertyName(element); |
+ jsAst.PropertyAccess pa = new jsAst.PropertyAccess( |
new jsAst.VariableUse(namer.globalObjectFor(element)), |
name); |
return pa; |
@@ -293,23 +298,8 @@ class OldEmitter implements Emitter { |
return jsAst.js.expressionTemplateFor( |
"('$isPrefix' + #) in #.prototype"); |
- case JsBuiltin.isFunctionTypeRti: |
- String functionClassName = |
- backend.namer.runtimeTypeName(compiler.functionClass); |
- return jsAst.js.expressionTemplateFor( |
- '#.$typeNameProperty === "$functionClassName"'); |
- |
- case JsBuiltin.isDartObjectTypeRti: |
- String objectClassName = |
- backend.namer.runtimeTypeName(compiler.objectClass); |
- return jsAst.js.expressionTemplateFor( |
- '#.$typeNameProperty === "$objectClassName"'); |
- |
- case JsBuiltin.isNullTypeRti: |
- String nullClassName = |
- backend.namer.runtimeTypeName(compiler.nullClass); |
- return jsAst.js.expressionTemplateFor( |
- '#.$typeNameProperty === "$nullClassName"'); |
+ case JsBuiltin.isGivenTypeRti: |
+ return jsAst.js.expressionTemplateFor('#.$typeNameProperty === #'); |
case JsBuiltin.getMetadata: |
String metadataAccess = |
@@ -371,7 +361,7 @@ class OldEmitter implements Emitter { |
/// The reflection name of class 'C' is 'C'. |
/// An anonymous mixin application has no reflection name. |
/// This is used by js_mirrors.dart. |
- String getReflectionName(elementOrSelector, String mangledName) { |
+ String getReflectionName(elementOrSelector, jsAst.Name mangledName) { |
String name = elementOrSelector.name; |
if (backend.shouldRetainName(name) || |
elementOrSelector is Element && |
@@ -390,13 +380,15 @@ class OldEmitter implements Emitter { |
return null; |
} |
- String getReflectionNameInternal(elementOrSelector, String mangledName) { |
+ String getReflectionNameInternal(elementOrSelector, |
+ jsAst.Name mangledName) { |
String name = namer.privateName(elementOrSelector.memberName); |
if (elementOrSelector.isGetter) return name; |
if (elementOrSelector.isSetter) { |
- if (!mangledName.startsWith(namer.setterPrefix)) return '$name='; |
- String base = mangledName.substring(namer.setterPrefix.length); |
- String getter = '${namer.getterPrefix}$base'; |
+ if (mangledName is! SetterName) return '$name='; |
+ SetterName setterName = mangledName; |
+ jsAst.Name base = setterName.base; |
+ jsAst.Name getter = namer.deriveGetterName(base); |
mangledFieldNames.putIfAbsent(getter, () => name); |
assert(mangledFieldNames[getter] == name); |
recordedMangledNames.add(getter); |
@@ -409,7 +401,7 @@ class OldEmitter implements Emitter { |
// Closures are synthesized and their name might conflict with existing |
// globals. Assign an illegal name, and make sure they don't clash |
// with each other. |
- return " $mangledName"; |
+ return " $name"; |
} |
if (elementOrSelector is Selector |
|| elementOrSelector.isFunction |
@@ -501,7 +493,8 @@ class OldEmitter implements Emitter { |
if (compiler.hasIncrementalSupport) { |
ClassBuilder cachedBuilder = |
cachedClassBuilders.putIfAbsent(classElement, () { |
- ClassBuilder builder = new ClassBuilder(classElement, namer); |
+ ClassBuilder builder = |
+ new ClassBuilder.forClass(classElement, namer); |
classEmitter.emitClass(cls, builder, fragment); |
return builder; |
}); |
@@ -525,7 +518,7 @@ class OldEmitter implements Emitter { |
// We need to filter out null-elements for the interceptors. |
// TODO(floitsch): use the precomputed interceptors here. |
if (element == null) continue; |
- ClassBuilder builder = new ClassBuilder(element, namer); |
+ ClassBuilder builder = new ClassBuilder.forStatics(element, namer); |
containerBuilder.addMemberMethod(method, builder); |
getElementDescriptor(element, fragment).properties |
.addAll(builder.properties); |
@@ -625,12 +618,12 @@ class OldEmitter implements Emitter { |
// before code generation. |
if (code == null) continue; |
if (compiler.enableMinification) { |
- laziesInfo.addAll([js.string(namer.globalPropertyName(element)), |
- js.string(namer.lazyInitializerName(element)), |
+ laziesInfo.addAll([js.quoteName(namer.globalPropertyName(element)), |
+ js.quoteName(namer.lazyInitializerName(element)), |
code]); |
} else { |
- laziesInfo.addAll([js.string(namer.globalPropertyName(element)), |
- js.string(namer.lazyInitializerName(element)), |
+ laziesInfo.addAll([js.quoteName(namer.globalPropertyName(element)), |
+ js.quoteName(namer.lazyInitializerName(element)), |
code, |
js.string(element.name)]); |
} |
@@ -655,8 +648,8 @@ class OldEmitter implements Emitter { |
// in new lazy values. |
return js('#(#,#,#,#,#)', |
[js(lazyInitializerName), |
- js.string(namer.globalPropertyName(element)), |
- js.string(namer.lazyInitializerName(element)), |
+ js.quoteName(namer.globalPropertyName(element)), |
+ js.quoteName(namer.lazyInitializerName(element)), |
code, |
js.string(element.name), |
isolateProperties]); |
@@ -665,14 +658,14 @@ class OldEmitter implements Emitter { |
if (compiler.enableMinification) { |
return js('#(#,#,#)', |
[js(lazyInitializerName), |
- js.string(namer.globalPropertyName(element)), |
- js.string(namer.lazyInitializerName(element)), |
+ js.quoteName(namer.globalPropertyName(element)), |
+ js.quoteName(namer.lazyInitializerName(element)), |
code]); |
} else { |
return js('#(#,#,#,#)', |
[js(lazyInitializerName), |
- js.string(namer.globalPropertyName(element)), |
- js.string(namer.lazyInitializerName(element)), |
+ js.quoteName(namer.globalPropertyName(element)), |
+ js.quoteName(namer.lazyInitializerName(element)), |
code, |
js.string(element.name)]); |
} |
@@ -720,16 +713,15 @@ class OldEmitter implements Emitter { |
} |
jsAst.Statement buildConstantInitializer(ConstantValue constant) { |
- String name = namer.constantName(constant); |
+ jsAst.Name name = namer.constantName(constant); |
return js.statement('#.# = #', |
[namer.globalObjectForConstant(constant), name, |
constantInitializerExpression(constant)]); |
} |
- jsAst.Template get makeConstantListTemplate { |
+ jsAst.Expression constantListGenerator(jsAst.Expression array) { |
// TODO(floitsch): there is no harm in caching the template. |
- return jsAst.js.uncachedExpressionTemplate( |
- '${namer.isolateName}.$makeConstListProperty(#)'); |
+ return js('${namer.isolateName}.#(#)', [makeConstListProperty, array]); |
} |
jsAst.Statement buildMakeConstantList() { |
@@ -1024,12 +1016,11 @@ class OldEmitter implements Emitter { |
} |
void assemblePrecompiledConstructor(OutputUnit outputUnit, |
- String constructorName, |
+ jsAst.Name constructorName, |
jsAst.Expression constructorAst, |
List<String> fields) { |
cspPrecompiledFunctionFor(outputUnit).add( |
- new jsAst.FunctionDeclaration( |
- new jsAst.VariableDeclaration(constructorName), constructorAst)); |
+ new jsAst.FunctionDeclaration(constructorName, constructorAst)); |
String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME; |
bool hasIsolateSupport = compiler.hasIsolateSupport; |
@@ -1051,7 +1042,7 @@ class OldEmitter implements Emitter { |
}''', |
{"constructorName": constructorName, |
"typeNameProperty": typeNameProperty, |
- "constructorNameString": js.string(constructorName), |
+ "constructorNameString": js.quoteName(constructorName), |
"hasIsolateSupport": hasIsolateSupport, |
"fieldNamesArray": fieldNamesArray})); |
@@ -1073,10 +1064,11 @@ class OldEmitter implements Emitter { |
// typedefs is supported. |
jsAst.Expression typeIndex = |
task.metadataCollector.reifyType(type, ignoreTypeVariables: true); |
- ClassBuilder builder = new ClassBuilder(typedef, namer); |
- builder.addProperty(embeddedNames.TYPEDEF_TYPE_PROPERTY_NAME, typeIndex); |
- builder.addProperty(embeddedNames.TYPEDEF_PREDICATE_PROPERTY_NAME, |
- js.boolean(true)); |
+ ClassBuilder builder = new ClassBuilder.forStatics(typedef, namer); |
+ builder.addPropertyByName(embeddedNames.TYPEDEF_TYPE_PROPERTY_NAME, |
+ typeIndex); |
+ builder.addPropertyByName(embeddedNames.TYPEDEF_PREDICATE_PROPERTY_NAME, |
+ js.boolean(true)); |
// We can be pretty sure that the objectClass is initialized, since |
// typedefs are only emitted with reflection, which requires lots of |
@@ -1084,13 +1076,13 @@ class OldEmitter implements Emitter { |
assert(compiler.objectClass != null); |
builder.superName = namer.className(compiler.objectClass); |
jsAst.Node declaration = builder.toObjectInitializer(); |
- String mangledName = namer.globalPropertyName(typedef); |
+ jsAst.Name mangledName = namer.globalPropertyName(typedef); |
String reflectionName = getReflectionName(typedef, mangledName); |
getElementDescriptor(library, mainFragment) |
..addProperty(mangledName, declaration) |
- ..addProperty("+$reflectionName", js.string('')); |
+ ..addPropertyByName("+$reflectionName", js.string('')); |
// Also emit a trivial constructor for CSP mode. |
- String constructorName = mangledName; |
+ jsAst.Name constructorName = mangledName; |
jsAst.Expression constructorAst = js('function() {}'); |
List<String> fieldNames = []; |
assemblePrecompiledConstructor(mainOutputUnit, |
@@ -1190,12 +1182,11 @@ class OldEmitter implements Emitter { |
List<jsAst.Statement> parts = <jsAst.Statement>[]; |
if (!mangledFieldNames.isEmpty) { |
- var keys = mangledFieldNames.keys.toList(); |
- keys.sort(); |
+ List<jsAst.Name> keys = mangledFieldNames.keys.toList()..sort(); |
var properties = []; |
- for (String key in keys) { |
- var value = js.string('${mangledFieldNames[key]}'); |
- properties.add(new jsAst.Property(js.string(key), value)); |
+ for (jsAst.Name key in keys) { |
+ var value = js.string(mangledFieldNames[key]); |
+ properties.add(new jsAst.Property(key, value)); |
} |
jsAst.Expression mangledNamesAccess = |
@@ -1205,16 +1196,16 @@ class OldEmitter implements Emitter { |
} |
if (!mangledGlobalFieldNames.isEmpty) { |
- var keys = mangledGlobalFieldNames.keys.toList(); |
- keys.sort(); |
- var properties = []; |
- for (String key in keys) { |
- var value = js.string('${mangledGlobalFieldNames[key]}'); |
- properties.add(new jsAst.Property(js.string(key), value)); |
+ List<jsAst.Name> keys = mangledGlobalFieldNames.keys.toList() |
+ ..sort(); |
+ List<jsAst.Property> properties = <jsAst.Property>[]; |
+ for (jsAst.Name key in keys) { |
+ jsAst.Literal value = js.string(mangledGlobalFieldNames[key]); |
+ properties.add(new jsAst.Property(js.quoteName(key), value)); |
} |
jsAst.Expression mangledGlobalNamesAccess = |
generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES); |
- var map = new jsAst.ObjectInitializer(properties); |
+ jsAst.ObjectInitializer map = new jsAst.ObjectInitializer(properties); |
parts.add(js.statement('# = #', [mangledGlobalNamesAccess, map])); |
} |
@@ -1717,6 +1708,7 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) { |
ClassBuilder getElementDescriptor(Element element, Fragment fragment) { |
Element owner = element.library; |
+ bool isClass = false; |
if (!element.isLibrary && !element.isTopLevel && !element.isNative) { |
// For static (not top level) elements, record their code in a buffer |
// specific to the class. For now, not supported for native classes and |
@@ -1735,7 +1727,9 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) { |
} |
return elementDescriptors |
.putIfAbsent(fragment, () => new Map<Element, ClassBuilder>()) |
- .putIfAbsent(owner, () => new ClassBuilder(owner, namer)); |
+ .putIfAbsent(owner, () { |
+ return new ClassBuilder(owner, namer, owner.isClass); |
+ }); |
} |
/// Emits support-code for deferred loading into [output]. |
@@ -1757,11 +1751,12 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) { |
// Function for initializing a loaded hunk, given its hash. |
#initializeLoadedHunk = function(hunkHash) { |
$deferredInitializers[hunkHash]( |
- $globalsHolder, ${namer.currentIsolate}); |
+ #globalsHolder, ${namer.currentIsolate}); |
#deferredInitialized[hunkHash] = true; |
}; |
} |
- ''', {"isHunkLoaded": generateEmbeddedGlobalAccess( |
+ ''', {"globalsHolder": globalsHolder, |
+ "isHunkLoaded": generateEmbeddedGlobalAccess( |
embeddedNames.IS_HUNK_LOADED), |
"isHunkInitialized": generateEmbeddedGlobalAccess( |
embeddedNames.IS_HUNK_INITIALIZED), |
@@ -1834,14 +1829,18 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) { |
body.add(js.comment("/* ::norenaming:: ")); |
for (String globalObject in Namer.reservedGlobalObjectNames) { |
- body.add(js.statement('var #object = ${globalsHolder}.#object;', |
- {'object': globalObject})); |
+ body.add(js.statement('var #object = #globalsHolder.#object;', |
+ {'globalsHolder': globalsHolder, |
+ 'object': globalObject})); |
} |
- body..add(js.statement('var init = ${globalsHolder}.init;')) |
+ body..add(js.statement('var init = #globalsHolder.init;', |
+ {'globalsHolder': globalsHolder})) |
..add(js.statement('var $setupProgramName = ' |
- '$globalsHolder.$setupProgramName;')) |
+ '#globalsHolder.$setupProgramName;', |
+ {'globalsHolder': globalsHolder})) |
..add(js.statement('var ${namer.isolateName} = ' |
- '${globalsHolder}.${namer.isolateName};')); |
+ '#globalsHolder.${namer.isolateName};', |
+ {'globalsHolder': globalsHolder})); |
String typesAccess = |
generateEmbeddedGlobalAccessString(embeddedNames.TYPES); |
if (libraryDescriptor != null) { |
@@ -1874,10 +1873,10 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) { |
statements |
..add(buildGeneratedBy()) |
..add(js.statement('${deferredInitializers}.current = ' |
- """function (${globalsHolder}) { |
+ """function (#) { |
# |
} |
- """, [body])); |
+ """, [globalsHolder, body])); |
result[outputUnit] = new jsAst.Program(statements); |
} |