Conversation
dfaedc7 to
e36e622
Compare
| console.log(++CONFIG.VALUE); | ||
| console.log(++CONFIG["VAL" + "UE"]); | ||
| console.log(++DEBUG[CONFIG.VALUE]); | ||
| CONFIG.VALUE.FOO = "bar"; |
There was a problem hiding this comment.
This leads to a nonsensical replacement 42..FOO - could you replace it with something that works - be it another variable or an object literal or something?
There was a problem hiding this comment.
Fixed - now behaves the same way as #1467.
|
If this PR incorporates the same tests as PR #1467 and addresses the same issues and does not rely on |
|
I noticed that this works: but the reverse does not: It's it's too difficult to fix we can drop the arbitrary node replacement feature altogether and just stick to replacing constants and literals. |
|
@alexlamsl By the way, these PRs are really impressive. Just tell me when you think I'm asking for an unreasonable feature. |
|
@kzc as long as you are willing to test and point out areas of bugs / improvements, I'm happy to give it a go 😉 While making fixes to #1467, I noticed there is a fundamental difference between So this is a reboot of the efforts, separating #1425 (best-effort basis) with Let me try and address the two issues you've mentioned above, and if successful, I'll close out #1467. |
| options = { | ||
| global_defs: { DEBUG: 0 } | ||
| } | ||
| input: { |
There was a problem hiding this comment.
Please add this to the beginning of input:
const DEBUG = true;
It should also generate a warning.
Could you also add OTHER: 1 to global_defs and the following line to the test:
var OTHER;
To ensure it also produces a warning.
There was a problem hiding this comment.
It would generate a warning, plus killing all the positive cases below (because they are no longer AST_SymolRef.undeclared() 😅
There was a problem hiding this comment.
I'll pick two OTHER variables as you suggested then.
There was a problem hiding this comment.
You could name it something else. Just curious what happens to variable declarations that are set and not set.
There was a problem hiding this comment.
Having const DEBUG = false; at the top of the file and overriding it with --define DEBUG=true (or vice versa) would be a common use case. It would work well with -c toplevel.
There was a problem hiding this comment.
Overriding the definition would be ideal if you don't mind the extra work.
There was a problem hiding this comment.
Okay, I'll go with the warning option then.
That's fine too.
There was a problem hiding this comment.
Overriding the definition would be ideal
Should we be limiting this override to top-level-defined variables or at any scopes?
There was a problem hiding this comment.
So this is an interesting case to consider:
global_defs: { "config.DEBUG" : 1 }
var config = { engine: "voom!" };
if (config.DEBUG) {
log();
}Should we override the value and/or raise a warning, or something else altogether?
There was a problem hiding this comment.
I've added those tests to this PR to reflect the current behaviour. Please leave comments on what you expect each case to be and we'll go from there?
| x = DEBUG; | ||
| } | ||
| expect: { | ||
| const ENV = 3; |
There was a problem hiding this comment.
overriding const ENV should warn.
| } | ||
| expect: { | ||
| const ENV = 3; | ||
| var FOO = 4; |
There was a problem hiding this comment.
overriding var FOO should warn.
One could argue in this specific case if it is set to the same value (4) it shouldn't - but that's too much work.
test/compress/global_defs.js
Outdated
| } | ||
| expect: { | ||
| const FOO = { BAR: 0 }; | ||
| console.log(FOO.BAR); |
There was a problem hiding this comment.
This is a tricky case. But since FOO is known to be global I think FOO.BAR should be changed to 0.
Had FOO been a local variable or parameter, then it would have been left as is.
There was a problem hiding this comment.
So do you mean no changes to current behaviour is required for this case?
There was a problem hiding this comment.
If FOO is global - which it is in this test case - then FOO.BAR should be changed to 0.
There was a problem hiding this comment.
Ah I see - the FOO.BAR ➡️ 0 optimisation goes under #1425. I'll add unsafe here to enable it then.
There was a problem hiding this comment.
Interesting side effect. That wasn't my intention. Even if FOO was declared as const FOO = null; I was thinking that since FOO is global then FOO.BAR is fair game to be replaced with the global_defs setting.
There was a problem hiding this comment.
I'm slightly confused now - FOO.BAR is defined as "moo" In global_defs, so do you mean you want that instead of 0?
There was a problem hiding this comment.
PTAL at e88acb4 and see if that matches what you mean?
There was a problem hiding this comment.
I think the new test and behavior is correct.
| } | ||
|
|
||
| (function (def){ | ||
| AST_Node.DEFMETHOD("resolve_defines", function(compressor) { |
There was a problem hiding this comment.
To speed this up when global_defs are not defined:
if (!compressor.option("global_defs")) return null;
lib/compress.js
Outdated
| }); | ||
| def(AST_SymbolRef, function(compressor, suffix){ | ||
| if (!this.undeclared()) return; | ||
| var name = this.name + suffix; |
lib/compress.js
Outdated
| if (!this.undeclared()) return; | ||
| var name = this.name + suffix; | ||
| var defines = compressor.option("global_defs"); | ||
| if (defines && HOP(defines, name)) { |
There was a problem hiding this comment.
-
if (defines && HOP(defines, (name = this.name + suffix))) {
|
@kzc you may have discovered a bug / missing feature in #1469 (comment) |
| } | ||
| input: { | ||
| function f(CONFIG) { | ||
| return CONFIG.VALUE; |
There was a problem hiding this comment.
add comment: // CONFIG not global - do not replace
| } | ||
| function g() { | ||
| var CONFIG = { VALUE: 1 }; | ||
| return CONFIG.VALUE; |
There was a problem hiding this comment.
add comment: // CONFIG not global - do not replace
| } | ||
| input: { | ||
| function f(CONFIG) { | ||
| return CONFIG.VALUE; |
There was a problem hiding this comment.
add comment: // CONFIG not global - do not replace
| } | ||
| function g() { | ||
| var CONFIG = { VALUE: 1 }; | ||
| return CONFIG.VALUE; |
There was a problem hiding this comment.
add comment: // CONFIG not global - do not replace
|
(Travis CI timed out.) |
|
I think we have keep backwards compatibility with But this seems inconsistent to me. ENV is global in both cases, but only in the former case is it replaced. So if we are to keep backwards compatibility then we can't have a global What's the logic governing the current behavior in master? |
|
Both So this PR current is backward compatible with |
It's probably prudent to retain this behavior in 2.x and revisit the logic in 3.x. If the variable is declared in 2.x, then no substitutions can take place at all - correct? Hmm. I wonder if any code in the wild would break since using the |
Except for the expanded syntax, e.g.
I'm wondering about that too - the |
|
I tend to agree. A case could easily be made to allow @avdg, @rvanvelzen Do you have an opinion on this? |
c7c7218 to
af34265
Compare
|
Squashed all the previous commits, and added one to demonstrate the potential breaking change we've discussed. FWIW, I'd vote towards including the change as it seems to be the expected behaviour, but I'm fine with it either way. |
|
LGTM |
|
LGTM unless there are coverage holes (which is a hard question anyway now especially without cover analysis). But there are many tests in already :-) |
- support arrays, objects & AST_Node - support `"a.b":1` on both cli & API - emit warning if variable is modified - override top-level variables fixes mishoo#1416 closes mishoo#1198
1f52b51 to
7c4bf9d
Compare
- support arrays, objects & AST_Node - support `"a.b":1` on both cli & API - emit warning if variable is modified - override top-level variables fixes mishoo#1416 closes mishoo#1198 closes mishoo#1469
This is an alternative approach to #1467, incorporating the feature to substitute
AST_Nodewhen supplied via command-line (API also supported, but a bit messier).This PR also has the advantage of not relying on #1425 thus not requiring
unsafeto function for expanded property syntax, i.e.process.engine="V8"now works with default compress options.Included (slightly modified) all the tests from #1467, added cli mocha tests for #1467 (comment)
/cc @kzc