Skip to content

Commit 24d81ff

Browse files
committed
Pre-merge
1 parent b8a8f3c commit 24d81ff

File tree

4 files changed

+97
-45
lines changed

4 files changed

+97
-45
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
node_modules
22
npm-debug.log
3+
.idea/

Diff for: Preprocessor.js

+58-44
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,18 @@
4747
this.baseDir = typeof baseDirOrIncludes == 'string' ? baseDirOrIncludes : ".";
4848

4949
/**
50-
* Included sources by filename.
51-
* @type {Object.<string, string>}
50+
* Current base directory.
51+
* @type {string}
52+
* @expose
5253
*/
53-
this.includes = typeof baseDirOrIncludes == 'object' ? baseDirOrIncludes : {};
54+
this.dir = this.baseDir;
5455

5556
/**
56-
* Whether running inside of node.js or not.
57-
* @type {boolean}
57+
* Included sources by filename.
58+
* @type {!Object.<string, string>}
5859
* @expose
5960
*/
60-
this.isNode = (typeof window == 'undefined' || !window.window) && typeof require == 'function';
61+
this.includes = typeof baseDirOrIncludes == 'object' ? baseDirOrIncludes : {};
6162

6263
/**
6364
* Error reporting source ahead length.
@@ -67,12 +68,21 @@
6768
this.errorSourceAhead = 50;
6869

6970
/**
70-
* Runtime defines.
71-
* @type {Array.<string>}
71+
* Defines.
72+
* @type {!Object.<string>}
73+
* @expose
7274
*/
73-
this.defines = [];
75+
this.defines = {};
7476
};
7577

78+
/**
79+
* Whether running under node.js or not.
80+
* @type {boolean}
81+
* @const
82+
* @expose
83+
*/
84+
Preprocessor.IS_NODE = (typeof window === 'undefined' || !window.window) && typeof require === 'function' && typeof process === 'object' && typeof process.nextTick === 'function';
85+
7686
/**
7787
* Definition expression
7888
* @type {!RegExp}
@@ -107,7 +117,7 @@
107117
* #define EXPRESSION
108118
* @type {!RegExp}
109119
*/
110-
Preprocessor.DEFINE = /define[ ]+([^\n]+)\r?(?:\n|$)/g;
120+
Preprocessor.DEFINE = /define[ ]+([^ ]+)[ ]+([^\n]+)\r?(?:\n|$)/g;
111121

