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

Unified Diff: pkg/compiler/lib/src/js_backend/namer.dart

Issue 2907373002: Use entities for globals in Namer. (Closed)
Patch Set: Updated cf. comments Created 3 years, 7 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_emitter/code_emitter_task.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/js_backend/namer.dart
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 43bb6804b3e4934847540521360696d2f0f7791e..b367c9e4e4f1c97f7215919f5b9b2866c9c5fb35 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -514,8 +514,7 @@ class Namer {
/// (see [globalObjectFor]), we currently use a single namespace for all these
/// names.
final NamingScope globalScope = new NamingScope();
- final Map<Element, jsAst.Name> userGlobals =
- new HashMap<Element, jsAst.Name>();
+ final Map<Entity, jsAst.Name> userGlobals = new HashMap<Entity, jsAst.Name>();
final Map<String, jsAst.Name> internalGlobals =
new HashMap<String, jsAst.Name>();
@@ -867,7 +866,7 @@ class Namer {
jsAst.Name fieldAccessorName(FieldElement element) {
return element.isInstanceMember
? _disambiguateMember(element.memberName)
- : _disambiguateGlobal(element);
+ : _disambiguateGlobalMember(element);
}
/**
@@ -877,19 +876,32 @@ class Namer {
jsAst.Name fieldPropertyName(FieldElement element) {
return element.isInstanceMember
? instanceFieldPropertyName(element)
- : _disambiguateGlobal(element);
+ : _disambiguateGlobalMember(element);
}
- /**
- * Returns a JavaScript property name used to store [element] on one
- * of the global objects.
- *
- * Should be used together with [globalObjectFor], which denotes the object
- * on which the returned property name should be used.
- */
- jsAst.Name globalPropertyName(Element element) {
- return _disambiguateGlobal(element);
- }
+ /// Returns a JavaScript property name used to store the member [element] on
+ /// one of the global objects.
+ ///
+ /// Should be used together with [globalObjectForMember], which denotes the
+ /// object on which the returned property name should be used.
+ jsAst.Name globalPropertyNameForMember(MemberEntity element) =>
+ _disambiguateGlobalMember(element);
+
+ /// Returns a JavaScript property name used to store the class [element] on
+ /// one of the global objects.
+ ///
+ /// Should be used together with [globalObjectForClass], which denotes the
+ /// object on which the returned property name should be used.
+ jsAst.Name globalPropertyNameForClass(ClassEntity element) =>
+ _disambiguateGlobalType(element);
+
+ /// Returns a JavaScript property name used to store the type (typedef)
+ /// [element] on one of the global objects.
+ ///
+ /// Should be used together with [globalObjectForType], which denotes the
+ /// object on which the returned property name should be used.
+ jsAst.Name globalPropertyNameForType(TypeDeclarationElement element) =>
+ _disambiguateGlobalType(element);
/**
* Returns the JavaScript property name used to store an instance field.
@@ -1023,16 +1035,30 @@ class Namer {
});
}
+ jsAst.Name _disambiguateGlobalMember(MemberEntity element) {
+ return _disambiguateGlobal(element, _proposeNameForMember);
+ }
+
+ jsAst.Name _disambiguateGlobalType(Entity element) {
+ return _disambiguateGlobal(element, _proposeNameForType);
+ }
+
/// Returns the disambiguated name for a top-level or static element.
///
/// The resulting name is unique within the global-member namespace.
- jsAst.Name _disambiguateGlobal(Element element) {
+ jsAst.Name _disambiguateGlobal(
+ Entity element, String proposeName(Entity element)) {
// TODO(asgerf): We can reuse more short names if we disambiguate with
// a separate namespace for each of the global holder objects.
- element = element.declaration;
+ if (element is Element) {
+ // Ensures we only work on declarations. Non-[Element] entities do not
+ // have the declaration/implementation separation.
+ Element e = element;
+ element = e.declaration;
+ }
jsAst.Name newName = userGlobals[element];
if (newName == null) {
- String proposedName = _proposeNameForGlobal(element);
+ String proposedName = proposeName(element);
newName = getFreshName(globalScope, proposedName);
userGlobals[element] = newName;
}
@@ -1247,33 +1273,40 @@ class Namer {
return name;
}
- /**
- * Returns a proposed name for the given top-level or static element.
- * The returned id is guaranteed to be a valid JavaScript identifier.
- */
- String _proposeNameForGlobal(Element element) {
- assert(!element.isInstanceMember);
- if (element.isGenerativeConstructor) {
- return '${element.enclosingClass.name}\$${element.name}';
+ /// Returns a proposed name for the given typedef or class [element].
+ /// The returned id is guaranteed to be a valid JavaScript identifier.
+ String _proposeNameForType(Entity element) {
+ return element.name.replaceAll('+', '_');
+ }
+
+ /// Returns a proposed name for the given top-level or static member
+ /// [element]. The returned id is guaranteed to be a valid JavaScript
+ /// identifier.
+ String _proposeNameForMember(MemberEntity element) {
+ if (element.isConstructor) {
+ return _proposeNameForConstructor(element);
+ } else if (element.enclosingClass != null) {
+ ClassEntity enclosingClass = element.enclosingClass;
+ return '${enclosingClass.name}_${element.name}';
}
- if (element.isFactoryConstructor) {
+ return element.name.replaceAll('+', '_');
+ }
+
+ String _proposeNameForConstructor(ConstructorEntity element) {
+ String className = element.enclosingClass.name;
+ if (element.isGenerativeConstructor) {
+ return '${className}\$${element.name}';
+ } else {
// TODO(johnniwinther): Change factory name encoding as to not include
// the class-name twice.
- String className = element.enclosingClass.name;
- return '${className}_${Elements.reconstructConstructorName(element)}';
- }
- if (Elements.isStaticOrTopLevel(element)) {
- if (element.isClassMember) {
- ClassElement enclosingClass = element.enclosingClass;
- return '${enclosingClass.name}_${element.name}';
+ String constructorName;
+ if (element.name == '') {
+ constructorName = className;
+ } else {
+ constructorName = '${className}\$${element.name}';
}
- return element.name.replaceAll('+', '_');
+ return '${className}_${constructorName}';
}
- if (element.isLibrary) {
- LibraryElement library = element;
- return _proposeNameForLibrary(library);
- }
- return element.name;
}
/**
@@ -1356,7 +1389,7 @@ class Namer {
// The unspecialized getInterceptor method can also be accessed through
// its element, so we treat this as a user-space global instead of an
// internal global.
- return _disambiguateGlobal(getInterceptor);
+ return _disambiguateGlobalMember(getInterceptor);
}
String suffix = suffixForGetInterceptor(classes);
return _disambiguateInternalGlobal("${getInterceptor.name}\$$suffix");
@@ -1407,14 +1440,14 @@ class Namer {
// To prevent clashes in both namespaces at once, we disambiguate the name
// as a global here, and in [_sanitizeForAnnotations] we ensure that
// ordinary instance members cannot start with `$is` or `$as`.
- return _disambiguateGlobal(element);
+ return _disambiguateGlobalType(element);
}
/// Returns the disambiguated name of [class_].
///
/// This is both the *runtime type* of the class (see [runtimeTypeName])
/// and a global property name in which to store its JS constructor.
- jsAst.Name className(ClassElement class_) => _disambiguateGlobal(class_);
+ jsAst.Name className(ClassElement class_) => _disambiguateGlobalType(class_);
/// Property name on which [member] can be accessed directly,
/// without clashing with another JS property name.
@@ -1450,10 +1483,10 @@ class Namer {
///
/// The name is not necessarily unique to [method], since a static method
/// may share its name with an instance method.
- jsAst.Name methodPropertyName(Element method) {
+ jsAst.Name methodPropertyName(MethodElement method) {
return method.isInstanceMember
? instanceMethodName(method)
- : globalPropertyName(method);
+ : globalPropertyNameForMember(method);
}
/// Returns true if [element] is stored in the static state holder
@@ -1461,40 +1494,57 @@ class Namer {
/// there, whereas constants are stored in 'C'. Functions, accessors,
/// classes, etc. are stored in one of the other objects in
/// [reservedGlobalObjectNames].
- bool _isPropertyOfStaticStateHolder(Element element) {
+ bool _isPropertyOfStaticStateHolder(MemberEntity element) {
// TODO(ahe): Make sure this method's documentation is always true and
// remove the word "intend".
- return
- // TODO(ahe): Re-write these tests to be positive (so it only returns
- // true for static/top-level mutable fields). Right now, a number of
- // other elements, such as bound closures also live in
- // [staticStateHolder].
- !element.isAccessor &&
- !element.isClass &&
- !element.isTypedef &&
- !element.isConstructor &&
- !element.isFunction &&
- !element.isLibrary;
+ if (element is MemberElement) {
+ // TODO(johnniwinther): Clean up this method to have a single semantics on
+ // entities.
+ return
+ // TODO(ahe): Re-write these tests to be positive (so it only returns
+ // true for static/top-level mutable fields). Right now, a number of
+ // other elements, such as bound closures also live in
+ // [staticStateHolder].
+ !element.isAccessor &&
+ !element.isClass &&
+ !element.isTypedef &&
+ !element.isConstructor &&
+ !element.isFunction &&
+ !element.isLibrary;
+ }
+ return element.isField;
}
/// Returns [staticStateHolder] or one of [reservedGlobalObjectNames].
// TODO(johnniwinther): Verify that the implementation can be changed to
// `globalObjectForLibrary(element.library)`.
String globalObjectForMethod(MethodElement element) =>
- globalObjectFor(element);
+ globalObjectForMember(element);
/// Returns [staticStateHolder] or one of [reservedGlobalObjectNames].
- String globalObjectFor(Element element) {
+ String globalObjectForMember(MemberEntity element) {
if (_isPropertyOfStaticStateHolder(element)) return staticStateHolder;
return globalObjectForLibrary(element.library);
}
+ String globalObjectForClass(ClassEntity element) {
+ return globalObjectForLibrary(element.library);
+ }
+
+ String globalObjectForType(Entity element) {
+ if (element is TypedefElement) {
+ return globalObjectForLibrary(element.library);
+ }
+ return globalObjectForClass(element);
+ }
+
/// Returns the [reservedGlobalObjectNames] for [library].
- String globalObjectForLibrary(LibraryElement library) {
+ String globalObjectForLibrary(LibraryEntity library) {
if (library == _commonElements.interceptorsLibrary) return 'J';
- if (library.isInternalLibrary) return 'H';
- if (library.isPlatformLibrary) {
- if ('${library.canonicalUri}' == 'dart:html') return 'W';
+ Uri uri = library.canonicalUri;
+ if (uri.scheme == 'dart') {
+ if (uri.path == 'html') return 'W';
+ if (uri.path.startsWith('_')) return 'H';
return 'P';
}
return userGlobalObjects[library.name.hashCode % userGlobalObjects.length];
@@ -1505,9 +1555,9 @@ class Namer {
return new CompoundName([_literalLazyGetterPrefix, name]);
}
- jsAst.Name lazyInitializerName(Element element) {
- assert(Elements.isStaticOrTopLevelField(element));
- jsAst.Name name = _disambiguateGlobal(element);
+ jsAst.Name lazyInitializerName(FieldEntity element) {
+ assert(element.isTopLevel || element.isStatic);
+ jsAst.Name name = _disambiguateGlobalMember(element);
// These are not real dart getters, so do not use GetterName;
return deriveLazyInitializerName(name);
}
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_emitter/code_emitter_task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698