Chromium Code Reviews| 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..1b9d9b7b98f456af00d2bc044b5cc07da38f5913 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/mirror_renamer/renamer.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/mirror_renamer/renamer.dart |
| @@ -5,28 +5,86 @@ |
| 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 = |
|
Johnni Winther
2013/08/26 07:38:27
Assert that [symbolsMapIdentifer] is not null.
zarah
2013/08/28 10:19:03
Done.
|
| + mirrorHelperSymbolsMapNode.definitions.nodes.head.asSend().selector; |
| + 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] = ''; |
| + }); |
| } |
| -} |
| +} |