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

Unified Diff: sdk/lib/_internal/compiler/implementation/js_backend/namer.dart

Issue 68203020: Reapply "Fix issues with field names by ensuring that fields have exactly one name regardless of ho… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 1 month 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: sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index e22454b9d7c423ac28d4d59d52eb8d5cb9bf1733..40209b2a5a7f18aef579d46ba40e63c194ed3fc5 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -226,6 +226,9 @@ class Namer implements ClosureNamer {
// Name of property in a class description for the native dispatch metadata.
final String nativeSpecProperty = '%';
+ static final RegExp IDENTIFIER = new RegExp(r'^[A-Za-z_$][A-Za-z0-9_$]*$');
+ static final RegExp NON_IDENTIFIER_CHAR = new RegExp(r'[^A-Za-z_0-9$]');
+
/**
* Map from top-level or static elements to their unique identifiers provided
* by [getName].
@@ -440,29 +443,64 @@ class Namer implements ClosureNamer {
String invocationMirrorInternalName(Selector selector)
=> invocationName(selector);
- String instanceFieldName(Element element) {
+ /**
+ * Returns name of accessor (root to getter and setter) for a static or
+ * instance field.
+ */
+ String fieldAccessorName(Element element) {
+ return element.isInstanceMember()
+ ? instanceFieldAccessorName(element)
+ : getNameOfField(element);
+ }
+
+ /**
+ * Returns name of the JavaScript property used to store a static or instance
+ * field.
+ */
+ String fieldPropertyName(Element element) {
+ return element.isInstanceMember()
+ ? instanceFieldPropertyName(element)
+ : getNameOfField(element);
+ }
+
+ /**
+ * Returns name of accessor (root to getter and setter) for an instance field.
+ */
+ String instanceFieldAccessorName(Element element) {
String proposedName = privateName(element.getLibrary(), element.name);
return getMappedInstanceName(proposedName);
}
- // Construct a new name for the element based on the library and class it is
- // in. The name here is not important, we just need to make sure it is
- // unique. If we are minifying, we actually construct the name from the
- // minified versions of the class and instance names, but the result is
- // minified once again, so that is not visible in the end result.
- String shadowedFieldName(Element fieldElement) {
- // Check for following situation: Native field ${fieldElement.name} has
- // fixed JSName ${fieldElement.nativeName()}, but a subclass shadows this
- // name. We normally handle that by renaming the superclass field, but we
- // can't do that because native fields have fixed JavaScript names.
- // In practice this can't happen because we can't inherit from native
- // classes.
- assert (!fieldElement.hasFixedBackendName());
+ /**
+ * Returns name of the JavaScript property used to store an instance field.
+ */
+ String instanceFieldPropertyName(Element element) {
+ if (element.hasFixedBackendName()) {
+ return element.fixedBackendName();
+ }
+ // If a class is used anywhere as a mixin, we must make the name unique so
+ // that it does not accidentally shadow. Also, the mixin name must be
+ // constant over all mixins.
+ if (compiler.world.isUsedAsMixin(element.getEnclosingClass()) ||
+ shadowingAnotherField(element)) {
+ // Construct a new name for the element based on the library and class it
+ // is in. The name here is not important, we just need to make sure it is
+ // unique. If we are minifying, we actually construct the name from the
+ // minified version of the class name, but the result is minified once
+ // again, so that is not visible in the end result.
+ String libraryName = getNameOfLibrary(element.getLibrary());
+ String className = getNameOfClass(element.getEnclosingClass());
+ String instanceName = privateName(element.getLibrary(), element.name);
+ return getMappedInstanceName('$libraryName\$$className\$$instanceName');
+ }
- String libraryName = getNameOfLibrary(fieldElement.getLibrary());
- String className = getNameOfClass(fieldElement.getEnclosingClass());
- String instanceName = instanceFieldName(fieldElement);
- return getMappedInstanceName('$libraryName\$$className\$$instanceName');
+ String proposedName = privateName(element.getLibrary(), element.name);
+ return getMappedInstanceName(proposedName);
+ }
+
+
+ bool shadowingAnotherField(Element element) {
+ return element.getEnclosingClass().hasFieldShadowedBy(element);
}
String setterName(Element element) {
@@ -592,6 +630,15 @@ class Namer implements ClosureNamer {
? name.substring(name.lastIndexOf('.') + 1)
: name.substring(0, name.indexOf('.'));
}
+ // The filename based name can contain all kinds of nasty characters. Make
+ // sure it is an identifier.
+ if (!IDENTIFIER.hasMatch(name)) {
+ name = name.replaceAllMapped(NON_IDENTIFIER_CHAR,
+ (match) => match[0].codeUnitAt(0).toRadixString(16));
+ if (!IDENTIFIER.hasMatch(name)) { // e.g. starts with digit.
+ name = 'lib_$name';
+ }
+ }
} else {
name = element.name;
}
@@ -718,7 +765,9 @@ class Namer implements ClosureNamer {
} else if (element.kind == ElementKind.SETTER) {
return setterName(element);
} else if (element.kind == ElementKind.FIELD) {
- return instanceFieldName(element);
+ compiler.internalError(
+ 'use instanceFieldPropertyName or instanceFieldAccessorName',
+ node: element.parseNode(compiler));
} else {
compiler.internalError('getName for bad kind: ${element.kind}',
node: element.parseNode(compiler));

Powered by Google App Engine
This is Rietveld 408576698