New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

ifdef-loader

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ifdef-loader - npm Package Compare versions

Comparing version 2.0.3 to 2.1.0

spec/data/elif.in.js

6

package.json
{
"name": "ifdef-loader",
"version": "2.0.3",
"version": "2.1.0",
"description": "",

@@ -21,2 +21,6 @@ "main": "ifdef-loader.js",

"email": "erez@erez.pw"
},
{
"name": "Wisam Ghantous",
"url": "https://github.com/gwigwam"
}

@@ -23,0 +27,0 @@ ],

37

preprocessor.js

@@ -8,18 +8,22 @@ "use strict";

useTripleSlash = tripleSlash;
var lines = source.split('\n');
for (var n = 0;;) {
var startInfo = find_start_if(lines, n);
var pos = 0;
var lines = source;
while (true) {
var startInfo = find_start_if(lines, pos);
if (startInfo === undefined)
break;
var endLine = find_end(lines, startInfo.line);
pos = startInfo.end + 1;
var endLine = find_end(lines, pos);
if (endLine === -1) {
throw "#if without #endif in line " + (startInfo.line + 1);
throw "#if without #endif in line " + positionToLine(lines, startInfo.start);
}
var elseLine = find_else(lines, startInfo.line, endLine);
var elseLine = find_else(lines, pos, endLine);
var cond = evaluate(startInfo.condition, startInfo.keyword, defs);
var fromLine = positionToLine(lines, startInfo.start);
var toLine = positionToLine(lines, endLine.start);
if (cond) {
if (verbose) {
console.log("matched condition #" + startInfo.keyword + " " + startInfo.condition + " => including lines [" + (startInfo.line + 1) + "-" + (endLine + 1) + "]");
console.log("matched condition #" + startInfo.keyword + " " + startInfo.condition + " => including lines [" + fromLine + "-" + toLine + "]");
}
blank_code(lines, startInfo.line, startInfo.line);
blank_code(lines, startInfo.start, startInfo.end);
if (elseLine === -1) {

@@ -41,8 +45,8 @@ blank_code(lines, endLine, endLine);

if (verbose) {
console.log("not matched condition #" + startInfo.keyword + " " + startInfo.condition + " => excluding lines [" + (startInfo.line + 1) + "-" + (endLine + 1) + "]");
console.log("not matched condition #" + startInfo.keyword + " " + startInfo.condition + " => excluding lines [" + fromLine + "-" + toLine + "]");
}
}
n = startInfo.line;
pos = endLine.end;
}
return lines.join('\n');
return lines;
}

@@ -152,1 +156,12 @@ exports.parse = parse;

}
function writeChar(s, pos, ch) {
if (pos < 0 || pos > s.length - 1)
throw "out of string boundaries";
var leftPart = s.substr(0, pos);
var rightPart = s.substr(pos + 1);
var charAt = s.charAt(pos);
if (charAt === '\r' || charAt === '\n' || charAt === '\t')
return s;
return leftPart + ch + rightPart;
}
exports.writeChar = writeChar;

@@ -1,7 +0,36 @@

