Why doesn't the Closure compiler shorten this?

I'm not sure if this is just a bug or an intended function.

Basically, I have this tiny function (now I see that end is blue, but it works fine, if I rename it to something else, I still have a problem):

 function f(a, b) { var start = Math.min(a, b); var end = Math.max(a, b); tb.selectionStart = start; tb.selectionEnd = end; }; 

When compiling with close I get:

 function f(a,b){var c=Math.max(a,b);tb.selectionStart=Math.min(a,b);tb.selectionEnd=c}; 

However, why is selectionStart set to Math.min directly, and selecitonEnd set to variable ( c ), which is declared first? Shorter to do tb.selectionEnd=Math.max(a,b) ?

Any ideas are welcome.

+4
source share
2 answers

EDIT: THIS LINK is "OFFICIAL" ANSWER: https://web.archive.org/web/20151226143155/http://code.google.com/p/closure-compiler/issues/detail?id=410

I think the assignment of a variable, followed immediately by the use of this variable, can be inlined. However, if there is any statement between them that cannot be proved without side effects, then the compiler will not embed it.

In your case, assigning the variable "start" is separated from using "start" only by the assignment operator "end". However, this statement has no side effects, since Math.max is an internal function, and the compiler knows that it has no side effects.

However, in your case the assignment of the variable "end" is separated from the use of this variable by the operator, which is the assignment of the "start" property. Now, I believe that the compiler does not assume that simply assigning a property is always without side effects; this is because some properties, when assigned, actually cause different behavior or change the global state (for example, RegExp). On some systems, property assignment actually triggers certain system functions (for example, a hardware interface), which, in turn, may contain side effects.

This is why sometimes when you have code like this:

 foo.bar = 1; foo.bar = 2; foo.bar = 3; 

The compiler will not delete the first two statements, as the assignment of "bar" can have side effects.

So, in your question, the variable "end" cannot be embedded, because the tb.selectionStart = start; may have side effects (perhaps only in strange cases).

If you make "tb" a local variable, or something that the compiler has full control (for example, a simple object: var tb = {}; ), then you will find that the compiler embeds all assignments perfectly.

+4
source

if you paste this code it works.

 function f(a, b) { var start = Math.min(a, b); tb.selectionStart = start; var end = Math.max(a, b); tb.selectionEnd = end; }; 

function f(a,b){tb.selectionStart=Math.min(a,b);tb.selectionEnd=Math.max(a,b)};

i is a fault compiler error.

+3
source

Source: https://habr.com/ru/post/1346906/


All Articles