OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 part of js_backend; | 5 part of js_backend; |
6 | 6 |
7 /** | 7 /** |
8 * Assigns JavaScript identifiers to Dart variables, class-names and members. | 8 * Assigns JavaScript identifiers to Dart variables, class-names and members. |
9 */ | 9 */ |
10 class MinifyNamer extends Namer with _MinifiedFieldNamer, | 10 class MinifyNamer extends Namer |
11 _MinifyConstructorBodyNamer, _MinifiedOneShotInterceptorNamer { | 11 with |
| 12 _MinifiedFieldNamer, |
| 13 _MinifyConstructorBodyNamer, |
| 14 _MinifiedOneShotInterceptorNamer { |
12 MinifyNamer(Compiler compiler) : super(compiler) { | 15 MinifyNamer(Compiler compiler) : super(compiler) { |
13 reserveBackendNames(); | 16 reserveBackendNames(); |
14 fieldRegistry = new _FieldNamingRegistry(this); | 17 fieldRegistry = new _FieldNamingRegistry(this); |
15 } | 18 } |
16 | 19 |
17 _FieldNamingRegistry fieldRegistry; | 20 _FieldNamingRegistry fieldRegistry; |
18 | 21 |
19 String get isolateName => 'I'; | 22 String get isolateName => 'I'; |
20 String get isolatePropertiesName => 'p'; | 23 String get isolatePropertiesName => 'p'; |
21 bool get shouldMinify => true; | 24 bool get shouldMinify => true; |
22 | 25 |
23 final String getterPrefix = 'g'; | 26 final String getterPrefix = 'g'; |
24 final String setterPrefix = 's'; | 27 final String setterPrefix = 's'; |
25 final String callPrefix = ''; // this will create function names $<n> | 28 final String callPrefix = ''; // this will create function names $<n> |
26 | 29 |
27 final ALPHABET_CHARACTERS = 52; // a-zA-Z. | 30 final ALPHABET_CHARACTERS = 52; // a-zA-Z. |
28 final ALPHANUMERIC_CHARACTERS = 62; // a-zA-Z0-9. | 31 final ALPHANUMERIC_CHARACTERS = 62; // a-zA-Z0-9. |
29 | 32 |
30 /// You can pass an invalid identifier to this and unlike its non-minifying | 33 /// You can pass an invalid identifier to this and unlike its non-minifying |
31 /// counterpart it will never return the proposedName as the new fresh name. | 34 /// counterpart it will never return the proposedName as the new fresh name. |
32 /// | 35 /// |
33 /// [sanitizeForNatives] and [sanitizeForAnnotations] are ignored because the | 36 /// [sanitizeForNatives] and [sanitizeForAnnotations] are ignored because the |
34 /// minified names will always avoid clashing with annotated names or natives. | 37 /// minified names will always avoid clashing with annotated names or natives. |
35 @override | 38 @override |
36 String _generateFreshStringForName(String proposedName, | 39 String _generateFreshStringForName(String proposedName, NamingScope scope, |
37 NamingScope scope, | 40 {bool sanitizeForNatives: false, bool sanitizeForAnnotations: false}) { |
38 {bool sanitizeForNatives: false, | |
39 bool sanitizeForAnnotations: false}) { | |
40 String freshName; | 41 String freshName; |
41 String suggestion = scope.suggestName(proposedName); | 42 String suggestion = scope.suggestName(proposedName); |
42 if (suggestion != null && scope.isUnused(suggestion)) { | 43 if (suggestion != null && scope.isUnused(suggestion)) { |
43 freshName = suggestion; | 44 freshName = suggestion; |
44 } else { | 45 } else { |
45 freshName = _getUnusedName(proposedName, scope); | 46 freshName = _getUnusedName(proposedName, scope); |
46 } | 47 } |
47 scope.registerUse(freshName); | 48 scope.registerUse(freshName); |
48 return freshName; | 49 return freshName; |
49 } | 50 } |
50 | 51 |
51 // From issue 7554. These should not be used on objects (as instance | 52 // From issue 7554. These should not be used on objects (as instance |
52 // variables) because they clash with names from the DOM. However, it is | 53 // variables) because they clash with names from the DOM. However, it is |
53 // OK to use them as fields, as we only access fields directly if we know | 54 // OK to use them as fields, as we only access fields directly if we know |
54 // the receiver type. | 55 // the receiver type. |
55 static const List<String> _reservedNativeProperties = const <String>[ | 56 static const List<String> _reservedNativeProperties = const <String>[ |
56 'a', 'b', 'c', 'd', 'e', 'f', 'r', 'x', 'y', 'z', 'Q', | 57 'a', 'b', 'c', 'd', 'e', 'f', 'r', 'x', 'y', 'z', 'Q', |
57 // 2-letter: | 58 // 2-letter: |
58 'ch', 'cx', 'cy', 'db', 'dx', 'dy', 'fr', 'fx', 'fy', 'go', 'id', 'k1', | 59 'ch', 'cx', 'cy', 'db', 'dx', 'dy', 'fr', 'fx', 'fy', 'go', 'id', 'k1', |
59 'k2', 'k3', 'k4', 'r1', 'r2', 'rx', 'ry', 'x1', 'x2', 'y1', 'y2', | 60 'k2', 'k3', 'k4', 'r1', 'r2', 'rx', 'ry', 'x1', 'x2', 'y1', 'y2', |
60 // 3-letter: | 61 // 3-letter: |
61 'add', 'all', 'alt', 'arc', 'CCW', 'cmp', 'dir', 'end', 'get', 'in1', | 62 'add', 'all', 'alt', 'arc', 'CCW', 'cmp', 'dir', 'end', 'get', 'in1', |
62 'in2', 'INT', 'key', 'log', 'low', 'm11', 'm12', 'm13', 'm14', 'm21', | 63 'in2', 'INT', 'key', 'log', 'low', 'm11', 'm12', 'm13', 'm14', 'm21', |
63 'm22', 'm23', 'm24', 'm31', 'm32', 'm33', 'm34', 'm41', 'm42', 'm43', | 64 'm22', 'm23', 'm24', 'm31', 'm32', 'm33', 'm34', 'm41', 'm42', 'm43', |
64 'm44', 'max', 'min', 'now', 'ONE', 'put', 'red', 'rel', 'rev', 'RGB', | 65 'm44', 'max', 'min', 'now', 'ONE', 'put', 'red', 'rel', 'rev', 'RGB', |
65 'sdp', 'set', 'src', 'tag', 'top', 'uid', 'uri', 'url', 'URL', | 66 'sdp', 'set', 'src', 'tag', 'top', 'uid', 'uri', 'url', 'URL', |
66 // 4-letter: | 67 // 4-letter: |
67 'abbr', 'atob', 'Attr', 'axes', 'axis', 'back', 'BACK', 'beta', 'bias', | 68 'abbr', 'atob', 'Attr', 'axes', 'axis', 'back', 'BACK', 'beta', 'bias', |
68 'Blob', 'blue', 'blur', 'BLUR', 'body', 'BOOL', 'BOTH', 'btoa', 'BYTE', | 69 'Blob', 'blue', 'blur', 'BLUR', 'body', 'BOOL', 'BOTH', 'btoa', 'BYTE', |
69 'cite', 'clip', 'code', 'cols', 'cues', 'data', 'DECR', 'DONE', 'face', | 70 'cite', 'clip', 'code', 'cols', 'cues', 'data', 'DECR', 'DONE', 'face', |
70 'file', 'File', 'fill', 'find', 'font', 'form', 'gain', 'hash', 'head', | 71 'file', 'File', 'fill', 'find', 'font', 'form', 'gain', 'hash', 'head', |
71 'high', 'hint', 'host', 'href', 'HRTF', 'IDLE', 'INCR', 'info', 'INIT', | 72 'high', 'hint', 'host', 'href', 'HRTF', 'IDLE', 'INCR', 'info', 'INIT', |
72 'isId', 'item', 'KEEP', 'kind', 'knee', 'lang', 'left', 'LESS', 'line', | 73 'isId', 'item', 'KEEP', 'kind', 'knee', 'lang', 'left', 'LESS', 'line', |
73 'link', 'list', 'load', 'loop', 'mode', 'name', 'Node', 'None', 'NONE', | 74 'link', 'list', 'load', 'loop', 'mode', 'name', 'Node', 'None', 'NONE', |
74 'only', 'open', 'OPEN', 'ping', 'play', 'port', 'rect', 'Rect', 'refX', | 75 'only', 'open', 'OPEN', 'ping', 'play', 'port', 'rect', 'Rect', 'refX', |
75 'refY', 'RGBA', 'root', 'rows', 'save', 'seed', 'seek', 'self', 'send', | 76 'refY', 'RGBA', 'root', 'rows', 'save', 'seed', 'seek', 'self', 'send', |
76 'show', 'SINE', 'size', 'span', 'stat', 'step', 'stop', 'tags', 'text', | 77 'show', 'SINE', 'size', 'span', 'stat', 'step', 'stop', 'tags', 'text', |
77 'Text', 'time', 'type', 'view', 'warn', 'wrap', 'ZERO']; | 78 'Text', 'time', 'type', 'view', 'warn', 'wrap', 'ZERO' |
| 79 ]; |
78 | 80 |
79 void reserveBackendNames() { | 81 void reserveBackendNames() { |
80 for (String name in _reservedNativeProperties) { | 82 for (String name in _reservedNativeProperties) { |
81 if (name.length < 2) { | 83 if (name.length < 2) { |
82 // Ensure the 1-letter names are disambiguated to the same name. | 84 // Ensure the 1-letter names are disambiguated to the same name. |
83 String disambiguatedName = name; | 85 String disambiguatedName = name; |
84 reservePublicMemberName(name, disambiguatedName); | 86 reservePublicMemberName(name, disambiguatedName); |
85 } | 87 } |
86 instanceScope.registerUse(name); | 88 instanceScope.registerUse(name); |
87 // Getter and setter names are autogenerated by prepending 'g' and 's' to | 89 // Getter and setter names are autogenerated by prepending 'g' and 's' to |
88 // field names. Therefore there are some field names we don't want to | 90 // field names. Therefore there are some field names we don't want to |
89 // use. It is implicit in the next line that the banned prefix is | 91 // use. It is implicit in the next line that the banned prefix is |
90 // only one character. | 92 // only one character. |
91 if (_hasBannedPrefix(name)) { | 93 if (_hasBannedPrefix(name)) { |
92 instanceScope.registerUse(name.substring(1)); | 94 instanceScope.registerUse(name.substring(1)); |
93 } | 95 } |
94 } | 96 } |
95 | 97 |
96 // These popular names are present in most programs and deserve | 98 // These popular names are present in most programs and deserve |
97 // single character minified names. We could determine the popular names | 99 // single character minified names. We could determine the popular names |
98 // individually per program, but that would mean that the output of the | 100 // individually per program, but that would mean that the output of the |
99 // minifier was less stable from version to version of the program being | 101 // minifier was less stable from version to version of the program being |
100 // minified. | 102 // minified. |
101 _populateSuggestedNames( | 103 _populateSuggestedNames(instanceScope, const <String>[ |
102 instanceScope, | 104 r'$add', |
103 const <String>[ | 105 r'add$1', |
104 r'$add', r'add$1', r'$and', | 106 r'$and', |
105 r'$or', | 107 r'$or', |
106 r'current', r'$shr', r'$eq', r'$ne', | 108 r'current', |
107 r'$index', r'$indexSet', | 109 r'$shr', |
108 r'$xor', r'clone$0', | 110 r'$eq', |
109 r'iterator', r'length', | 111 r'$ne', |
110 r'$lt', r'$gt', r'$le', r'$ge', | 112 r'$index', |
111 r'moveNext$0', r'node', r'on', r'$negate', r'push', r'self', | 113 r'$indexSet', |
112 r'start', r'target', r'$shl', r'value', r'width', r'style', | 114 r'$xor', |
113 r'noSuchMethod$1', r'$mul', r'$div', r'$sub', r'$not', r'$mod', | 115 r'clone$0', |
114 r'$tdiv', r'toString$0']); | 116 r'iterator', |
| 117 r'length', |
| 118 r'$lt', |
| 119 r'$gt', |
| 120 r'$le', |
| 121 r'$ge', |
| 122 r'moveNext$0', |
| 123 r'node', |
| 124 r'on', |
| 125 r'$negate', |
| 126 r'push', |
| 127 r'self', |
| 128 r'start', |
| 129 r'target', |
| 130 r'$shl', |
| 131 r'value', |
| 132 r'width', |
| 133 r'style', |
| 134 r'noSuchMethod$1', |
| 135 r'$mul', |
| 136 r'$div', |
| 137 r'$sub', |
| 138 r'$not', |
| 139 r'$mod', |
| 140 r'$tdiv', |
| 141 r'toString$0' |
| 142 ]); |
115 | 143 |
116 _populateSuggestedNames( | 144 _populateSuggestedNames(globalScope, const <String>[ |
117 globalScope, | 145 r'Object', |
118 const <String>[ | 146 'wrapException', |
119 r'Object', 'wrapException', r'$eq', r'S', r'ioore', | 147 r'$eq', |
120 r'UnsupportedError$', r'length', r'$sub', | 148 r'S', |
121 r'$add', r'$gt', r'$ge', r'$lt', r'$le', r'add', | 149 r'ioore', |
122 r'iae', | 150 r'UnsupportedError$', |
123 r'ArgumentError$', r'BoundClosure', r'Closure', r'StateError$', | 151 r'length', |
124 r'getInterceptor', r'max', r'$mul', | 152 r'$sub', |
125 r'Map', r'Key_Key', r'$div', | 153 r'$add', |
126 r'List_List$from', | 154 r'$gt', |
127 r'LinkedHashMap_LinkedHashMap$_empty', | 155 r'$ge', |
128 r'LinkedHashMap_LinkedHashMap$_literal', | 156 r'$lt', |
129 r'min', | 157 r'$le', |
130 r'RangeError$value', r'JSString', r'JSNumber', | 158 r'add', |
131 r'JSArray', r'createInvocationMirror', r'String', | 159 r'iae', |
132 r'setRuntimeTypeInfo', r'createRuntimeType' | 160 r'ArgumentError$', |
133 ]); | 161 r'BoundClosure', |
| 162 r'Closure', |
| 163 r'StateError$', |
| 164 r'getInterceptor', |
| 165 r'max', |
| 166 r'$mul', |
| 167 r'Map', |
| 168 r'Key_Key', |
| 169 r'$div', |
| 170 r'List_List$from', |
| 171 r'LinkedHashMap_LinkedHashMap$_empty', |
| 172 r'LinkedHashMap_LinkedHashMap$_literal', |
| 173 r'min', |
| 174 r'RangeError$value', |
| 175 r'JSString', |
| 176 r'JSNumber', |
| 177 r'JSArray', |
| 178 r'createInvocationMirror', |
| 179 r'String', |
| 180 r'setRuntimeTypeInfo', |
| 181 r'createRuntimeType' |
| 182 ]); |
134 } | 183 } |
135 | 184 |
136 void _populateSuggestedNames(NamingScope scope, | 185 void _populateSuggestedNames(NamingScope scope, List<String> suggestions) { |
137 List<String> suggestions) { | |
138 int c = $a - 1; | 186 int c = $a - 1; |
139 String letter; | 187 String letter; |
140 for (String name in suggestions) { | 188 for (String name in suggestions) { |
141 do { | 189 do { |
142 assert(c != $Z); | 190 assert(c != $Z); |
143 c = (c == $z) ? $A : c + 1; | 191 c = (c == $z) ? $A : c + 1; |
144 letter = new String.fromCharCodes([c]); | 192 letter = new String.fromCharCodes([c]); |
145 } while (_hasBannedPrefix(letter) || scope.isUsed(letter)); | 193 } while (_hasBannedPrefix(letter) || scope.isUsed(letter)); |
146 assert(!scope.hasSuggestion(name)); | 194 assert(!scope.hasSuggestion(name)); |
147 scope.addSuggestion(name, letter); | 195 scope.addSuggestion(name, letter); |
148 } | 196 } |
149 } | 197 } |
150 | 198 |
151 | |
152 // This gets a minified name based on a hash of the proposed name. This | 199 // This gets a minified name based on a hash of the proposed name. This |
153 // is slightly less efficient than just getting the next name in a series, | 200 // is slightly less efficient than just getting the next name in a series, |
154 // but it means that small changes in the input program will give smallish | 201 // but it means that small changes in the input program will give smallish |
155 // changes in the output, which can be useful for diffing etc. | 202 // changes in the output, which can be useful for diffing etc. |
156 String _getUnusedName(String proposedName, NamingScope scope) { | 203 String _getUnusedName(String proposedName, NamingScope scope) { |
157 int hash = _calculateHash(proposedName); | 204 int hash = _calculateHash(proposedName); |
158 // Avoid very small hashes that won't try many names. | 205 // Avoid very small hashes that won't try many names. |
159 hash = hash < 1000 ? hash * 314159 : hash; // Yes, it's prime. | 206 hash = hash < 1000 ? hash * 314159 : hash; // Yes, it's prime. |
160 | 207 |
161 // Try other n-character names based on the hash. We try one to three | 208 // Try other n-character names based on the hash. We try one to three |
162 // character identifiers. For each length we try around 10 different names | 209 // character identifiers. For each length we try around 10 different names |
163 // in a predictable order determined by the proposed name. This is in order | 210 // in a predictable order determined by the proposed name. This is in order |
164 // to make the renamer stable: small changes in the input should nornally | 211 // to make the renamer stable: small changes in the input should nornally |
165 // result in relatively small changes in the output. | 212 // result in relatively small changes in the output. |
166 for (int n = 1; n <= 3; n++) { | 213 for (int n = 1; n <= 3; n++) { |
167 int h = hash; | 214 int h = hash; |
168 while (h > 10) { | 215 while (h > 10) { |
169 List<int> codes = <int>[_letterNumber(h)]; | 216 List<int> codes = <int>[_letterNumber(h)]; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 | 315 |
269 int get numberOfConstructors => _constructors.length; | 316 int get numberOfConstructors => _constructors.length; |
270 | 317 |
271 _ConstructorBodyNamingScope _superScope; | 318 _ConstructorBodyNamingScope _superScope; |
272 | 319 |
273 _ConstructorBodyNamingScope.rootScope(ClassElement cls) | 320 _ConstructorBodyNamingScope.rootScope(ClassElement cls) |
274 : _superScope = null, | 321 : _superScope = null, |
275 _startIndex = 0, | 322 _startIndex = 0, |
276 _constructors = cls.constructors.toList(growable: false); | 323 _constructors = cls.constructors.toList(growable: false); |
277 | 324 |
278 _ConstructorBodyNamingScope.forClass(ClassElement cls, | 325 _ConstructorBodyNamingScope.forClass( |
279 _ConstructorBodyNamingScope superScope) | 326 ClassElement cls, _ConstructorBodyNamingScope superScope) |
280 : _superScope = superScope, | 327 : _superScope = superScope, |
281 _startIndex = superScope._startIndex + superScope.numberOfConstructors, | 328 _startIndex = superScope._startIndex + superScope.numberOfConstructors, |
282 _constructors = cls.constructors.toList(growable: false); | 329 _constructors = cls.constructors.toList(growable: false); |
283 | 330 |
284 // Mixin Applications have constructors but we never generate code for them, | 331 // Mixin Applications have constructors but we never generate code for them, |
285 // so they do not count in the inheritance chain. | 332 // so they do not count in the inheritance chain. |
286 _ConstructorBodyNamingScope.forMixinApplication(ClassElement cls, | 333 _ConstructorBodyNamingScope.forMixinApplication( |
287 _ConstructorBodyNamingScope superScope) | 334 ClassElement cls, _ConstructorBodyNamingScope superScope) |
288 : _superScope = superScope, | 335 : _superScope = superScope, |
289 _startIndex = superScope._startIndex + superScope.numberOfConstructors, | 336 _startIndex = superScope._startIndex + superScope.numberOfConstructors, |
290 _constructors = const []; | 337 _constructors = const []; |
291 | 338 |
292 factory _ConstructorBodyNamingScope(ClassElement cls, | 339 factory _ConstructorBodyNamingScope(ClassElement cls, |
293 Map<ClassElement, _ConstructorBodyNamingScope> registry) { | 340 Map<ClassElement, _ConstructorBodyNamingScope> registry) { |
294 return registry.putIfAbsent(cls, () { | 341 return registry.putIfAbsent(cls, () { |
295 if (cls.superclass == null) { | 342 if (cls.superclass == null) { |
296 return new _ConstructorBodyNamingScope.rootScope(cls); | 343 return new _ConstructorBodyNamingScope.rootScope(cls); |
297 } else if (cls.isMixinApplication) { | 344 } else if (cls.isMixinApplication) { |
298 return new _ConstructorBodyNamingScope.forMixinApplication(cls, | 345 return new _ConstructorBodyNamingScope.forMixinApplication( |
299 new _ConstructorBodyNamingScope(cls.superclass, registry)); | 346 cls, new _ConstructorBodyNamingScope(cls.superclass, registry)); |
300 } else { | 347 } else { |
301 return new _ConstructorBodyNamingScope.forClass(cls, | 348 return new _ConstructorBodyNamingScope.forClass( |
302 new _ConstructorBodyNamingScope(cls.superclass, registry)); | 349 cls, new _ConstructorBodyNamingScope(cls.superclass, registry)); |
303 } | 350 } |
304 }); | 351 }); |
305 } | 352 } |
306 | 353 |
307 String constructorBodyKeyFor(ConstructorBodyElement body) { | 354 String constructorBodyKeyFor(ConstructorBodyElement body) { |
308 int position = _constructors.indexOf(body.constructor); | 355 int position = _constructors.indexOf(body.constructor); |
309 assert(invariant(body, position >= 0, message: "constructor body missing")); | 356 assert(invariant(body, position >= 0, message: "constructor body missing")); |
310 return "@constructorBody@${_startIndex + position}"; | 357 return "@constructorBody@${_startIndex + position}"; |
311 } | 358 } |
312 } | 359 } |
313 | 360 |
314 abstract class _MinifyConstructorBodyNamer implements Namer { | 361 abstract class _MinifyConstructorBodyNamer implements Namer { |
315 Map<ClassElement, _ConstructorBodyNamingScope> _constructorBodyScopes = | 362 Map<ClassElement, _ConstructorBodyNamingScope> _constructorBodyScopes = |
316 new Map<ClassElement, _ConstructorBodyNamingScope>(); | 363 new Map<ClassElement, _ConstructorBodyNamingScope>(); |
317 | 364 |
318 @override | 365 @override |
319 jsAst.Name constructorBodyName(FunctionElement method) { | 366 jsAst.Name constructorBodyName(FunctionElement method) { |
320 _ConstructorBodyNamingScope scope = | 367 _ConstructorBodyNamingScope scope = new _ConstructorBodyNamingScope( |
321 new _ConstructorBodyNamingScope(method.enclosingClass, | 368 method.enclosingClass, _constructorBodyScopes); |
322 _constructorBodyScopes); | |
323 String key = scope.constructorBodyKeyFor(method); | 369 String key = scope.constructorBodyKeyFor(method); |
324 return _disambiguateMemberByKey(key, | 370 return _disambiguateMemberByKey( |
325 () => _proposeNameForConstructorBody(method)); | 371 key, () => _proposeNameForConstructorBody(method)); |
326 } | 372 } |
327 } | 373 } |
328 | 374 |
329 abstract class _MinifiedOneShotInterceptorNamer implements Namer { | 375 abstract class _MinifiedOneShotInterceptorNamer implements Namer { |
330 /// Property name used for the one-shot interceptor method for the given | 376 /// Property name used for the one-shot interceptor method for the given |
331 /// [selector] and return-type specialization. | 377 /// [selector] and return-type specialization. |
332 @override | 378 @override |
333 jsAst.Name nameForGetOneShotInterceptor(Selector selector, | 379 jsAst.Name nameForGetOneShotInterceptor( |
334 Iterable<ClassElement> classes) { | 380 Selector selector, Iterable<ClassElement> classes) { |
335 String root = selector.isOperator | 381 String root = selector.isOperator |
336 ? operatorNameToIdentifier(selector.name) | 382 ? operatorNameToIdentifier(selector.name) |
337 : privateName(selector.memberName); | 383 : privateName(selector.memberName); |
338 String prefix = selector.isGetter | 384 String prefix = |
339 ? r"$get" | 385 selector.isGetter ? r"$get" : selector.isSetter ? r"$set" : ""; |
340 : selector.isSetter ? r"$set" : ""; | 386 String callSuffix = selector.isCall |
341 String callSuffix = | 387 ? callSuffixForStructure(selector.callStructure).join() |
342 selector.isCall ? callSuffixForStructure(selector.callStructure).join() | 388 : ""; |
343 : ""; | |
344 String suffix = suffixForGetInterceptor(classes); | 389 String suffix = suffixForGetInterceptor(classes); |
345 String fullName = "\$intercepted$prefix\$$root$callSuffix\$$suffix"; | 390 String fullName = "\$intercepted$prefix\$$root$callSuffix\$$suffix"; |
346 return _disambiguateInternalGlobal(fullName); | 391 return _disambiguateInternalGlobal(fullName); |
347 } | 392 } |
348 } | 393 } |
349 | |
OLD | NEW |