Index: sdk/lib/_internal/compiler/implementation/mirror_renamer/renamer.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/mirror_renamer/renamer.dart b/sdk/lib/_internal/compiler/implementation/mirror_renamer/renamer.dart |
index 003dda44768370e4daaa8994d6ab2ca587f32386..5be6d776072731d0d87bdde2e1d6208966279f7a 100644 |
--- a/sdk/lib/_internal/compiler/implementation/mirror_renamer/renamer.dart |
+++ b/sdk/lib/_internal/compiler/implementation/mirror_renamer/renamer.dart |
@@ -5,28 +5,87 @@ |
part of mirror_renamer; |
class MirrorRenamer { |
- static const String MIRROR_HELPER_CLASS = 'MirrorHelper'; |
- static const String MIRROR_HELPER_GET_NAME_FUNCTION = 'getName'; |
- static const String MIRROR_HELPER_LIBRARY_NAME = 'mirror_helper.dart'; |
- static const String MIRROR_HELPER_LIBRARY_PREFIX = 'm'; |
- static const String MIRROR_HELPER_CLASS_FULLY_QUALIFIED_NAME = |
- '$MIRROR_HELPER_LIBRARY_PREFIX.$MIRROR_HELPER_CLASS'; |
- |
- static void handleStaticSend(Map<Node, String> renames, Element element, |
- Send node, Compiler compiler) { |
+ static const String MIRROR_HELPER_GET_NAME_FUNCTION = 'helperGetName'; |
+ static const String MIRROR_HELPER_LIBRARY_NAME = '_mirror_helper'; |
+ static const String MIRROR_HELPER_SYMBOLS_MAP_NAME = '_SYMBOLS'; |
+ |
+ /// Maps mangled name to original name. |
+ Map<String, SourceString> symbols = new Map<String, SourceString>(); |
+ /// Contains all occurrencs of MirrorSystem.getName() calls in the user code. |
+ List<Node> mirrorSystemGetNameNodes = <Node>[]; |
+ /** |
+ * Initialized when the placeholderCollector collects the FunctionElement |
+ * backend.mirrorHelperGetNameFunction which represents the helperGetName |
+ * function in _mirror_helper. |
+ */ |
+ FunctionExpression mirrorHelperGetNameFunctionNode; |
+ VariableDefinitions mirrorHelperSymbolsMapNode; |
+ Compiler compiler; |
+ DartBackend backend; |
+ |
+ MirrorRenamer(this.compiler, this.backend); |
+ |
+ void registerStaticSend(Element element, Send node) { |
if (element == compiler.mirrorSystemGetNameFunction) { |
- renames[node.selector] = MIRROR_HELPER_GET_NAME_FUNCTION; |
- renames[node.receiver] = MIRROR_HELPER_CLASS_FULLY_QUALIFIED_NAME; |
- } |
+ mirrorSystemGetNameNodes.add(node); |
+ } |
} |
- static void addMirrorHelperImport(Map<LibraryElement, String> imports) { |
- Uri mirrorHelperUri = new Uri(path: MIRROR_HELPER_LIBRARY_NAME); |
- // TODO(zarah): Remove this hack! LibraryElementX should not be created |
- // outside the library loader. When actual mirror helper library |
- // is created, change to load that. |
- LibraryElement mirrorHelperLib = new LibraryElementX( |
- new Script(mirrorHelperUri, null)); |
- imports.putIfAbsent(mirrorHelperLib, () => MIRROR_HELPER_LIBRARY_PREFIX); |
+ void registerHelperElement(Element element, Node node) { |
+ if (element == backend.mirrorHelperGetNameFunction) { |
+ mirrorHelperGetNameFunctionNode = node; |
+ } else if (element == backend.mirrorHelperSymbolsMap) { |
+ mirrorHelperSymbolsMapNode = node; |
+ } |
+ } |
+ |
+ /** |
+ * Adds a toplevel node to the output containing a map from the mangled |
+ * to the unmangled names and replaces calls to MirrorSystem.getName() |
+ * with calls to the corresponding wrapper from _mirror_helper which has |
+ * been added during resolution. [renames] is assumed to map nodes in user |
+ * code to mangled names appearing in output code, and [topLevelNodes] should |
+ * contain all the toplevel ast nodes that will be emitted in the output. |
+ */ |
+ void addRenames(Map<Node, String> renames, List<Node> topLevelNodes) { |
+ |
+ Node parse(String text) { |
+ Token tokens = compiler.scanner.tokenize(text); |
+ return compiler.parser.parseCompilationUnit(tokens); |
+ } |
+ |
+ // Add toplevel map containing all renames. |
+ symbols = new Map<String, SourceString>(); |
+ for (Node node in renames.keys) { |
+ Identifier identifier = node.asIdentifier(); |
+ if (identifier != null) { |
+ symbols.putIfAbsent(renames[node], () => identifier.source); |
+ } |
+ } |
+ |
+ Identifier symbolsMapIdentifier = |
+ mirrorHelperSymbolsMapNode.definitions.nodes.head.asSend().selector; |
+ assert(symbolsMapIdentifier != null); |
+ topLevelNodes.remove(mirrorHelperSymbolsMapNode); |
+ |
+ StringBuffer sb = new StringBuffer( |
+ 'const ${renames[symbolsMapIdentifier]} = const<String,SourceString>{'); |
+ bool first = true; |
+ for (String mangledName in symbols.keys) { |
+ if (!first) { |
+ sb.write(','); |
+ } else { |
+ first = false; |
+ } |
+ sb.write("'$mangledName' : '${symbols[mangledName]}'"); |
+ } |
+ sb.write('};'); |
+ topLevelNodes.add(parse(sb.toString())); |
+ |
+ // Replace calls to Mirrorsystem.getName with calls to helper function. |
+ mirrorSystemGetNameNodes.forEach((node) { |
+ renames[node.selector] = renames[mirrorHelperGetNameFunctionNode.name]; |
+ renames[node.receiver] = ''; |
+ }); |
} |
-} |
+} |