| 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] = '';
|
| + });
|
| }
|
| -}
|
| +}
|
|
|