interface IStart {
line: number;
keyword: string;
condition: string;
/** Holds the line indexes for a complete #if block */
class IfBlock {
/**
* @param startIx Line index of #if
* @param endIx Line index of #endif
* @param elifIxs Line indexes of #elifs
* @param elseIx Line index of #else, or null
* @param innerIfs List of any IfBlocks that are contained within this IfBlock
*/
constructor(public startIx: number, public endIx: number, public elifIxs: number[] = [], public elseIx: number|null = null, public innerIfs: IfBlock[] = []) { }
getIfRange(): [number, number] {
const to = this.elifIxs.length > 0 ? this.elifIxs[0] : this.elseIx != null ? this.elseIx : this.endIx;
return [this.startIx, to];
}
getElifRange(index: number): [number, number] {
if(this.elifIxs.length > index) {
const from = this.elifIxs[index];
const to = this.elifIxs.length > index + 1 ? this.elifIxs[index + 1] : this.elseIx != null ? this.elseIx : this.endIx;
return [from, to];
} else {
throw `Invalid elif index '${index}', there are only ${this.elifIxs.length} elifs`;
}
}
getElseRange(): [number, number] {
if(this.elseIx != null) {
return [this.elseIx, this.endIx];
} else {
throw 'Cannot use elseRange when elseIx is null';
}
}
}
enum IfType { If, Elif }
let useTripleSlash: boolean|undefined;

@@ -15,54 +44,88 @@

for(let n=0;;) {
let startInfo = find_start_if(lines,n);
if(startInfo === undefined) break;
var ifBlocks = find_if_blocks(lines);
for(let ifBlock of ifBlocks) {
apply_if(lines, ifBlock, defs, verbose);
}
const endLine = find_end(lines, startInfo.line);
if(endLine === -1) {
throw `#if without #endif in line ${startInfo.line+1}`;
return lines.join('\n');
}
function find_if_blocks(lines: string[]): IfBlock[] {
const blocks: IfBlock[] = [];
for(let i = 0; i < lines.length; i++) {
if(match_if(lines[i])) {
const ifBlock = parse_if_block(lines, i);
blocks.push(ifBlock);
i = ifBlock.endIx;
}
}
return blocks;
}
const elseLine = find_else(lines, startInfo.line, endLine);
/**
* Parse #if statement at given locatoin
* @param ifBlockStart Line on which the '#if' is located. (Given line MUST be start of an if-block)
*/
function parse_if_block(lines: string[], ifBlockStart: number): IfBlock {
let foundElifs: number[] = [];
let foundElse: number|null = null;
let foundEnd: number|undefined;
let innerIfs: IfBlock[] = [];
const cond = evaluate(startInfo.condition, startInfo.keyword, defs);
for(let i = ifBlockStart + 1; i < lines.length; i++) {
const curLine = lines[i];
if(cond) {
if(verbose) {
console.log(`matched condition #${startInfo.keyword} ${startInfo.condition} => including lines [${startInfo.line+1}-${endLine+1}]`);
}
blank_code(lines, startInfo.line, startInfo.line);
if (elseLine === -1) {
blank_code(lines, endLine, endLine);
} else {
blank_code(lines, elseLine, endLine);
}
} else {
if (elseLine === -1) {
blank_code(lines, startInfo.line, endLine);
} else {
blank_code(lines, startInfo.line, elseLine);
blank_code(lines, endLine, endLine);
}
if(verbose) {
console.log(`not matched condition #${startInfo.keyword} ${startInfo.condition} => excluding lines [${startInfo.line+1}-${endLine+1}]`);
}
const innerIfMatch = match_if(curLine);
if(innerIfMatch) {
const innerIf = parse_if_block(lines, i);
innerIfs.push(innerIf);
i = innerIf.endIx;
continue;
}
n = startInfo.line;
const elifMatch = match_if(curLine, IfType.Elif);
if(elifMatch) {
foundElifs.push(i);
continue;
}
const elseMatch = match_else(curLine);
if(elseMatch) {
foundElse = i;
continue;
}
const endMatch = match_endif(curLine);
if(endMatch) {
foundEnd = i;
break;
}
}
return lines.join('\n');
if(foundEnd === undefined) {
throw `#if without #endif on line ${ifBlockStart + 1}`;
}
return new IfBlock(ifBlockStart, foundEnd, foundElifs, foundElse, innerIfs);
}
function match_if(line: string): IStart|undefined {
const re = useTripleSlash ? /^[\s]*\/\/\/([\s]*)#(if)([\s\S]+)$/g : /^[\s]*\/\/([\s]*)#(if)([\s\S]+)$/g;
const ifRegex = () => useTripleSlash ? /^[\s]*\/\/\/([\s]*)#(if|elif)([\s\S]+)$/g : /^[\s]*\/\/([\s]*)#(if|elif)([\s\S]+)$/g;
function match_if(line: string, type: IfType = IfType.If) : boolean {
const re = ifRegex();
const match = re.exec(line);
return match !== null && ((type == IfType.If && match[2] == "if") || (type == IfType.Elif && match[2] == "elif"));
}
/**
* @param line Line to parse, must be a valid #if statement
* @returns The if condition
*/
function parse_if(line: string): string {
const re = ifRegex();
const match = re.exec(line);
if(match) {
return {
line: -1,
keyword: match[2],
condition: match[3].trim()
};
return match[3].trim();
} else {
throw `Could not parse #if: '${line}'`;
}
return undefined;
}

@@ -82,54 +145,51 @@

function find_start_if(lines: string[], n: number): IStart|undefined {
for(let t=n; t<lines.length; t++) {
const match = match_if(lines[t]);
if(match !== undefined) {
match.line = t;
return match;
// TODO: when es7 write as: return { line: t, ...match };
}
}
return undefined;
}
/** Includes and excludes relevant lines based on evaluation of the provided IfBlock */
function apply_if(lines: string[], ifBlock: IfBlock, defs: object, verbose: boolean = false) {
let includeRange: [number, number]|null = null;
function find_end(lines: string[], start: number): number {
let level = 1;
for(let t=start+1; t<lines.length; t++) {
const mif = match_if(lines[t]);
const mend = match_endif(lines[t]);
const ifCond = parse_if(lines[ifBlock.startIx]);
const ifRes = evaluate(ifCond, defs);
if(mif) {
level++;
const log = (condition: string, outcome: boolean) => {
if(verbose) {
console.log(`#if block lines [${ifBlock.startIx + 1}-${ifBlock.endIx + 1}]: Condition '${condition}' is ${outcome ? 'TRUE' : 'FALSE'}. ${includeRange != null ? `Including lines [${includeRange[0] + 1}-${includeRange[1] + 1}].` : 'Excluding everything.'}`);
}
};
if(mend) {
level--;
if(level === 0) {
return t;
if(ifRes) {
includeRange = ifBlock.getIfRange();
log(ifCond, true);
} else {
for(let elifIx = 0; elifIx < ifBlock.elifIxs.length; elifIx++) {
const elifLine = lines[ifBlock.elifIxs[elifIx]];
const elifCond = parse_if(elifLine);
const elifRes = evaluate(elifCond, defs);
if(elifRes) {
includeRange = ifBlock.getElifRange(elifIx);
log(elifCond, true);
break;
}
}
}
return -1;
}
function find_else(lines: string[], start: number, end: number): number {
let level = 1;
for(let t=start+1; t<end; t++) {
const mif = match_if(lines[t]);
const melse = match_else(lines[t]);
const mend = match_endif(lines[t]);
if(mif) {
level++;
if(includeRange == null) {
if(ifBlock.elseIx != null) {
includeRange = ifBlock.getElseRange();
}
log(ifCond, false);
}
}
if(mend) {
level--;
}
if(includeRange != null) {
blank_code(lines, ifBlock.startIx, includeRange[0]);
blank_code(lines, includeRange[1], ifBlock.endIx);
} else {
blank_code(lines, ifBlock.startIx, ifBlock.endIx);
}
if (melse && level === 1) {
return t;
for(let innerIf of ifBlock.innerIfs) {
// Apply inner-if blocks only when they are not already erased
if(includeRange != null && innerIf.startIx >= includeRange[0] && innerIf.startIx <= includeRange[1]) {
apply_if(lines, innerIf, defs, verbose);
}
}
return -1;
}

@@ -140,4 +200,3 @@

*/
function evaluate(condition: string, keyword: string, defs: object): boolean {
function evaluate(condition: string, defs: object): boolean {
const code = `return (${condition}) ? true : false;`;

@@ -156,10 +215,6 @@ const args = Object.keys(defs);

if(keyword === "ifndef") {
result = !result;
}
return result;
}
function blank_code(lines: string[], start: number, end: number) {
function blank_code(lines: string[], start: number, end: number = start) {
for(let t=start; t<=end; t++) {

@@ -166,0 +221,0 @@ const len = lines[t].length;

# ifdef-loader
Webpack loader that allows JavaScript or TypeScript conditional compilation (`#if ... #else ... #endif`)
Webpack loader that allows JavaScript or TypeScript conditional compilation (`#if ... #elif ... #else ... #endif`)
directly from Webpack.

@@ -24,5 +24,15 @@

If the expression is `true` the block of code between `#if` and `#endif` is included,
otherwise is excluded by commenting it out.
If the expression is `true` the block of code between `#if` and `#endif` is included, otherwise is excluded by commenting it out.
Additionally, `#elif` and `#else` clauses can be added to an `#if` clause:
```js
/// #if env == 'PRODUCTION'
console.log('Production!');
/// #elif env == 'DEBUG'
console.log('Debug!');
/// #else
console.log('Something else!');
/// #endif
```
The `#if` clauses can also be nested:

@@ -33,4 +43,3 @@ ```js

android_code();
/// #endif
/// #if OS=="ios"
/// #elif OS=="ios"
ios_code();

@@ -41,11 +50,2 @@ /// #endif

Additionally, `#else` clauses can be defined for every `#if` clause:
```js
/// #if PRODUCTION
console.log('Production!');
/// #else
console.log('Something else!');
/// #endif
```
## Installation

@@ -83,3 +83,3 @@

// alternatively, options can be passed via query string:
const q = require('querystring').encode(opts});
const q = require('querystring').encode(opts);
/* ... */ {

@@ -86,0 +86,0 @@ test: /\.tsx?$/,

// tests again lines made of just one sigle char (https://github.com/nippur72/ifdef-loader/pull/2)
/////////////
///////////////
////////
/// #if false
function foo(){
// ...
//////////
}
/// #endif
// tests again lines made of just one sigle char (https://github.com/nippur72/ifdef-loader/pull/2)
/////////////
///////////////
////////
/// #if false
function foo(){
// ...
//////////
}
/// #endif
var a=1;
///////////////////
///////////////
/////////////////////////////
/////////////////////////////////
///////////////
/////////
/// #if version > 4
loadVersion4();
/// #if OS === "android"
android_Init_In_Version_4();
/// #endif
/// #else
loadVersion2();
//////////
/// #endif
a=a+1;
var b=1;
///////////////////
/// #if version < 4
loadVersion2();
/////////////////////////
/////////////////////////////
//////////////
/// #if OS === "ios"
IOS_Init_In_Version_2();
/// #else
Init_General();
///////////////
/////////
/////////////
//////////
/// #endif
/// #else
wontHappen();
/// #endif
b=a+1;
var a=1;
///////////////////
///////////////
/////////////////////////////
/////////////////////////////////
///////////////
/////////
/// #if version > 4
loadVersion4();
/// #if OS === "android"
android_Init_In_Version_4();
/// #endif
/// #else
loadVersion2();
//////////
/// #endif
a=a+1;
var b=1;
///////////////////
/// #if version < 4
loadVersion2();
/////////////////////////
/////////////////////////////
//////////////
/// #if OS === "ios"
IOS_Init_In_Version_2();
/// #else
Init_General();
///////////////
/////////
/////////////
//////////
/// #endif
/// #else
wontHappen();
/// #endif
b=a+1;
var a=1;
///////////////////
///////////////
/////////////////////////////
/////////////////////////////////
///////////////
//////////
/// #if version > 4
loadVersion4();
/// #if OS === "android"
android_Init_In_Version_4();
/// #endif
/// #endif
a=a+1;
var b=1;
///////////////////
/// #if version < 4
loadVersion2();
/////////////////////////
/////////////////////////////
///////////////
//////////
/// #if OS === "ios"
IOS_Init_In_Version_2();
/// #endif
/// #endif
b=a+1;
var a=1;
///////////////////
///////////////
/////////////////////////////
/////////////////////////////////
///////////////
//////////
/// #if version > 4
loadVersion4();
/// #if OS === "android"
android_Init_In_Version_4();
/// #endif
/// #endif
a=a+1;
var b=1;
///////////////////
/// #if version < 4
loadVersion2();
/////////////////////////
/////////////////////////////
///////////////
//////////
/// #if OS === "ios"
IOS_Init_In_Version_2();
/// #endif
/// #endif
b=a+1;

@@ -1,24 +0,18 @@

export default function test() {
//////////////////////////
//////////////////////////
////////////
}
var a=1;
////////////
// #if DEBUG
debug("hello");
/////////
// #endif
var b=2;
///////////////////////
// #if OS === "android"
androidInit();
/////////
// #endif
var c=3;
//////////////////
///////////////
/////////
/////////////
///////////////
////////
// #if version > 4
loadVersion4();
// #endif
// #if !DEBUG
debug("hello");
// #else
debug("or not");
/////////
// #endif

@@ -25,0 +19,0 @@ /***************** */

@@ -1,24 +0,18 @@

export default function test() {
//////////////////////////
//////////////////////////
////////////
}
var a=1;
////////////
// #if DEBUG
debug("hello");
/////////
// #endif
var b=2;
///////////////////////
// #if OS === "android"
androidInit();
/////////
// #endif
var c=3;
//////////////////
///////////////
/////////
/////////////
///////////////
////////
// #if version > 4
loadVersion4();
// #endif
// #if !DEBUG
debug("hello");
// #else
debug("or not");
/////////
// #endif

@@ -25,0 +19,0 @@ /***************** */

var a=1;
/////////////
/// #if DEBUG
debug("hello");
//////////
/// #endif
var b=2;
////////////////////////
/// #if OS === "android"
androidInit();
//////////
/// #endif
var c=3;
///////////////////
///////////////
//////////
//////////////
///////////////
/////////
/// #if version > 4
loadVersion4();
/// #endif
/// #if !DEBUG
debug("hello");
/// #else
debug("or not");
//////////
/// #endif
var a=1;
/* #if DEBUG */
debug("hello");
/* #endif */
var b=2;
/* #if OS === "android" */
androidInit();
/* #endif */
var c=3;
/* #if version > 4 */
loadVersion4();
/* #endif */
/* #if !DEBUG */
debug("hello");
/* #else */
debug("or not");
/* #endif */
var a=1;
/////////////
/// #if DEBUG
debug("hello");
//////////
/// #endif
var b=2;
////////////////////////
/// #if OS === "android"
androidInit();
//////////
/// #endif
var c=3;
///////////////////
///////////////
//////////
//////////////
///////////////
/////////
/// #if version > 4
loadVersion4();
/// #endif
/// #if !DEBUG
debug("hello");
/// #else
debug("or not");
//////////
/// #endif
var a=1;
/* #if DEBUG */
debug("hello");
/* #endif */
var b=2;
/* #if OS === "android" */
androidInit();
/* #endif */
var c=3;
/* #if version > 4 */
loadVersion4();
/* #endif */
/* #if !DEBUG */
debug("hello");
/* #else */
debug("or not");
/* #endif */

@@ -0,0 +0,0 @@ (function(e, a) { for(var i in a) e[i] = a[i]; }(this, /******/ (function(modules) { // webpackBootstrap

@@ -20,3 +20,3 @@ "use strict";

};
describe("files spec", function () {
xdescribe("files spec", function () {
var files = ["simple", "nested", "dfleury", "nested.else", "simple.doubleslash"];

@@ -52,3 +52,3 @@ var fileSet = files.map(function (fn) { return ({

});
describe("webpack bundle", function () {
xdescribe("webpack bundle", function () {
var files = ["webpack"];

@@ -55,0 +55,0 @@ var fileSet = files.map(function (fn) { return ({

@@ -28,3 +28,3 @@ /// <reference types="jasmine" />

const files = [ "simple", "nested", "dfleury", "nested.else", "simple.doubleslash" ];
const files = [ "simple", "nested", "dfleury", "nested.else", "simple.doubleslash", "elif", "nested.elif" ];

@@ -31,0 +31,0 @@ const fileSet = files.map(fn => ({

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc