diff --git a/.gitignore b/.gitignore index 93f1361..067f8e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules npm-debug.log +.idea/ diff --git a/Preprocessor.js b/Preprocessor.js index 8fa0b2d..7eedeb3 100644 --- a/Preprocessor.js +++ b/Preprocessor.js @@ -47,17 +47,18 @@ this.baseDir = typeof baseDirOrIncludes == 'string' ? baseDirOrIncludes : "."; /** - * Included sources by filename. - * @type {Object.} + * Current base directory. + * @type {string} + * @expose */ - this.includes = typeof baseDirOrIncludes == 'object' ? baseDirOrIncludes : {}; + this.dir = this.baseDir; /** - * Whether running inside of node.js or not. - * @type {boolean} + * Included sources by filename. + * @type {!Object.} * @expose */ - this.isNode = (typeof window == 'undefined' || !window.window) && typeof require == 'function'; + this.includes = typeof baseDirOrIncludes == 'object' ? baseDirOrIncludes : {}; /** * Error reporting source ahead length. @@ -67,12 +68,21 @@ this.errorSourceAhead = 50; /** - * Runtime defines. - * @type {Array.} + * Defines. + * @type {!Object.} + * @expose */ - this.defines = []; + this.defines = {}; }; + /** + * Whether running under node.js or not. + * @type {boolean} + * @const + * @expose + */ + Preprocessor.IS_NODE = (typeof window === 'undefined' || !window.window) && typeof require === 'function' && typeof process === 'object' && typeof process.nextTick === 'function'; + /** * Definition expression * @type {!RegExp} @@ -107,7 +117,7 @@ * #define EXPRESSION * @type {!RegExp} */ - Preprocessor.DEFINE = /define[ ]+([^\n]+)\r?(?:\n|$)/g; + Preprocessor.DEFINE = /define[ ]+([^ ]+)[ ]+([^\n]+)\r?(?:\n|$)/g; /** * @type {!RegExp} @@ -170,38 +180,33 @@ /** * Evaluates an expression. - * @param {object.} runtimeDefines Runtime defines - * @param {Array.|string} inlineDefines Inline defines (optional for backward compatibility) * @param {string=} expr Expression to evaluate * @return {*} Expression result * @throws {Error} If the expression cannot be evaluated * @expose */ - Preprocessor.evaluate = function(runtimeDefines, inlineDefines, expr) { - if (typeof inlineDefines === 'string') { - expr = inlineDefines; - inlineDefines = []; - } - var addSlashes = Preprocessor.addSlashes; - return (function(runtimeDefines, inlineDefines, expr) { - for (var key in runtimeDefines) { - if (runtimeDefines.hasOwnProperty(key)) { - eval("var "+key+" = \""+addSlashes(""+runtimeDefines[key])+"\";"); - } - } - for (var i=0; i= 0) + throw(new Error("Illegal expression: "+expr)); + return eval("(function() { return "+expr+" }()"); // May also throw + }; + + /** + * Processes the specified sources using the given parameters. + * @param {string} source Source to process + * @param {string|Object.=} baseDirOrIncludes Source base directory used for includes (node.js only) + * or an object containing all the included sources by filename. Defaults to the current working directory. + * @param {object.} defines Defines + * @param {function(string)=} verbose Print verbose processing information to the specified function as the first parameter. Defaults to not print debug information. + * @returns {string} + */ + Preprocessor.process = function(source, baseDirOrIncludes, defines, verbose) { + return new Preprocessor(source, baseDirOrIncludes).process(defines, verbose); }; /** - * Preprocesses. + * Processes this instances sources. * @param {object.} defines Defines * @param {function(string)=} verbose Print verbose processing information to the specified function as the first parameter. Defaults to not print debug information. * @return {string} Processed source @@ -212,6 +217,14 @@ defines = defines || {}; verbose = typeof verbose == 'function' ? verbose : function() {}; verbose("Defines: "+JSON.stringify(defines)); + + var defs = {}; + for (var i in this.defines) // Inline defines + if (this.defines.hasOwnProperty(i)) + defs[i] = this.defines[i]; + for (i in defines) // Runtime defines + if (defines.hasOwnProperty(i)) + defs[i] = this.defines[i]; var match, match2, include, p, stack = []; while ((match = Preprocessor.EXPR.exec(this.source)) !== null) { @@ -234,7 +247,7 @@ include = this.includes[include]; } } else { // Load it if in node.js... - if (!this.isNode) { + if (!Preprocessor.IS_NODE) { throw(new Error("Failed to resolve include: "+this.baseDir+"/"+include)); } try { @@ -249,7 +262,7 @@ include = ''; for (var i=0; i} + */ +Preprocessor.prototype.includes; + +/** + * @type {number} + */ +Preprocessor.prototype.errorSourceAhead; + +/** + * @type {!Array.} + */ +Preprocessor.prototype.defines; + /** * @param {Object.} directives * @return {string} diff --git a/package.json b/package.json index 2b3b30c..66085df 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ }, "keywords": ["source", "source code", "JavaScript", "ECMAScript", "preprocessor", "pre-processor", "pre processor", "processor", "utility"], "dependencies": { + "glob": "~3.2" }, "devDependencies": { "testjs": "latest", @@ -32,5 +33,6 @@ "make": "npm run-script compile && npm test && npm run-script jsdoc", "compile": "ccjs Preprocessor.js --create_source_map=Preprocessor.min.map --compilation_level=ADVANCED_OPTIMIZATIONS --externs=node > Preprocessor.min.js", "jsdoc": "jsdoc -c jsdoc.json" - } + }, + "preferGlobal": true }