Эвристическое переименование свойств
Где-то посередине между продвинутым и обычным сжатием находится эвристическое переименование.
При его использовании Google Closure Compiler переименует все свойства объекта и прототипа, кроме тех, которые начинаются с _подчеркивания.
Эти свойства оптимизатор считает публичными (да-да, не приватными а публичными) и не переименует вообще.
Например, объявим класс Animal . Он будет состоять из конструктора и методов в прототипе.
/** @constructor */
function Animal() { }
Animal.prototype = {
speed: 10,
calculateDistance: function(time, speed) {
return time*speed;
},
_setSpeed: function(speed) {
this.speed = speed
},
_run: function(time) {
alert(this.calculateDistance(time, this.speed))
}
}
После обычной оптимизации:
function Animal() {
}
Animal.prototype = {speed:10, calculateDistance:function(a, b) {
return a * b
}, _setSpeed:function(a) {
this.speed = a
}, _run:function(a) {
alert(this.calculateDistance(a, this.speed))
}};
После оптимизации с эвристическим переименованием:
function Animal() {
}
Animal.prototype = {a:10, b:function(a, b) {
return a * b
}, _setSpeed:function(a) {
this.a = a
}, _run:function(a) {
alert(this.b(a, this.a))
}};
Как видите, все свойства, кроме _setSpeed , _run были переименованы.
При этом компилятор учел, что speed переименовано в a и также переименовал this.speed в this.a .
Оптимизация касается прототипов и объектов в литеральной нотации {prop: 'val', ...} .
Для определения, какие свойства экспортируемые, а какие нет, Closure Compiler использует класс GoogleCodingConvention, метод isExported которого можно поменять на удобный вам. Например, наоборот сделать экспортируемыми методы без подчеркивания.
Переименованием занимается класс RenamePrototypes, логика методов canRenamePrototypeProperty и canRenameObjLitProperty также в вашем распоряжении.
Чтобы включить эвристическое переименование, можно создать соответствующий флаг.
Этот флаг включен в сборку MyCompiler под именем property_renaming_policy :
--property_renaming_policy=AGGRESSIVE_HEURISTIC
Есть также значение HEURISTIC, но в нем вообще мало смысла, даже рассматривать нет резона.
Продвинутый режим сжатия не совместим (и его не стоит использовать) с эвристическим переименованием, так как он представляет собой следующую ступень агрессивности - переименовывает все подряд.
То есть, по возрастающей идут:
- Простая оптимизация - сжимаются локальные свойства.
- Эвристическое переименование (при простой оптимизации) - дополнительно сжимаются все свойства, кроме начинающихся с подчеркивания.
- Продвинутая оптимизация - сжимается все.
Возможно, эвристическое переименование было промежуточным этапом в разработке компилятора, до продвинутой оптимизации.
Мне было интересно разобраться в этом режиме, но сложно придумать ему применение. Если вам придет в голову что-то дельное - напишите
|
попробовал я --property_renaming_policy=AGGRESSIVE_HEURISTIC
на моем проекте вываливается с ошибкой "ERROR - Rename prototypes and inline variables cannot be used together"
в сорцах нашел упоминание
if (isInliningForbidden()) {
// In old renaming schemes, inlining a variable can change whether
// or not a property is renamed. This is bad, and those old renaming
// schemes need to die.
return new ErrorPass(compiler, CANNOT_USE_PROTOTYPE_AND_VAR);
Видимо вы врубили одновременно ADVANCED оптимизацию.
Подтверждаю - если при компиляции указаны опции AGGRESSIVE_HEURISTIC или HEURISTIC - не работает и вываливается с той же ошибкой.
ERROR - Rename prototypes and inline variables cannot be used together
--compilation_level SIMPLE_OPTIMIZATIONS
В режиме же
--compilation_level WHITESPACE_ONLY
просто ничего не делается.
Закомментировал вызовы isInliningForbidden - все равно ничего не происходит. Опция совершенно мёртвенькая.
В какой версии это ещё работало?