1#! /usr/bin/env node
2
3"use strict";
4
5var U2 = require("../tools/node");
6var fs = require("fs");
7var yargs = require("yargs");
8var ARGS = yargs
9    .describe("o", "Output file")
10    .argv;
11var files = ARGS._.slice();
12var output = {
13    vars: {},
14    props: {}
15};
16
17if (ARGS.o) try {
18    output = JSON.parse(fs.readFileSync(ARGS.o, "utf8"));
19} catch(ex) {}
20
21files.forEach(getProps);
22
23if (ARGS.o) {
24    fs.writeFileSync(ARGS.o, JSON.stringify(output, null, 2), "utf8");
25} else {
26    console.log("%s", JSON.stringify(output, null, 2));
27}
28
29function getProps(filename) {
30    var code = fs.readFileSync(filename, "utf8");
31    var ast = U2.parse(code);
32
33    ast.walk(new U2.TreeWalker(function(node){
34        if (node instanceof U2.AST_ObjectKeyVal) {
35            add(node.key);
36        }
37        else if (node instanceof U2.AST_ObjectProperty) {
38            add(node.key.name);
39        }
40        else if (node instanceof U2.AST_Dot) {
41            add(node.property);
42        }
43        else if (node instanceof U2.AST_Sub) {
44            addStrings(node.property);
45        }
46    }));
47
48    function addStrings(node) {
49        var out = {};
50        try {
51            (function walk(node){
52                node.walk(new U2.TreeWalker(function(node){
53                    if (node instanceof U2.AST_Seq) {
54                        walk(node.cdr);
55                        return true;
56                    }
57                    if (node instanceof U2.AST_String) {
58                        add(node.value);
59                        return true;
60                    }
61                    if (node instanceof U2.AST_Conditional) {
62                        walk(node.consequent);
63                        walk(node.alternative);
64                        return true;
65                    }
66                    throw out;
67                }));
68            })(node);
69        } catch(ex) {
70            if (ex !== out) throw ex;
71        }
72    }
73
74    function add(name) {
75        output.props[name] = true;
76    }
77}
78