| Index: compiler/java/com/google/dart/compiler/backend/js/DollarMangler.java
|
| diff --git a/compiler/java/com/google/dart/compiler/backend/js/DollarMangler.java b/compiler/java/com/google/dart/compiler/backend/js/DollarMangler.java
|
| deleted file mode 100644
|
| index 648a0d75d74271d649caaf063a123fcbdc671ace..0000000000000000000000000000000000000000
|
| --- a/compiler/java/com/google/dart/compiler/backend/js/DollarMangler.java
|
| +++ /dev/null
|
| @@ -1,424 +0,0 @@
|
| -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -package com.google.dart.compiler.backend.js;
|
| -
|
| -import com.google.common.collect.ImmutableSet;
|
| -import com.google.dart.compiler.InternalCompilerException;
|
| -import com.google.dart.compiler.ast.LibraryUnit;
|
| -import com.google.dart.compiler.parser.Token;
|
| -import com.google.dart.compiler.resolver.ClassElement;
|
| -import com.google.dart.compiler.resolver.Element;
|
| -import com.google.dart.compiler.resolver.ElementKind;
|
| -import com.google.dart.compiler.resolver.FieldElement;
|
| -import com.google.dart.compiler.resolver.LibraryElement;
|
| -import com.google.dart.compiler.resolver.MethodElement;
|
| -
|
| -import java.security.MessageDigest;
|
| -import java.security.NoSuchAlgorithmException;
|
| -import java.util.Set;
|
| -
|
| -/**
|
| - * Mangles classes and members (including constructors and operators).
|
| - * These must be accessible from outside the compilation unit and must therefore have a
|
| - * predictable mangling.
|
| - *
|
| - * <p>Functions, constructors and initializers to become top-level functions. They
|
| - * cannot conflict with other members, but must not conflict with predefined JavaScript globals.
|
| - *
|
| - * <p>Other members (fields, operators, methods) are always accessed through an object. The mangler
|
| - * only needs to guard against conflicts with predefined JavaScript properties (like "prototype"
|
| - * and "__proto__").
|
| - */
|
| -public class DollarMangler implements DartMangler {
|
| - // TODO(floitsch): get rid of the blacklisted libraries.
|
| - // Libraries, where class-names must not include the library-name.
|
| - private static final Set<String> BLACKLISTED_LIBRARIES = ImmutableSet.<String>of("corelib",
|
| - "corelib_impl", "dom");
|
| -
|
| - // Helpers for getters/setters/operator name mangling.
|
| - private static final String OPERATOR_SUFFIX = "$operator";
|
| - private static final String GETTER_SUFFIX = "$getter";
|
| - private static final String SETTER_SUFFIX = "$setter";
|
| - private static final String FIELD_SUFFIX = "$field";
|
| - private static final String METHOD_SUFFIX = "$member";
|
| - private static final String NAMED_SUFFIX = "$named";
|
| - private static final String CONSTRUCTOR_SUFFIX = "$Constructor";
|
| - private static final String FACTORY_SUFFIX = "$Factory";
|
| - private static final String INITIALIZER_SUFFIX = "$Initializer";
|
| -
|
| - private static final String CLASS_SUFFIX = "$Dart";
|
| - private static final String HOISTED_METHOD_SUFFIX = "$Hoisted";
|
| - private static final String HOISTED_OPERATOR_SUFFIX = "$HoistedOperator";
|
| - private static final String HOISTED_CONSTRUCTOR_SUFFIX = "$HoistedConstructor";
|
| - private static final String HOISTED_STATIC_SUFFIX = "$HoistedStatic";
|
| - private static final String DYNAMIC_CLASS_NAME = "$_Dynamic_";
|
| - private static final String RTT_LOOKUP_NAME = "_$lookupRTT";
|
| -
|
| - private static final String NATIVE_PREFIX = "native_";
|
| -
|
| - private boolean isLibraryPrivate(String id) {
|
| - return (id.length() > 0) && (id.charAt(0) == '_');
|
| - }
|
| -
|
| - private String attachSuffix(String name, String suffix,
|
| - boolean isLibraryPrivate, LibraryElement currentLibrary) {
|
| - if (isLibraryPrivate) {
|
| - return name + '$' + mangleLibraryName(currentLibrary) + suffix + '_';
|
| - }
|
| - return name + suffix;
|
| - }
|
| -
|
| - private String attachSuffix(String name, String suffix, LibraryElement currentLibrary) {
|
| - return attachSuffix(name, suffix, isLibraryPrivate(name), currentLibrary);
|
| - }
|
| -
|
| - private String mangleLibraryName(LibraryElement element) {
|
| - LibraryUnit library = element.getLibraryUnit();
|
| - if (isInBlacklist(library)) {
|
| - return "";
|
| - }
|
| -
|
| - // TODO(floitsch): Replace this libraryName + md5(source) with something more enhanced.
|
| -
|
| - String libName = library.getName();
|
| - if (libName == null || libName.isEmpty()) {
|
| - libName = "unnamed";
|
| - }
|
| -
|
| - // If the libraryName is a path, cut off everything before the last slash.
|
| - int nameStart = libName.lastIndexOf('/') + 1;
|
| -
|
| - // add space for md5 + trailing '$' (and possible leading 'l').
|
| - StringBuilder sb = new StringBuilder(libName.length() + 8);
|
| -
|
| - // see if we have a leading number, in which case need to prepend an alpha char
|
| - final char startChar = libName.charAt(nameStart);
|
| - if ('0' <= startChar && startChar <= '9') {
|
| - sb.append('l');
|
| - }
|
| - sb.append(libName.substring(nameStart));
|
| -
|
| - // Replace all non-word chars ([^a-z_A-Z0-9]) with "_".
|
| - replaceNonWordChars(sb);
|
| -
|
| - MessageDigest md;
|
| - try {
|
| - md = MessageDigest.getInstance("MD5");
|
| - } catch (NoSuchAlgorithmException e) {
|
| - throw new AssertionError("Could not find MD5 digest");
|
| - }
|
| - byte[] md5 = md.digest(library.getSource().getUri().toString().getBytes());
|
| - // Only use the first 6 hex characters of the md5.
|
| - for (int i = 0; i < 3; i++) {
|
| - sb.append(Integer.toHexString((md5[i] & 0xf0) >> 4));
|
| - sb.append(Integer.toHexString(md5[i] & 0xf));
|
| - }
|
| -
|
| - sb.append("$");
|
| -
|
| - return sb.toString();
|
| - }
|
| -
|
| - /*
|
| - * Replace all non-word characters with an underscore
|
| - */
|
| - private void replaceNonWordChars(StringBuilder sb) {
|
| - /*
|
| - * This code is implemented as a more efficient implementation than using
|
| - * String.replaceAll("\\W", "_")
|
| - */
|
| - final int len = sb.length();
|
| - for (int idx = 0; idx < len; idx++) {
|
| - final char ch = sb.charAt(idx);
|
| - if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9'))) {
|
| - sb.setCharAt(idx, '_');
|
| - }
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public String mangleClassName(ClassElement classElement) {
|
| - String className = !classElement.isDynamic() ? classElement.getName() : DYNAMIC_CLASS_NAME;
|
| - return mangleClassNameHack(classElement.getLibrary(), className);
|
| - }
|
| -
|
| - @Override
|
| - @Deprecated
|
| - public String mangleClassNameHack(LibraryElement library, String className) {
|
| - String libraryToken = library == null ? "" : mangleLibraryName(library);
|
| - return libraryToken + className + CLASS_SUFFIX;
|
| - }
|
| -
|
| - private boolean isInBlacklist(LibraryUnit libraryUnit) {
|
| - if (libraryUnit.getName() == null) {
|
| - return false;
|
| - }
|
| - if (BLACKLISTED_LIBRARIES.contains(libraryUnit.getName())) {
|
| - return true;
|
| - }
|
| -
|
| - // Libraries that use the new syntax (with no name) will have a URI for a name, e.g.:
|
| - // file://blah/blah/coreimpl.dart
|
| - for (String name : BLACKLISTED_LIBRARIES) {
|
| - if (libraryUnit.getName().endsWith(name)) {
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - @Override
|
| - public String mangleConstructor(String constructorName, LibraryElement currentLibrary) {
|
| - return attachSuffix(constructorName, CONSTRUCTOR_SUFFIX, currentLibrary);
|
| - }
|
| -
|
| - @Override
|
| - public String createInitializerSyntax(String constructorName, LibraryElement currentLibrary) {
|
| - return attachSuffix(constructorName, INITIALIZER_SUFFIX, currentLibrary);
|
| - }
|
| -
|
| - @Override
|
| - public String createFactorySyntax(String className, String constructor,
|
| - LibraryElement currentLibrary) {
|
| - // We can't just return the constructor + suffix.
|
| - // A class might have factories for different classes.
|
| - String factoryName;
|
| - className = className.equals("<dynamic>") ? DYNAMIC_CLASS_NAME : className;
|
| - if (constructor.equals("")) {
|
| - factoryName = className + "$";
|
| - } else {
|
| - factoryName = className + "$" + constructor + "$" + className.length();
|
| - }
|
| -
|
| - return attachSuffix(factoryName, FACTORY_SUFFIX, isLibraryPrivate(constructor), currentLibrary);
|
| - }
|
| -
|
| - private boolean containsDollar(String str) {
|
| - return str.indexOf('$') >= 0;
|
| - }
|
| -
|
| - private String createHoistedFunctionName(String holderName,
|
| - String elementName,
|
| - String closureIdentifier,
|
| - String closureName,
|
| - String suffix) {
|
| - assert closureIdentifier.indexOf('$') == -1;
|
| - boolean containsDollar = containsDollar(holderName)
|
| - || containsDollar(elementName)
|
| - || (closureName != null && containsDollar(closureName));
|
| - String result;
|
| - if (closureName != null) {
|
| - // Return a mangled id of the form:
|
| - // class$method$id$closure$$Hoisted, or
|
| - // class$method$id$closure$12_23_45$Hoisted (if any of the strings contains dollars).
|
| - result = holderName + "$" + elementName + "$" + closureIdentifier + "$" + closureName + "$";
|
| - if (containsDollar) {
|
| - result += holderName.length() + "_" + elementName.length() + "_"
|
| - + closureIdentifier.length();
|
| - }
|
| - } else {
|
| - // Return a mangled id of the form:
|
| - // class$method$id$$Hoisted, or
|
| - // class$method$id$12_23$Hoisted (if any of the strings contains dollars).
|
| - result = holderName + "$" + elementName + "$" + closureIdentifier + "$";
|
| - if (containsDollar) {
|
| - result += holderName.length() + "_" + holderName.length();
|
| - }
|
| - }
|
| - return result + suffix;
|
| - }
|
| -
|
| - @Override
|
| - public String createHoistedFunctionName(Element holder,
|
| - Element element,
|
| - String closureIdentifier,
|
| - String closureName) {
|
| - String holderName = "";
|
| - switch (ElementKind.of(holder)) {
|
| - case CLASS:
|
| - holderName = mangleClassName((ClassElement) holder);
|
| - break;
|
| -
|
| - case LIBRARY:
|
| - holderName = mangleLibraryName((LibraryElement) holder);
|
| - break;
|
| - }
|
| -
|
| - String name = element.getName();
|
| - String suffix;
|
| - switch (ElementKind.of(element)) {
|
| - case METHOD:
|
| - if (element.getModifiers().isOperator()) {
|
| - suffix = HOISTED_OPERATOR_SUFFIX;
|
| - if (!name.equals(NEGATE_OPERATOR_NAME)) {
|
| - name = Token.lookup(name).name();
|
| - }
|
| - } else {
|
| - suffix = HOISTED_METHOD_SUFFIX;
|
| - }
|
| - break;
|
| -
|
| - case CONSTRUCTOR:
|
| - suffix = HOISTED_CONSTRUCTOR_SUFFIX;
|
| - break;
|
| -
|
| - default:
|
| - // Otherwise we are in a static initializer.
|
| - suffix = HOISTED_STATIC_SUFFIX;
|
| - }
|
| - return createHoistedFunctionName(holderName, name, closureIdentifier, closureName,
|
| - suffix);
|
| - }
|
| -
|
| - private String createFieldOrMethodBaseName(Element field, boolean accessor) {
|
| - String prefix = "";
|
| - Element enclosing = field.getEnclosingElement();
|
| - if (ElementKind.of(enclosing).equals(ElementKind.LIBRARY)) {
|
| - prefix = mangleLibraryName((LibraryElement) enclosing);
|
| - } else if (!accessor && field.getModifiers().isStatic()) {
|
| - prefix = mangleClassName((ClassElement) enclosing);
|
| - }
|
| - return prefix + field.getName();
|
| - }
|
| -
|
| - @Override
|
| - public String mangleField(FieldElement field, LibraryElement currentLibrary) {
|
| - return attachSuffix(createFieldOrMethodBaseName(field, false), FIELD_SUFFIX,
|
| - isLibraryPrivate(field.getName()), currentLibrary);
|
| - }
|
| -
|
| - @Override
|
| - public String mangleMethod(MethodElement method, LibraryElement currentLibrary) {
|
| - String methodName = method.getName();
|
| - if (method.getModifiers().isOperator()) {
|
| - methodName = createOperatorSyntax(methodName);
|
| - } else if (method.getModifiers().isGetter()) {
|
| - methodName = createGetterSyntax(methodName, currentLibrary);
|
| - } else if (method.getModifiers().isSetter()) {
|
| - methodName = createSetterSyntax(methodName, currentLibrary);
|
| - } else {
|
| - methodName = attachSuffix(methodName, METHOD_SUFFIX, currentLibrary);
|
| - }
|
| -
|
| - String prefix = "";
|
| - if (ElementKind.of(method.getEnclosingElement()).equals(ElementKind.LIBRARY)) {
|
| - prefix = mangleLibraryName((LibraryElement) method.getEnclosingElement());
|
| - }
|
| - return prefix + methodName;
|
| - }
|
| -
|
| - @Override
|
| - public String mangleNamedMethod(MethodElement method, LibraryElement currentLibrary) {
|
| - // There can be no named shims for operators, getters, or setters.
|
| - String methodName = method.getName();
|
| - methodName = attachSuffix(methodName, NAMED_SUFFIX, currentLibrary);
|
| -
|
| - String prefix = "";
|
| - if (ElementKind.of(method.getEnclosingElement()).equals(ElementKind.LIBRARY)) {
|
| - prefix = mangleLibraryName((LibraryElement) method.getEnclosingElement());
|
| - }
|
| - return prefix + methodName;
|
| - }
|
| -
|
| - @Override
|
| - public String mangleNamedMethod(String methodName, LibraryElement currentLibrary) {
|
| - return attachSuffix(methodName, NAMED_SUFFIX, currentLibrary);
|
| - }
|
| -
|
| - @Override
|
| - public String mangleEntryPoint(MethodElement method, LibraryElement library) {
|
| - Element holder = method.getEnclosingElement();
|
| - switch (ElementKind.of(holder)) {
|
| - case CLASS:
|
| - String mangledClassName = mangleClassName((ClassElement) holder);
|
| - return mangledClassName + "." + mangleMethod(method.getName(), library);
|
| -
|
| - case LIBRARY:
|
| - return mangleMethod(method, library);
|
| - }
|
| - throw new InternalCompilerException("Unknown entry point kind" + method);
|
| - }
|
| -
|
| - @Override
|
| - public String createGetterSyntax(FieldElement field, LibraryElement currentLibrary) {
|
| - return attachSuffix(createFieldOrMethodBaseName(field, true), GETTER_SUFFIX,
|
| - isLibraryPrivate(field.getName()), currentLibrary);
|
| - }
|
| -
|
| - @Override
|
| - public String createGetterSyntax(MethodElement field, LibraryElement currentLibrary) {
|
| - return attachSuffix(createFieldOrMethodBaseName(field, true), GETTER_SUFFIX,
|
| - isLibraryPrivate(field.getName()), currentLibrary);
|
| - }
|
| -
|
| - @Override
|
| - public String createSetterSyntax(FieldElement field, LibraryElement currentLibrary) {
|
| - return attachSuffix(createFieldOrMethodBaseName(field, true), SETTER_SUFFIX,
|
| - isLibraryPrivate(field.getName()), currentLibrary);
|
| - }
|
| -
|
| - @Override
|
| - public String mangleMethod(String methodName, LibraryElement currentLibrary) {
|
| - return attachSuffix(methodName, METHOD_SUFFIX, currentLibrary);
|
| - }
|
| -
|
| - private static String getNegateOperator() {
|
| - return NEGATE_OPERATOR_NAME + OPERATOR_SUFFIX;
|
| - }
|
| -
|
| - @Override
|
| - public String createOperatorSyntax(Token token) {
|
| - return token.name() + OPERATOR_SUFFIX;
|
| - }
|
| -
|
| - @Override
|
| - public String createOperatorSyntax(String operation) {
|
| - if (operation.equals(NEGATE_OPERATOR_NAME)) {
|
| - return getNegateOperator();
|
| - }
|
| - return Token.lookup(operation).name() + OPERATOR_SUFFIX;
|
| - }
|
| -
|
| - @Override
|
| - public String createGetterSyntax(String member, LibraryElement currentLibrary) {
|
| - return attachSuffix(member, GETTER_SUFFIX, currentLibrary);
|
| - }
|
| -
|
| - @Override
|
| - public String createSetterSyntax(String member, LibraryElement currentLibrary) {
|
| - return attachSuffix(member, SETTER_SUFFIX, currentLibrary);
|
| - }
|
| -
|
| - @Override
|
| - public String mangleNativeMethod(MethodElement element) {
|
| - String elementName = element.getName();
|
| - String encodedName = null;
|
| - if (element.getModifiers().isOperator()) {
|
| - if ("negate".equals(elementName)) {
|
| - encodedName = elementName;
|
| - } else {
|
| - encodedName = Token.lookup(elementName).name();
|
| - }
|
| - } else if (element.getModifiers().isGetter()) {
|
| - encodedName = "get$" + elementName;
|
| - } else if (element.getModifiers().isSetter()) {
|
| - encodedName = "set$" + elementName;
|
| - } else {
|
| - encodedName = elementName;
|
| - }
|
| - String holderName = element.getEnclosingElement().getName();
|
| - return NATIVE_PREFIX + holderName + "_" + encodedName;
|
| - }
|
| -
|
| - @Override
|
| - public String mangleRttLookupMethod(MethodElement method, LibraryElement currentLibrary) {
|
| - return mangleNamedMethod(method, currentLibrary) + RTT_LOOKUP_NAME;
|
| - }
|
| -
|
| - @Override
|
| - public String mangleRttLookupMethod(String methodName, LibraryElement currentLibrary) {
|
| - return mangleNamedMethod(methodName, currentLibrary) + RTT_LOOKUP_NAME;
|
| - }
|
| -}
|
|
|