| // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| part of 'namer.dart'; |
| |
| class FrequencyBasedNamer extends Namer |
| with _MinifiedFieldNamer, _MinifiedOneShotInterceptorNamer |
| implements js_ast.TokenFinalizer { |
| @override |
| late final FieldNamingRegistry fieldRegistry = FieldNamingRegistry(this); |
| List<TokenName> tokens = []; |
| |
| final Map<NamingScope, TokenScope> _tokenScopes = {}; |
| |
| @override |
| String get genericInstantiationPrefix => r'$I'; |
| |
| FrequencyBasedNamer(super.closedWorld, super.fixedNames); |
| |
| TokenScope newScopeFor(NamingScope scope) { |
| if (scope == instanceScope) { |
| Set<String> illegalNames = Set<String>.from(jsReserved); |
| for (String illegal in MinifyNamer._reservedNativeProperties) { |
| illegalNames.add(illegal); |
| if (hasBannedMinifiedPrefix(illegal)) { |
| illegalNames.add(illegal.substring(1)); |
| } |
| } |
| return TokenScope(illegalNames: illegalNames); |
| } else { |
| return TokenScope(illegalNames: jsReserved); |
| } |
| } |
| |
| @override |
| js_ast.Name getFreshName( |
| NamingScope scope, |
| String proposedName, { |
| bool sanitizeForNatives = false, |
| bool sanitizeForAnnotations = false, |
| }) { |
| // Grab the scope for this token |
| TokenScope tokenScope = _tokenScopes.putIfAbsent( |
| scope, |
| () => newScopeFor(scope), |
| ); |
| |
| // Get the name the normal namer would use as a key. |
| String proposed = _generateFreshStringForName( |
| proposedName, |
| scope, |
| sanitizeForNatives: sanitizeForNatives, |
| sanitizeForAnnotations: sanitizeForAnnotations, |
| ); |
| |
| TokenName name = TokenName(tokenScope, proposed); |
| tokens.add(name); |
| return name; |
| } |
| |
| @override |
| js_ast.Name instanceFieldPropertyName(FieldEntity element) { |
| js_ast.Name? proposed = _minifiedInstanceFieldPropertyName(element); |
| if (proposed != null) { |
| return proposed; |
| } |
| return super.instanceFieldPropertyName(element); |
| } |
| |
| @override |
| void finalizeTokens() { |
| int compareReferenceCount(TokenName a, TokenName b) { |
| int result = b._rc - a._rc; |
| if (result == 0) result = a.key.compareTo(b.key); |
| return result; |
| } |
| |
| List<TokenName> usedNames = tokens |
| .where((TokenName a) => a._rc > 0) |
| .toList(); |
| usedNames.sort(compareReferenceCount); |
| for (var token in usedNames) { |
| token.finalize(); |
| } |
| } |
| } |