blob: 19b483ee30ac175c3047e35edd062901ebc95f76 [file] [log] [blame]
// 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 js_backend.namer;
class FrequencyBasedNamer extends Namer
with _MinifiedFieldNamer, _MinifiedOneShotInterceptorNamer
implements jsAst.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
jsAst.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
jsAst.Name instanceFieldPropertyName(FieldEntity element) {
jsAst.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);
usedNames.forEach((TokenName token) => token.finalize());
}
}