Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: pkg/compiler/lib/src/js_backend/minify_namer.dart

Issue 707793002: Use field names that are unique only wrt. the inheritance chain in minified mode. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 { 10 class MinifyNamer extends Namer {
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 h += name.codeUnitAt(i); 202 h += name.codeUnitAt(i);
203 h &= 0xffffffff; 203 h &= 0xffffffff;
204 h += h << 10; 204 h += h << 10;
205 h &= 0xffffffff; 205 h &= 0xffffffff;
206 h ^= h >> 6; 206 h ^= h >> 6;
207 h &= 0xffffffff; 207 h &= 0xffffffff;
208 } 208 }
209 return h; 209 return h;
210 } 210 }
211 211
212 int _letterNumber(int x) { 212 static int _letterNumber(int x) {
213 if (x >= ALPHABET_CHARACTERS) x %= ALPHABET_CHARACTERS; 213 if (x >= ALPHABET_CHARACTERS) x %= ALPHABET_CHARACTERS;
214 if (x < 26) return $a + x; 214 if (x < 26) return $a + x;
215 return $A + x - 26; 215 return $A + x - 26;
216 } 216 }
217 217
218 int _alphaNumericNumber(int x) { 218 static int _alphaNumericNumber(int x) {
219 if (x >= ALPHANUMERIC_CHARACTERS) x %= ALPHANUMERIC_CHARACTERS; 219 if (x >= ALPHANUMERIC_CHARACTERS) x %= ALPHANUMERIC_CHARACTERS;
220 if (x < 26) return $a + x; 220 if (x < 26) return $a + x;
221 if (x < 52) return $A + x - 26; 221 if (x < 52) return $A + x - 26;
222 return $0 + x - 52; 222 return $0 + x - 52;
223 } 223 }
224 224
225 String instanceFieldPropertyName(Element element) {
226 _FieldNamingScope names;
227
228 if (element is BoxFieldElement) {
229 names = new _FieldNamingScope.forBox(element.box);
230 } else {
231 ClassElement cls = element is ClosureFieldElement
232 ? element.closureClass : element.enclosingClass;
233 names = new _FieldNamingScope.forClass(cls, compiler.world);
234 }
235
236 if (!names.containsField(element)) {
237 return super.instanceFieldPropertyName(element);
floitsch 2014/11/06 14:05:41 When can this happen? (add comment). How do you en
herhut 2014/11/14 10:40:05 I have reworked this and included support for nami
238 }
239
240 return names[element];
241 }
225 } 242 }
243
244 /**
245 * A [_FieldNamingScope] encodes a node in the inheritance tree of the current
246 * class hierarchy. The root node typically is the node corresponding to the
247 * `Object` class. It is used to assign a unique name to each field of a class.
248 * Unique here means unique wrt. all fields along the path back to the root.
249 * This is achieved at construction time via the [_count] field that counts the
250 * number of fields on the path to the root node that have been encountered so
251 * far.
252 * Obviously, this only works if no fields are added to a parent node after its
floitsch 2014/11/06 14:05:41 New line before.
herhut 2014/11/14 10:40:05 Done.
253 * children have added their first field.
254 */
255 class _FieldNamingScope {
256 final _FieldNamingScope superScope;
257 final Entity container;
258 final Map<Element, String> names = new Maplet<Element, String>();
259 int _count;
260
261 static Map<Entity, _FieldNamingScope> _scopes =
floitsch 2014/11/06 14:05:41 When is this map cleared? This looks like somethi
herhut 2014/11/14 10:40:05 I have factored the state out into a field of the
262 new Map<Entity, _FieldNamingScope>();
263
264 factory _FieldNamingScope.forClass(ClassElement cls, ClassWorld world) {
265 _FieldNamingScope computeFieldNames() {
266 _FieldNamingScope result;
267 ClassElement superClass = cls.superclass;
268 if (superClass != null) {
269 result = new _FieldNamingScope.inherit(cls,
270 new _FieldNamingScope.forClass(superClass, world));
271 } else {
272 result = new _FieldNamingScope.rootScope(cls);
273 }
274
275 // If this class is used as a mixin, we cannot rename its fields as
276 // there is no single place in the hierarchy where it belongs. Also,
277 // if this class is the result of a mixin application, we cannot remane
278 // its fields as they have to stay in sync with the fields of the mixed
279 // in class.
280 // However, we still produce an empty scope, as subclasses of this mixin
281 // application might still have their fields renamed.
282 if (cls.isMixinApplication || world.isUsedAsMixin(cls)) return result;
283
284 cls.forEachInstanceField((cls, field) => result.add(field));
285 return result;
286 }
287
288 return _scopes.putIfAbsent(cls, computeFieldNames);
289 }
290
291 factory _FieldNamingScope.forBox(Local box) {
292 return _scopes.putIfAbsent(box, () => new _BoxFieldNamingScope(box));
293 }
294
295 _FieldNamingScope.rootScope(this.container) :
floitsch 2014/11/06 14:05:41 : in next line.
herhut 2014/11/14 10:40:05 Done.
296 superScope = null,
floitsch 2014/11/06 14:05:41 indent by 4.
herhut 2014/11/14 10:40:05 Done.
297 _count = 0;
298
299 _FieldNamingScope.inherit(this.container, this.superScope) {
300 _count = superScope._count;
301 }
302
303 _valueIsUnused(String name) {
floitsch 2014/11/06 14:05:41 _isValueUnused
herhut 2014/11/14 10:40:05 Done.
304 return !names.values.contains(name) &&
305 ((superScope == null) || superScope._valueIsUnused(name));
306 }
307
308 String _nextName() {
309 List<int> codes = <int>[];
310 var cnt = _count++;
311 codes.add(MinifyNamer._letterNumber(cnt));
312 cnt ~/= MinifyNamer.ALPHABET_CHARACTERS;
313 while (cnt > 0) {
314 codes.add(MinifyNamer._alphaNumericNumber(cnt));
315 cnt ~/= MinifyNamer.ALPHANUMERIC_CHARACTERS;
316 }
317 return new String.fromCharCodes(codes);
318 }
319
320 String operator[](Element field) {
321 String name = names[field];
322 if (name == null && superScope != null) return superScope[field];
323 return name;
324 }
325
326 void add(Element field) {
327 String value = _nextName();
328 assert(invariant(field, _valueIsUnused(value)));
329 names[field] = value;
330 }
331
332 bool containsField(Element field) => names.containsKey(field);
333 }
334
335 /**
336 * [BoxFieldElement] fields work differently in that they do not belong to an
337 * actual class but an anonymous box associated to a [Local]. As there is no
338 * inheritance chain, we do not need to compute fields a priori but can assign
339 * names on the fly.
340 */
341 class _BoxFieldNamingScope extends _FieldNamingScope {
342 _BoxFieldNamingScope(Local box) : super.rootScope(box);
343
344 bool containsField(_) => true;
345
346 String operator[](Element field) {
347 if (!names.containsKey(field)) add(field);
348 return names[field];
349 }
350 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698