112122
/**
113123
* @type {!RegExp}
@@ -170,38 +180,33 @@
170180

171181
/**
172182
* Evaluates an expression.
173-
* @param {object.<string,string>} runtimeDefines Runtime defines
174-
* @param {Array.<string>|string} inlineDefines Inline defines (optional for backward compatibility)
175183
* @param {string=} expr Expression to evaluate
176184
* @return {*} Expression result
177185
* @throws {Error} If the expression cannot be evaluated
178186
* @expose
179187
*/
180-
Preprocessor.evaluate = function(runtimeDefines, inlineDefines, expr) {
181-
if (typeof inlineDefines === 'string') {
182-
expr = inlineDefines;
183-
inlineDefines = [];
184-
}
185-
var addSlashes = Preprocessor.addSlashes;
186-
return (function(runtimeDefines, inlineDefines, expr) {
187-
for (var key in runtimeDefines) {
188-
if (runtimeDefines.hasOwnProperty(key)) {
189-
eval("var "+key+" = \""+addSlashes(""+runtimeDefines[key])+"\";");
190-
}
191-
}
192-
for (var i=0; i<inlineDefines.length; i++) {
193-
var def = inlineDefines[i];
194-
if (def.substring(0,9) != 'function ' && def.substring(0,4) != 'var ') {
195-
def = "var "+def; // Enforce local
196-
}
197-
eval(def);
198-
}
199-
return eval(expr);
200-
}).bind(null)(runtimeDefines, inlineDefines, expr);
188+
Preprocessor.evaluate = function(expr) {
189+
// Potentially this is dangerous but as we don't want to write a special interpreter, it must be good enough.
190+
if (expr.indexOf(";") >= 0)
191+
throw(new Error("Illegal expression: "+expr));
192+
return eval("(function() { return "+expr+" }()"); // May also throw
193+
};
194+
195+
/**
196+
* Processes the specified sources using the given parameters.
197+
* @param {string} source Source to process
198+
* @param {string|Object.<string,string>=} baseDirOrIncludes Source base directory used for includes (node.js only)
199+
* or an object containing all the included sources by filename. Defaults to the current working directory.
200+
* @param {object.<string,string>} defines Defines
201+
* @param {function(string)=} verbose Print verbose processing information to the specified function as the first parameter. Defaults to not print debug information.
202+
* @returns {string}
203+
*/
204+
Preprocessor.process = function(source, baseDirOrIncludes, defines, verbose) {
205+
return new Preprocessor(source, baseDirOrIncludes).process(defines, verbose);
201206
};
202207

203208
/**
204-
* Preprocesses.
209+
* Processes this instances sources.
205210
* @param {object.<string,string>} defines Defines
206211
* @param {function(string)=} verbose Print verbose processing information to the specified function as the first parameter. Defaults to not print debug information.
207212
* @return {string} Processed source
@@ -212,6 +217,14 @@
212217
defines = defines || {};
213218
verbose = typeof verbose == 'function' ? verbose : function() {};
214219
verbose("Defines: "+JSON.stringify(defines));
220+
221+
var defs = {};
222+
for (var i in this.defines) // Inline defines
223+
if (this.defines.hasOwnProperty(i))
224+
defs[i] = this.defines[i];
225+
for (i in defines) // Runtime defines
226+
if (defines.hasOwnProperty(i))
227+
defs[i] = this.defines[i];
215228

216229
var match, match2, include, p, stack = [];
217230
while ((match = Preprocessor.EXPR.exec(this.source)) !== null) {
@@ -234,7 +247,7 @@
234247
include = this.includes[include];
235248
}
236249
} else { // Load it if in node.js...
237-
if (!this.isNode) {
250+
if (!Preprocessor.IS_NODE) {
238251
throw(new Error("Failed to resolve include: "+this.baseDir+"/"+include));
239252
}
240253
try {
@@ -249,7 +262,7 @@
249262
include = '';
250263
for (var i=0; i<files.length; i++) {
251264
verbose(' incl: '+files[i]);
252-
var contents = fs.readFileSync(files[i])+"";
265+
var contents = fs.readFileSync(files[i])+"\n"; // One new line between files
253266
_this.includes[key] = contents;
254267
include += contents;
255268
}
@@ -274,7 +287,7 @@
274287
}
275288
include = match2[1];
276289
verbose(" expr: "+match2[1]);
277-
include = Preprocessor.evaluate(defines, this.defines, match2[1]);
290+
include = Preprocessor.evaluate(defs, match2[1]);
278291
verbose(" value: "+Preprocessor.nlToStr(include));
279292
this.source = this.source.substring(0, match.index)+indent+include+this.source.substring(Preprocessor.PUT.lastIndex);
280293
Preprocessor.EXPR.lastIndex = match.index + include.length;
@@ -289,11 +302,11 @@
289302
}
290303
verbose(" test: "+match2[2]);
291304
if (match2[1] == "ifdef") {
292-
include = !!defines[match2[2]];
305+
include = typeof defs[match2[2]] !== 'undefined';
293306
} else if (match2[1] == "ifndef") {
294-
include = !defines[match2[2]];
307+
include = typeof defs[match2[2]] === 'undefined';
295308
} else {
296-
include = Preprocessor.evaluate(defines, this.defines, match2[2]);
309+
include = Preprocessor.evaluate(defines, match2[2]);
297310
}
298311
verbose(" value: "+include);
299312
stack.push(p={
@@ -333,7 +346,7 @@
333346
if (match2[1] == 'else') {
334347
include = !before["include"];
335348
} else {
336-
include = Preprocessor.evaluate(defines, this.defines, match2[2]);
349+
include = Preprocessor.evaluate(defs, match2[2]);
337350
}
338351
stack.push(p={
339352
"include": !before["include"],
@@ -349,9 +362,10 @@
349362
if ((match2 = Preprocessor.DEFINE.exec(this.source)) === null) {
350363
throw(new Error("Illegal #"+match[2]+": "+this.source.substring(match.index, match.index+this.errorSourceAhead)+"..."));
351364
}
352-
var define = match2[1];
353-
verbose(" def: "+match2[1]);
354-
this.defines.push(define);
365+
var defineName = match2[1],
366+
defineValue = match2[2];
367+
verbose(" def: "+defineName+" "+defineValue);
368+
defs[defineName] = defineValue;
355369
this.source = this.source.substring(0, match.index)+indent+this.source.substring(Preprocessor.DEFINE.lastIndex);
356370
Preprocessor.EXPR.lastIndex = match.index;
357371
verbose(" continue at "+Preprocessor.EXPR.lastIndex);

Diff for: externs/Preprocessor.js

+35
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
*/
3434
var Preprocessor = function(source, baseDir) {};
3535

36+
/**
37+
* @type {boolean}
38+
*/
39+
Preprocessor.IS_NODE;
40+
3641
/**
3742
* @param {string} str
3843
* @returns {string}
@@ -71,6 +76,36 @@ Preprocessor.nlToStr = function(str) {};
7176
*/
7277
Preprocessor.evaluate = function(runtimeDefines, inlineDefines, expr) {};
7378

79+
/**
80+
* @type {string}
81+
*/
82+
Preprocessor.prototype.source;
83+
84+
/**
85+
* @type {string}
86+
*/
87+
Preprocessor.prototype.baseDir;
88+
89+
/**
90+
* @type {string}
91+
*/
92+
Preprocessor.prototype.dir;
93+
94+
/**
95+
* @type {!Object.<string,string>}
96+
*/
97+
Preprocessor.prototype.includes;
98+
99+
/**
100+
* @type {number}
101+
*/
102+
Preprocessor.prototype.errorSourceAhead;
103+
104+
/**
105+
* @type {!Array.<string>}
106+
*/
107+
Preprocessor.prototype.defines;
108+
74109
/**
75110
* @param {Object.<string,*>} directives
76111
* @return {string}

Diff for: package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
},
1717
"keywords": ["source", "source code", "JavaScript", "ECMAScript", "preprocessor", "pre-processor", "pre processor", "processor", "utility"],
1818
"dependencies": {
19+
"glob": "~3.2"
1920
},
2021
"devDependencies": {
2122
"testjs": "latest",
@@ -32,5 +33,6 @@
3233
"make": "npm run-script compile && npm test && npm run-script jsdoc",
3334
"compile": "ccjs Preprocessor.js --create_source_map=Preprocessor.min.map --compilation_level=ADVANCED_OPTIMIZATIONS --externs=node > Preprocessor.min.js",
3435
"jsdoc": "jsdoc -c jsdoc.json"
35-
}
36+
},
37+
"preferGlobal": true
3638
}

0 commit comments

Comments
 (0)