Search code examples
javascriptgoogle-closure-compilergoogle-closurekineticjs

Google Closure and generated getters/setters


I'm trying to get KineticJS to work with Google Closure Compiler. KineticJS, however, generated it's getters & setters based on the name of the variables.

Something like this:

// add getter and setter methods
Kinetic.Node.addSetters = function(constructor, arr) {
    for(var n = 0; n < arr.length; n++) {
        var attr = arr[n];
        this._addSetter(constructor, attr);
    }
};
Kinetic.Node.addGetters = function(constructor, arr) {
    for(var n = 0; n < arr.length; n++) {
        var attr = arr[n];
        this._addGetter(constructor, attr);
    }
};
Kinetic.Node.addGettersSetters = function(constructor, arr) {
    this.addSetters(constructor, arr);
    this.addGetters(constructor, arr);
};
Kinetic.Node._addSetter = function(constructor, attr) {
    var that = this;
    var method = 'set' + attr.charAt(0).toUpperCase() + attr.slice(1);
    constructor.prototype[method] = function() {
        var arg;
        if(arguments.length == 1) {
            arg = arguments[0];
        }
        else {
            arg = Array.prototype.slice.call(arguments);
        }
        var obj = {};
        obj[attr] = arg;
        this.setAttrs(obj);
    };
};
Kinetic.Node._addGetter = function(constructor, attr) {
    var that = this;
    var method = 'get' + attr.charAt(0).toUpperCase() + attr.slice(1);
    constructor.prototype[method] = function(arg) {
        return this.attrs[attr];
    };
};
// add getters setters
Kinetic.Node.addGettersSetters(Kinetic.Node, ['x', 'y', 'scale', 'rotation', 'opacity', 'name', 'id', 'offset', 'draggable', 'dragConstraint', 'dragBounds', 'listening']);

so, with the addGettersSetters method you generate getters & setters based on the names of the variables.

Google closure can't interpret this however, and gives warning (not error, just warnings, but still...): WARNING - Property setImage never defined on Kinetic.Image

I could add externs to for each getter & setter. Alternatively I could rewrite all the getter/setter stuff, to make it actual methods (non-generated ones) by hand. That last part seems the best, since then Closure can optimize those and do some magic with it (I hope.) Though that would be quite a bit of work, so I was wondering, is it possible to run my program, so it generates the getters & setters, and then extracting them? Or, if someone has a better idea, that's welcome too.

Thanks! -Pablo


Solution

  • Which answer is best depends on which compilation mode you are using and how you are the library.

    If you are using ADVANCED mode and compiling the library with your other sources, rewriting is likely best (I assume this is what you are trying to do currently). However, if you are loading the library separately or concatenating the library source to your ADVANCED compiled source, extern definitions are a good option (this is a good approach if library maintainers don't support Closure Compiler ADVANCED compilation).

    There are various tools that people have created to help auto-generate externs for libraries but it usually best if someone creates the externs and maintains them with the library. Some library externs are hosted in the Closure Compiler source repository and maintained by the community so that is always an option.