| Index: sdk/lib/_internal/compiler/js_lib/js_names.dart
|
| diff --git a/sdk/lib/_internal/compiler/js_lib/js_names.dart b/sdk/lib/_internal/compiler/js_lib/js_names.dart
|
| index 87cc6c04eea97bdddc5e4322a1513dcacf728283..a1358935d86057819d2b44616b07d742b750e200 100644
|
| --- a/sdk/lib/_internal/compiler/js_lib/js_names.dart
|
| +++ b/sdk/lib/_internal/compiler/js_lib/js_names.dart
|
| @@ -26,55 +26,103 @@ preserveNames() {}
|
| /// A map from mangled names to "reflective" names, that is, unmangled names
|
| /// with some additional information, such as, number of required arguments.
|
| /// This map is for mangled names used as instance members.
|
| -final Map<String, String> mangledNames =
|
| - computeMangledNames(
|
| - JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES),
|
| - false);
|
| +final _LazyMangledNamesMap mangledNames = new _LazyMangledInstanceNamesMap(
|
| + JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES));
|
|
|
| /// A map from "reflective" names to mangled names (the reverse of
|
| /// [mangledNames]).
|
| -final Map<String, String> reflectiveNames =
|
| - computeReflectiveNames(mangledNames);
|
| +final _LazyReflectiveNamesMap reflectiveNames =
|
| + new _LazyReflectiveNamesMap(JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES),
|
| + true);
|
|
|
| /// A map from mangled names to "reflective" names (see [mangledNames]). This
|
| /// map is for globals, that is, static and top-level members.
|
| -final Map<String, String> mangledGlobalNames = computeMangledNames(
|
| - JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES),
|
| - true);
|
| +final _LazyMangledNamesMap mangledGlobalNames = new _LazyMangledNamesMap(
|
| + JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES));
|
|
|
| /// A map from "reflective" names to mangled names (the reverse of
|
| /// [mangledGlobalNames]).
|
| -final Map<String, String> reflectiveGlobalNames =
|
| - computeReflectiveNames(mangledGlobalNames);
|
| +final _LazyReflectiveNamesMap reflectiveGlobalNames =
|
| + new _LazyReflectiveNamesMap(
|
| + JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES), false);
|
|
|
| /// [jsMangledNames] is a JavaScript object literal. The keys are the mangled
|
| /// names, and the values are the "reflective" names.
|
| -Map<String, String> computeMangledNames(jsMangledNames, bool isGlobal) {
|
| - preserveNames();
|
| - var keys = extractKeys(jsMangledNames);
|
| - var result = <String, String>{};
|
| - String getterPrefix = JS_GET_NAME('GETTER_PREFIX');
|
| - int getterPrefixLength = getterPrefix.length;
|
| - String setterPrefix = JS_GET_NAME('SETTER_PREFIX');
|
| - for (String key in keys) {
|
| - String value = JS('String', '#[#]', jsMangledNames, key);
|
| - result[key] = value;
|
| - if (!isGlobal) {
|
| - if (key.startsWith(getterPrefix)) {
|
| - result['$setterPrefix${key.substring(getterPrefixLength)}'] = '$value=';
|
| - }
|
| +class _LazyMangledNamesMap {
|
| + var _jsMangledNames;
|
| +
|
| + _LazyMangledNamesMap(this._jsMangledNames);
|
| +
|
| + String operator[](String key) {
|
| + String result = JS('var', '#[#]', _jsMangledNames, key);
|
| + // Filter out all non-string values to protect against polution from
|
| + // anciliary fields in [_jsMangledNames].
|
| + bool filter =
|
| + JS('bool', '# == null || typeof # !== "string"', result, result);
|
| + return filter ? null : result;
|
| + }
|
| +}
|
| +
|
| +class _LazyMangledInstanceNamesMap extends _LazyMangledNamesMap {
|
| + _LazyMangledInstanceNamesMap(_jsMangledNames) : super(_jsMangledNames);
|
| +
|
| + String operator[](String key) {
|
| + var result = super[key];
|
| + String setterPrefix = JS_GET_NAME('SETTER_PREFIX');
|
| + if (result == null && key.startsWith(setterPrefix)) {
|
| + String getterPrefix = JS_GET_NAME('GETTER_PREFIX');
|
| + int setterPrefixLength = getterPrefix.length;
|
| +
|
| + // Generate the setter name from the getter name.
|
| + key = '$getterPrefix${key.substring(setterPrefixLength)}';
|
| + result = super[key];
|
| + return (result != null) ? "${result}=" : null;
|
| }
|
| + return result;
|
| }
|
| - return result;
|
| }
|
|
|
| -Map<String, String> computeReflectiveNames(Map<String, String> map) {
|
| - preserveNames();
|
| - var result = <String, String>{};
|
| - map.forEach((String mangledName, String reflectiveName) {
|
| - result[reflectiveName] = mangledName;
|
| - });
|
| - return result;
|
| +class _LazyReflectiveNamesMap {
|
| + final _jsMangledNames;
|
| + final bool _isInstance;
|
| + var _cacheLength = 0;
|
| + var _cache;
|
| +
|
| + _LazyReflectiveNamesMap(this._jsMangledNames, this._isInstance);
|
| +
|
| + Map<String, String> _updateReflectiveNames() {
|
| + preserveNames();
|
| + var result = <String, String>{};
|
| + var keys = JS('List', 'Object.keys(#)', _jsMangledNames);
|
| + for (String key in keys) {
|
| + var reflectiveName = JS('var', '#[#]', _jsMangledNames, key);
|
| + // Filter out all non-string values to protect against polution from
|
| + // anciliary fields in [_jsMangledNames].
|
| + bool filter = JS('bool', '# == null || typeof # !== "string"',
|
| + reflectiveName, reflectiveName);
|
| + if (filter) continue;
|
| + result[reflectiveName] = key;
|
| +
|
| + String getterPrefix = JS_GET_NAME('GETTER_PREFIX');
|
| + if (_isInstance && key.startsWith(getterPrefix)) {
|
| + int getterPrefixLength = getterPrefix.length;
|
| + String setterPrefix = JS_GET_NAME('SETTER_PREFIX');
|
| + result['$reflectiveName='] =
|
| + '$setterPrefix${key.substring(getterPrefixLength)}';
|
| + }
|
| + }
|
| + return result;
|
| + }
|
| +
|
| + int get _jsMangledNamesLength => JS('int', '#.length', _jsMangledNames);
|
| +
|
| + String operator[](String key) {
|
| + if (_cache == null || _jsMangledNamesLength != _cacheLength) {
|
| + _cache = _updateReflectiveNames();
|
| + _cacheLength = _jsMangledNamesLength;
|
| + }
|
| + return _cache[key];
|
| + }
|
| }
|
|
|
| @NoInline()
|
|
|