google / closure-compiler

A JavaScript checker and optimizer.
https://developers.google.com/closure/compiler/
Apache License 2.0
7.38k stars 1.15k forks source link

ADVANCED_OPTIMIZATIONS compilation option makes Uncaught TypeError: Cannot read property 'length' of undefined #1863

Closed doom-fr closed 8 years ago

doom-fr commented 8 years ago

I have an error when I am compiling lastest paper-core.js (v0.9.25) and my ultra simple script with Closure Compiler and ADVANCED_OPTIMIZATIONS option :

test-bug-minification.min.js:230 Uncaught TypeError: Cannot read property 'length' of undefined
test-bug-minification.min.html:8 Uncaught ReferenceError: Test is not defined

In some previous tests, the log is more verbose (if it could help) :

test-bug-minification.min.js:230 Uncaught TypeError: Cannot read property 'length' of undefined
k @ test-bug-minification.min.js:230
b.extend.g @ test-bug-minification.min.js:239
(anonymous function) @ test-bug-minification.min.js:238
(anonymous function) @ test-bug-minification.min.js:1
test-bug-minification.min.html:8 Uncaught ReferenceError: Test is not defined

All goes well with SIMPLE_OPTIMIZATIONS option. Errors appear only with ADVANCED_OPTIMIZATIONS option.

As paperjs is a great but big library, I don't know from what line it cames from (source map has not doing miracles).

Here is my files (also attached bug paperjs compilation with closure.zip ) :

my no-minified html :

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
            <script src="test-bug-minification.js"></script>
            <script src="paper-core.js"></script>
            <script>
                test=null;
                window.onload=function() { test=new Test('myCanvas'); }
            </script>
        </head>
    <body>
        <canvas id="myCanvas" resize>Sorry no &lt;canvas&gt;.</canvas>
    </body>
</html>

my no-minified js :

function Test(canvas) {
    paper.setup(document.getElementById(canvas));
    var path = new paper.Path();
    path.strokeColor = 'black';
    var start = new paper.Point(100, 100);
    path.moveTo(start);
    path.lineTo(start.add([ 200, -50 ]));
    path.lineTo(start.add([ 200, 150 ]));
    paper.view.draw();
    }

// for closure
window['Test'] = Test;

my html for minified js :

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <script src="test-bug-minification.min.js"></script>
        <script>
            test=null;
            window.onload=function() { test=new Test('myCanvas'); }
        </script>
        </head>
    <body>
        <canvas id="myCanvas" resize>Sorry no &lt;canvas&gt;.</canvas>
    </body>
</html>

Compilation with latest version of closure compiler (v20160619) : java -jar compiler.jar --compilation_level=ADVANCED_OPTIMIZATIONS --js paper-core.js test-bug-minification.js --js_output_file test-bug-minification.min.js

using Google Chrome Version 51.0.2704.103 m (64-bit)

concavelenz commented 8 years ago

Did you try using --debug to create a more readible version of the output? Have you also read the limitation impose by advance optimizations here:

https://developers.google.com/closure/compiler/docs/limitations

doom-fr commented 8 years ago

I have already compiled with the --debug option. the resulted error line is : $arg$$15$$.alpha}this.$__read$&&$type$$114$$&&($read$$1$$=1)}this.$_type$=$type$$114$$||"rgb";this.$_id$=$UID$$.get(Color$$1);if(!$cached$$inline_32_components$$2_data$$inline_33_l$$inline_31_match$$inline_27$$)for(this.$_components$=$cached$$inline_32_components$$2_data$$inline_33_l$$inline_31_match$$inline_27$$=[],$argType_parsers_point$$80_value$$inline_30$$=$componentParsers$$[this.$_type$],$components$$inline_28_i$$137_slice_string$$inline_26$$=0,$args$$8_i$$inline_29_l$$79_length$$38$$=$argType_parsers_point$$80_value$$inline_30$$.length;$components$$inline_28_i$$137_slice_string$$inline_26$$<

But What to do with this ?? The error occurred in the source of paperjs and I am not enough expert in javascript to point the problem.

What I can say is that my compilation command line returns no error and no warning. As I think that Closure warn if some code does not meet limitations (it does ?), I deduce that the problem was in Closure Compiler. But maybe I am wrong.

concavelenz commented 8 years ago

No, it can not warn in all cases or most cases where the limitations are violated. For instance, it is impossible to know that an property needed by external code was exported (deval'd code).

You may wish to disable the type based optimizations (--use_types_for_optimizations=false or something like that).

Generally, speaking the VERBOSE warnings/errors are to improve maintainability and do not enable optimizations (good typing can improve optimizations). You may wish to speak to the library authors and let them know of your interest in having advance mode compatibility and perhaps they can help you.

doom-fr commented 8 years ago

has tried your advice --use_types_for_optimization false, but nothing works better.

has tried also the verbose (--warning_level=VERBOSE) and some warnings and 3 errors come out :

paper-core.js:1079: WARNING - Redeclared variable: count
                        var count = Numerical.solveQuadratic(a, b1, c2, roots, min, max);
                            ^
paper-core.js:2943: WARNING - Redeclared variable: name
                        name = '_' + name;
                        ^
paper-core.js:5228: WARNING - Redeclared variable: selected
                        selected = !!selected,
                        ^
paper-core.js:6928: WARNING - Redeclared variable: path
                        path;
                        ^
paper-core.js:7296: WARNING - Redeclared variable: index
                        index = append ? segments.length : index;
                        ^
paper-core.js:7411: WARNING - Redeclared variable: curves
                                curves = curves.splice(index, amount);
                                ^
paper-core.js:8241: WARNING - Redeclared variable: through
                                through = middle.add(middle.subtract(from).rotate(
                                ^
paper-core.js:8251: WARNING - Redeclared variable: clockwise
                                        clockwise = !!Base.read(arguments),
                                        ^
paper-core.js:10048: WARNING - Redeclared variable: i
                                i = hsbIndices[i],
                                ^
paper-core.js:10737: WARNING - Redeclared variable: value
                                var value = this._values[key];
                                    ^
paper-core.js:12220: WARNING - Redeclared variable: l
                var l = getLum(dr, dg, db),
                    ^
paper-core.js:232: ERROR - variable module is undeclared
if (typeof module !== 'undefined')
           ^
paper-core.js:11076: ERROR - variable Stats is undeclared
                                && typeof Stats !== 'undefined') {
                                          ^
paper-core.js:13368: ERROR - variable define is undeclared
if (typeof define === 'function' && define.amd) {
           ^
3 error(s), 11 warning(s)

I have opened the library code and there seems to be effectively a problem with the redeclared variables (will say it to the authors). I have patch the warnings in a local copy.

But I don't know how to work around the problem with the typeof. How should we test an undeclared variable in closure ?

Thx for your help.

concavelenz commented 8 years ago

redeclared and undeclared variables aren't going to break any of the optimizations, they just commonly indicate typos.

doom-fr commented 8 years ago

yep, but with the --warning_level=VERBOSE the compiled file isn't create (without, it is created). Expected as the undeclared variables are detected as errors, but abnormal.

In fact, it seems that paperjs does not meet closure compiler limitations (they don't want to). So my first problem is maybe not an issue of closure compiler (but there's one with the verbose option. no?).