Esempio n. 1
0
function build_kendo(options) {
    var kcomp = get_kendo_config().components;
    var selection = [];
    options.components.forEach(function require(comp) {
        if (typeof comp == "string") {
            for (var i = 0; i < kcomp.length; ++i) {
                if (kcomp[i].id == comp) {
                    comp = kcomp[i];
                    break;
                }
            }
        }
        if (comp.depends) {
            comp.depends.forEach(require);
        }
        push_uniq(selection, comp.source);
    });

    var toplevel = new U2.AST_Toplevel({ body: [] });
    selection.forEach(function(filename){
        if (options.log) {
            options.log(filename);
        }
        filename = PATH.join(options.kendo_dir, filename);
        var code = FS.readFileSync(filename, { encoding: "utf8" });
        toplevel = U2.parse(code, {
            filename: filename,
            toplevel: toplevel
        });
    });

    toplevel = toplevel.transform(new U2.TreeTransformer(function before(node, descend){
        if (node === toplevel)
            return undefined;

        if (!(this.parent() instanceof U2.AST_Toplevel))
            return node;    // no point to descend.

        // discard RequireJS boilerplate
        if (node instanceof U2.AST_SimpleStatement
            && node.body instanceof U2.AST_Call
            && node.body.expression instanceof U2.AST_Conditional
            && node.body.expression.consequent instanceof U2.AST_SymbolRef
            && node.body.expression.consequent.name == "define")
            // WHOA, I should really implement some pattern matching in UglifyJS
        {
            // so if that's the case, we want to replace the whole
            // simple statement with the *body* of the function
            // that gets passed to `define`.
            var f = node.body.args[1]; // args[0] is the dependency list
            return U2.MAP.splice(f.body);
        }

        return node;
    }));

    return toplevel.print_to_string();
}
Esempio n. 2
0
function as_toplevel(input)
{
    if (input instanceof uglify.AST_BlockStatement)
        input = input.body;
    else if (input instanceof uglify.AST_Statement)
        input = [ input ];
    else throw new Error("Unsupported input syntax");
    
    var toplevel = new uglify.AST_Toplevel({ body: input });
    toplevel.figure_out_scope();
    return toplevel;
}
function extract_widget_info(ast) {
    ast = new U2.AST_Toplevel(ast);
    ast.figure_out_scope();
    var widgets = [];
    var scope = null;

    // Quick-n-dirty heuristic that should cover the use cases in Kendo.
    function dumb_eval(node) {
        if (node instanceof U2.AST_Constant) {
            return node.getValue();
        }
        if (node instanceof U2.AST_SymbolRef) {
            var init = node.definition().init;
            if (init) {
                return dumb_eval(init);
            }
            return node.name;
        }
        if (node instanceof U2.AST_Dot) {
            return dumb_eval(node.expression) + "." + node.property;
        }
        if (node instanceof U2.AST_Call && is_widget(node)) {
            return "kendo.ui.Widget.extend";
        }
        return null;        // dunno how to handle
    }

    // determine if node points to [window.]kendo.ui.SOMETHING
    function is_widget(node) {
        if (node instanceof U2.AST_Call &&
            node.expression instanceof U2.AST_Dot &&
            node.expression.property == "extend") {
            var x = dumb_eval(node.expression);
            if (!x) return false;
            return /^(window\.)?(kendo|kendo\.dataviz|kendo\.mobile)\.ui\..+?\.extend/.test(x);
        }
    }

    var tw = new U2.TreeWalker(function(node, descend){
        if (node instanceof U2.AST_Scope) {
            var save_scope = scope;
            scope = node;
            descend();
            scope = save_scope;
            return true;
        }
        if (is_widget(node)) {
            var def = node.args[0];
            var options = def.properties.filter(function(prop){
                return prop.key == "options";
            })[0];
            var events = def.properties.filter(function(prop){
                return prop.key == "events";
            })[0];
            if (events && events.value instanceof U2.AST_Array) {
                events = events.value.elements.map(function(el){
                    return dumb_eval(el);
                });
            }
            if (options) {
                var name = options.value.properties.filter(function(prop){
                    return prop.key == "name";
                })[0];
                if (name && name.value) {
                    name = name.value.value;
                    widgets.push({
                        name     : name,
                        options  : options.value.properties.map(function(prop){ return prop.key }),
                        events   : events,
                        inherits : node.expression.expression.print_to_string({ beautify: true }),
                        file     : node.start.file,
                        line     : node.start.line,
                        col      : node.start.col
                    });
                }
            }
        }
    });
    ast.walk(tw);
    return widgets;
}