blob: b1a2cd7f47ebefa9b594907a3b2422585ed034aa [file] [log] [blame] [edit]
// 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();
}
}
}