Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Unified Diff: pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart

Issue 1198293002: dart2js: Use an abstract Name class for names in the generated JavaScript ast. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fix tests Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);
}

Powered by Google App Engine
This is Rietveld 408576698