Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart._js_names; | 5 library dart._js_names; |
| 6 | 6 |
| 7 import 'dart:_js_embedded_names' show | 7 import 'dart:_js_embedded_names' show |
| 8 MANGLED_GLOBAL_NAMES, | 8 MANGLED_GLOBAL_NAMES, |
| 9 MANGLED_NAMES; | 9 MANGLED_NAMES; |
| 10 | 10 |
| 11 import 'dart:_foreign_helper' show | 11 import 'dart:_foreign_helper' show |
| 12 JS, | 12 JS, |
| 13 JS_EMBEDDED_GLOBAL, | 13 JS_EMBEDDED_GLOBAL, |
| 14 JS_GET_NAME; | 14 JS_GET_NAME; |
| 15 | 15 |
| 16 import 'dart:_js_helper' show | 16 import 'dart:_js_helper' show |
| 17 JsCache, | 17 JsCache, |
| 18 NoInline; | 18 NoInline; |
| 19 | 19 |
| 20 import 'dart:_interceptors' show JSArray; | 20 import 'dart:_interceptors' show JSArray; |
| 21 | 21 |
| 22 /// No-op method that is called to inform the compiler that unmangled named | 22 /// No-op method that is called to inform the compiler that unmangled named |
| 23 /// must be preserved. | 23 /// must be preserved. |
| 24 preserveNames() {} | 24 preserveNames() {} |
| 25 | 25 |
| 26 /// A map from mangled names to "reflective" names, that is, unmangled names | 26 /// A map from mangled names to "reflective" names, that is, unmangled names |
| 27 /// with some additional information, such as, number of required arguments. | 27 /// with some additional information, such as, number of required arguments. |
| 28 /// This map is for mangled names used as instance members. | 28 /// This map is for mangled names used as instance members. |
| 29 final Map<String, String> mangledNames = | 29 final _LazyMangledNamesMap mangledNames = new _LazyMangledInstanceNamesMap( |
| 30 computeMangledNames( | 30 JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES)); |
| 31 JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES), | |
| 32 false); | |
| 33 | 31 |
| 34 /// A map from "reflective" names to mangled names (the reverse of | 32 /// A map from "reflective" names to mangled names (the reverse of |
| 35 /// [mangledNames]). | 33 /// [mangledNames]). |
| 36 final Map<String, String> reflectiveNames = | 34 final _LazyReflectiveNamesMap reflectiveNames = |
| 37 computeReflectiveNames(mangledNames); | 35 new _LazyReflectiveNamesMap(JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES), |
| 36 true); | |
| 38 | 37 |
| 39 /// A map from mangled names to "reflective" names (see [mangledNames]). This | 38 /// A map from mangled names to "reflective" names (see [mangledNames]). This |
| 40 /// map is for globals, that is, static and top-level members. | 39 /// map is for globals, that is, static and top-level members. |
| 41 final Map<String, String> mangledGlobalNames = computeMangledNames( | 40 final _LazyMangledNamesMap mangledGlobalNames = new _LazyMangledNamesMap( |
| 42 JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES), | 41 JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES)); |
| 43 true); | |
| 44 | 42 |
| 45 /// A map from "reflective" names to mangled names (the reverse of | 43 /// A map from "reflective" names to mangled names (the reverse of |
| 46 /// [mangledGlobalNames]). | 44 /// [mangledGlobalNames]). |
| 47 final Map<String, String> reflectiveGlobalNames = | 45 final _LazyReflectiveNamesMap reflectiveGlobalNames = |
| 48 computeReflectiveNames(mangledGlobalNames); | 46 new _LazyReflectiveNamesMap( |
| 47 JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES), false); | |
| 49 | 48 |
| 50 /// [jsMangledNames] is a JavaScript object literal. The keys are the mangled | 49 /// [jsMangledNames] is a JavaScript object literal. The keys are the mangled |
| 51 /// names, and the values are the "reflective" names. | 50 /// names, and the values are the "reflective" names. |
| 52 Map<String, String> computeMangledNames(jsMangledNames, bool isGlobal) { | 51 class _LazyMangledNamesMap { |
| 53 preserveNames(); | 52 var _jsMangledNames; |
| 54 var keys = extractKeys(jsMangledNames); | 53 |
| 55 var result = <String, String>{}; | 54 _LazyMangledNamesMap(this._jsMangledNames); |
| 56 String getterPrefix = JS_GET_NAME('GETTER_PREFIX'); | 55 |
| 57 int getterPrefixLength = getterPrefix.length; | 56 String operator[](String key) { |
| 58 String setterPrefix = JS_GET_NAME('SETTER_PREFIX'); | 57 String result = JS('var', '#[#]', _jsMangledNames, key); |
| 59 for (String key in keys) { | 58 // Filter out all non-string values to protect against polution from |
| 60 String value = JS('String', '#[#]', jsMangledNames, key); | 59 // anciliary fields in [_jsMangledNames]. |
| 61 result[key] = value; | 60 bool filter = |
| 62 if (!isGlobal) { | 61 JS('bool', '# == null || typeof # !== "string"', result, result); |
|
sra1
2015/03/05 18:23:25
typeof is sufficient
herhut
2015/03/06 12:36:45
True, thanks!
| |
| 63 if (key.startsWith(getterPrefix)) { | 62 return filter ? null : result; |
| 64 result['$setterPrefix${key.substring(getterPrefixLength)}'] = '$value='; | 63 } |
| 64 } | |
| 65 | |
| 66 class _LazyMangledInstanceNamesMap extends _LazyMangledNamesMap { | |
| 67 _LazyMangledInstanceNamesMap(_jsMangledNames) : super(_jsMangledNames); | |
| 68 | |
| 69 String operator[](String key) { | |
| 70 var result = super[key]; | |
|
floitsch
2015/03/06 14:54:10
Use type.
herhut
2015/03/09 14:28:35
Done.
| |
| 71 String setterPrefix = JS_GET_NAME('SETTER_PREFIX'); | |
| 72 if (result == null && key.startsWith(setterPrefix)) { | |
|
floitsch
2015/03/06 14:54:10
Isn't this handled by the "_updateReflectiveNames
herhut
2015/03/09 14:28:35
_updateReflectiveNames is the inverse mapping. Thi
floitsch
2015/03/09 16:35:06
Explain in a comment.
| |
| 73 String getterPrefix = JS_GET_NAME('GETTER_PREFIX'); | |
| 74 int setterPrefixLength = getterPrefix.length; | |
|
floitsch
2015/03/09 16:35:06
getterPrefixLength
| |
| 75 | |
| 76 // Generate the setter name from the getter name. | |
| 77 key = '$getterPrefix${key.substring(setterPrefixLength)}'; | |
| 78 result = super[key]; | |
| 79 return (result != null) ? "${result}=" : null; | |
|
floitsch
2015/03/06 14:54:10
You don't need the curly braces.
herhut
2015/03/09 14:28:35
I actually find this easier to read. Unless you re
| |
| 80 } | |
| 81 return result; | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 class _LazyReflectiveNamesMap { | |
| 86 final _jsMangledNames; | |
| 87 final bool _isInstance; | |
| 88 var _cacheLength = 0; | |
|
floitsch
2015/03/06 14:54:10
types.
herhut
2015/03/09 14:28:35
Done.
| |
| 89 var _cache; | |
| 90 | |
| 91 _LazyReflectiveNamesMap(this._jsMangledNames, this._isInstance); | |
| 92 | |
| 93 Map<String, String> _updateReflectiveNames() { | |
| 94 preserveNames(); | |
| 95 var result = <String, String>{}; | |
|
floitsch
2015/03/06 14:54:10
Use types.
herhut
2015/03/09 14:28:35
Done.
| |
| 96 var keys = JS('List', 'Object.keys(#)', _jsMangledNames); | |
| 97 for (String key in keys) { | |
| 98 var reflectiveName = JS('var', '#[#]', _jsMangledNames, key); | |
| 99 // Filter out all non-string values to protect against polution from | |
| 100 // anciliary fields in [_jsMangledNames]. | |
| 101 bool filter = JS('bool', '# == null || typeof # !== "string"', | |
| 102 reflectiveName, reflectiveName); | |
| 103 if (filter) continue; | |
| 104 result[reflectiveName] = key; | |
| 105 | |
| 106 String getterPrefix = JS_GET_NAME('GETTER_PREFIX'); | |
| 107 if (_isInstance && key.startsWith(getterPrefix)) { | |
| 108 int getterPrefixLength = getterPrefix.length; | |
| 109 String setterPrefix = JS_GET_NAME('SETTER_PREFIX'); | |
| 110 result['$reflectiveName='] = | |
| 111 '$setterPrefix${key.substring(getterPrefixLength)}'; | |
| 65 } | 112 } |
| 66 } | 113 } |
| 114 return result; | |
| 67 } | 115 } |
| 68 return result; | |
| 69 } | |
| 70 | 116 |
| 71 Map<String, String> computeReflectiveNames(Map<String, String> map) { | 117 int get _jsMangledNamesLength => JS('int', '#.length', _jsMangledNames); |
| 72 preserveNames(); | 118 |
| 73 var result = <String, String>{}; | 119 String operator[](String key) { |
| 74 map.forEach((String mangledName, String reflectiveName) { | 120 if (_cache == null || _jsMangledNamesLength != _cacheLength) { |
| 75 result[reflectiveName] = mangledName; | 121 _cache = _updateReflectiveNames(); |
| 76 }); | 122 _cacheLength = _jsMangledNamesLength; |
| 77 return result; | 123 } |
| 124 return _cache[key]; | |
| 125 } | |
| 78 } | 126 } |
| 79 | 127 |
| 80 @NoInline() | 128 @NoInline() |
| 81 List extractKeys(victim) { | 129 List extractKeys(victim) { |
| 82 var result = JS('', '# ? Object.keys(#) : []', victim, victim); | 130 var result = JS('', '# ? Object.keys(#) : []', victim, victim); |
| 83 return new JSArray.markFixed(result); | 131 return new JSArray.markFixed(result); |
| 84 } | 132 } |
| 85 | 133 |
| 86 /** | 134 /** |
| 87 * Returns the (global) unmangled version of [name]. | 135 * Returns the (global) unmangled version of [name]. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 99 return JsCache.fetch(names, name); | 147 return JsCache.fetch(names, name); |
| 100 } | 148 } |
| 101 | 149 |
| 102 String unmangleAllIdentifiersIfPreservedAnyways(String str) { | 150 String unmangleAllIdentifiersIfPreservedAnyways(String str) { |
| 103 return JS("String", | 151 return JS("String", |
| 104 r"(#).replace(/[^<,> ]+/g," | 152 r"(#).replace(/[^<,> ]+/g," |
| 105 r"function(m) { return #[m] || m; })", | 153 r"function(m) { return #[m] || m; })", |
| 106 str, | 154 str, |
| 107 JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES)); | 155 JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES)); |
| 108 } | 156 } |
| OLD | NEW |