This commit is contained in:
Tutur33
2023-11-24 22:35:41 +01:00
parent 3c0b507a93
commit 7644b2a0f7
45165 changed files with 4803356 additions and 3 deletions
+66
View File
@@ -0,0 +1,66 @@
import { TagToken, LexerTagDefinitionContract, MustacheToken } from 'edge-lexer';
import { Parser } from '../Parser';
import { EdgeBuffer } from '../EdgeBuffer';
/**
* The parser needs the `compile` method on every tag
*/
export interface ParserTagDefinitionContract extends LexerTagDefinitionContract {
compile(parser: Parser, buffer: EdgeBuffer, token: TagToken): void;
}
/**
* Loc node from Acorn
*/
export type AcornLoc = {
start: {
line: number;
column: number;
};
end: {
line: number;
column: number;
};
};
export type TagTransformer = (tag: TagToken) => void;
export type MustacheTransformer = (tag: MustacheToken) => void;
export type ClaimTagFn = (name: string) => LexerTagDefinitionContract | null;
export type OnLineFn = (line: string) => string;
/**
* Parser options
*/
export type ParserOptions = {
/**
* Is parsing in async mode
*/
async?: boolean;
/**
* Modify the line before it is being processed by the lexer
*/
onLine?: OnLineFn;
/**
* Modify the tag before it is being processed by the parser
*/
onTag?: TagTransformer;
/**
* Modify the mustache block before it is being processed by the parser
*/
onMustache?: MustacheTransformer;
/**
* Claim un-registered tags
*/
claimTag?: ClaimTagFn;
/**
* Nested or flat path to the escape method for escaping values.
*/
escapeCallPath: string | [string, string];
/**
* Name of the property to be used for accessing the values from
* the template. Leave it to an empty string, if properties
* are available directly (meaning without a subpath).
*/
statePropertyName: string;
/**
* An array of local variables to be accessible directly. Define these
* so that the parser doesn't access them from the state property.
*/
localVariables?: string[];
};
+10
View File
@@ -0,0 +1,10 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
+109
View File
@@ -0,0 +1,109 @@
/**
* Buffer class to construct template
*/
export declare class EdgeBuffer {
private filename;
private outputFileAndLineNumber;
private outputOutVariable;
private outputReturnStatement;
private wrapInsideTryCatch;
private options;
/**
* Prefixes and suffix to wrap the final output
*/
private prefix;
private suffix;
/**
* Collected lines
*/
private buffer;
/**
* Current runtime line number
*/
private currentLineNumber;
/**
* Current runtime filename
*/
private currentFileName;
/**
* Cached compiled output. Once this value is set, the `flush`
* method will become a noop
*/
private compiledOutput;
/**
* Exposing output variable name
*/
outputVariableName: string;
constructor(filename: string, options: {
outputVar: string;
rethrowCallPath: string | [string, string];
});
/**
* Creates a new buffer instance by merging the options from the existing one
*/
create(filename: string, options: {
outputVar?: string;
rethrowCallPath?: string | [string, string];
}): EdgeBuffer;
/**
* Returns the size of buffer text
*/
get size(): number;
/**
* Setup template with initial set of lines
*/
private setup;
/**
* Tear down template by writing final set of lines
*/
private teardown;
/**
* Update the filename at runtime
*/
private updateFileName;
/**
* Update the line number at runtime
*/
private updateLineNumber;
/**
* Write raw text to the output variable
*/
outputRaw(text: string): this;
/**
* Write JS expression to the output variable
*/
outputExpression(text: string, filename: string, lineNumber: number, templateLiteral: boolean): this;
/**
* Write JS expression
*/
writeExpression(text: string, filename: string, lineNumber: number): this;
/**
* Write JS statement. Statements are not suffixed with a semi-colon. It
* means, they can be used for writing `if/else` statements.
*/
writeStatement(text: string, filename: string, lineNumber: number): this;
/**
* Wrap template with a custom prefix and suffix
*/
wrap(prefix: string, suffix: string): this;
/**
* Disable instantiation of the file and the line number variables.
*/
disableFileAndLineVariables(): this;
/**
* Disable instantiation of the out variable.
*/
disableOutVariable(): this;
/**
* Disable outputting the return statement
*/
disableReturnStatement(): this;
/**
* Disable wrapping buffer output inside try/catch.
*/
disableTryCatchBlock(): this;
/**
* Return template as a string
*/
flush(): string;
}
+235
View File
@@ -0,0 +1,235 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EdgeBuffer = void 0;
const os_1 = require("os");
const js_stringify_1 = __importDefault(require("js-stringify"));
/**
* Buffer class to construct template
*/
class EdgeBuffer {
constructor(filename, options) {
this.filename = filename;
this.outputFileAndLineNumber = true;
this.outputOutVariable = true;
this.outputReturnStatement = true;
this.wrapInsideTryCatch = true;
this.options = {
outputVar: '',
rethrowCallPath: '',
fileNameVar: '$filename',
lineVar: '$lineNumber',
};
/**
* Prefixes and suffix to wrap the final output
*/
this.prefix = [];
this.suffix = [];
/**
* Collected lines
*/
this.buffer = [];
/**
* Current runtime line number
*/
this.currentLineNumber = 1;
/**
* Current runtime filename
*/
this.currentFileName = this.filename;
this.outputVariableName = options.outputVar;
this.options.outputVar = options.outputVar;
this.options.rethrowCallPath = Array.isArray(options.rethrowCallPath)
? options.rethrowCallPath.join('.')
: options.rethrowCallPath;
}
/**
* Creates a new buffer instance by merging the options from the existing one
*/
create(filename, options) {
return new EdgeBuffer(filename, Object.assign({}, this.options, options));
}
/**
* Returns the size of buffer text
*/
get size() {
return this.buffer.length;
}
/**
* Setup template with initial set of lines
*/
setup(buffer) {
/**
* Define output variable
*/
this.outputOutVariable && buffer.push(`let ${this.outputVariableName} = "";`);
/**
* Define line number variable
*/
this.outputFileAndLineNumber && buffer.push(`let ${this.options.lineVar} = 1;`);
/**
* Define filename variable
*/
this.outputFileAndLineNumber &&
buffer.push(`let ${this.options.fileNameVar} = ${(0, js_stringify_1.default)(this.filename)};`);
/**
* Write try block
*/
this.wrapInsideTryCatch && buffer.push('try {');
}
/**
* Tear down template by writing final set of lines
*/
teardown(buffer) {
if (this.wrapInsideTryCatch) {
/**
* Close try and catch block
*/
buffer.push('} catch (error) {');
/**
* Write catch block
*/
buffer.push(`${this.options.rethrowCallPath}(error, ${this.options.fileNameVar}, ${this.options.lineVar});`);
/**
* End catch block
*/
buffer.push('}');
}
/**
* Return output variable
*/
this.outputReturnStatement && buffer.push(`return ${this.outputVariableName};`);
}
/**
* Update the filename at runtime
*/
updateFileName(filename) {
if (this.currentFileName !== filename) {
this.currentFileName = filename;
this.buffer.push(`${this.options.fileNameVar} = ${(0, js_stringify_1.default)(filename)};`);
}
}
/**
* Update the line number at runtime
*/
updateLineNumber(lineNumber) {
if (lineNumber > 0 && this.currentLineNumber !== lineNumber) {
this.currentLineNumber = lineNumber;
this.buffer.push(`${this.options.lineVar} = ${lineNumber};`);
}
}
/**
* Write raw text to the output variable
*/
outputRaw(text) {
this.buffer.push(`${this.outputVariableName} += ${(0, js_stringify_1.default)(text)};`);
return this;
}
/**
* Write JS expression to the output variable
*/
outputExpression(text, filename, lineNumber, templateLiteral) {
this.updateFileName(filename);
this.updateLineNumber(lineNumber);
text = templateLiteral ? `\`\${${text}}\`` : text;
this.buffer.push(`${this.outputVariableName} += ${text};`);
return this;
}
/**
* Write JS expression
*/
writeExpression(text, filename, lineNumber) {
this.updateFileName(filename);
this.updateLineNumber(lineNumber);
this.buffer.push(`${text};`);
return this;
}
/**
* Write JS statement. Statements are not suffixed with a semi-colon. It
* means, they can be used for writing `if/else` statements.
*/
writeStatement(text, filename, lineNumber) {
this.updateFileName(filename);
this.updateLineNumber(lineNumber);
this.buffer.push(`${text}`);
return this;
}
/**
* Wrap template with a custom prefix and suffix
*/
wrap(prefix, suffix) {
this.prefix.push(prefix);
this.suffix.push(suffix);
return this;
}
/**
* Disable instantiation of the file and the line number variables.
*/
disableFileAndLineVariables() {
this.outputFileAndLineNumber = false;
return this;
}
/**
* Disable instantiation of the out variable.
*/
disableOutVariable() {
this.outputOutVariable = false;
return this;
}
/**
* Disable outputting the return statement
*/
disableReturnStatement() {
this.outputReturnStatement = false;
return this;
}
/**
* Disable wrapping buffer output inside try/catch.
*/
disableTryCatchBlock() {
this.wrapInsideTryCatch = false;
return this;
}
/**
* Return template as a string
*/
flush() {
if (this.compiledOutput !== undefined) {
return this.compiledOutput;
}
let buffer = [];
/**
* Write prefixes
*/
this.prefix.forEach((text) => text.split(os_1.EOL).forEach((line) => buffer.push(`${line}`)));
/**
* Write setup code
*/
this.setup(buffer);
/**
* Copy template contents
*/
buffer = buffer.concat(this.buffer);
/**
* Write teardown code
*/
this.teardown(buffer);
/**
* Write prefixes
*/
this.suffix.forEach((text) => text.split(os_1.EOL).forEach((line) => buffer.push(`${line}`)));
this.compiledOutput = buffer.join(os_1.EOL);
return this.compiledOutput;
}
}
exports.EdgeBuffer = EdgeBuffer;
+5
View File
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+17
View File
@@ -0,0 +1,17 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
statement.elements = statement.elements.map((element) => (0, transformAst_1.transformAst)(element, filename, parser));
return statement;
},
};
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
@@ -0,0 +1,43 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
const edge_error_1 = require("edge-error");
exports.default = {
toStatement(statement, filename, parser) {
parser.stack.defineScope();
statement.params.forEach((param) => {
if (param.type === 'Identifier') {
parser.stack.defineVariable(param.name);
}
else if (param.type === 'ObjectPattern') {
parser.utils.collectObjectExpressionProperties(param).forEach((prop) => {
parser.stack.defineVariable(prop);
});
}
else if (param.type === 'ArrayPattern') {
parser.utils.collectArrayExpressionProperties(param).forEach((prop) => {
parser.stack.defineVariable(prop);
});
}
else {
const { line, col } = parser.utils.getExpressionLoc(param);
throw new edge_error_1.EdgeError(`Report this error to the maintainers: Unexpected arrow function property type ${param.type}`, 'E_PARSER_ERROR', {
line,
col,
filename,
});
}
});
statement.body = (0, transformAst_1.transformAst)(statement.body, filename, parser);
parser.stack.clearScope();
return statement;
},
};
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+17
View File
@@ -0,0 +1,17 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
statement.right = (0, transformAst_1.transformAst)(statement.right, filename, parser);
return statement;
},
};
+5
View File
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+27
View File
@@ -0,0 +1,27 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const edge_error_1 = require("edge-error");
const transformAst_1 = require("../Parser/transformAst");
const UNALLOWED_EXPRESSION_MESSAGE = 'Make sure to render template in async mode before using await expression';
exports.default = {
toStatement(statement, filename, parser) {
if (!parser.options.async) {
const { line, col } = parser.utils.getExpressionLoc(statement);
throw new edge_error_1.EdgeError(UNALLOWED_EXPRESSION_MESSAGE, 'E_PARSER_ERROR', {
line,
col,
filename,
});
}
statement.argument = (0, transformAst_1.transformAst)(statement.argument, filename, parser);
return statement;
},
};
+5
View File
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+18
View File
@@ -0,0 +1,18 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
statement.left = (0, transformAst_1.transformAst)(statement.left, filename, parser);
statement.right = (0, transformAst_1.transformAst)(statement.right, filename, parser);
return statement;
},
};
+5
View File
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+19
View File
@@ -0,0 +1,19 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
statement.body = statement.body.map((token) => {
return (0, transformAst_1.transformAst)(token, filename, parser);
});
return statement;
},
};
+5
View File
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+18
View File
@@ -0,0 +1,18 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
statement.callee = (0, transformAst_1.transformAst)(statement.callee, filename, parser);
statement.arguments = statement.arguments.map((node) => (0, transformAst_1.transformAst)(node, filename, parser));
return statement;
},
};
+5
View File
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+17
View File
@@ -0,0 +1,17 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
statement.expression = (0, transformAst_1.transformAst)(statement.expression, filename, parser);
return statement;
},
};
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
@@ -0,0 +1,19 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
statement.test = (0, transformAst_1.transformAst)(statement.test, filename, parser);
statement.consequent = (0, transformAst_1.transformAst)(statement.consequent, filename, parser);
statement.alternate = (0, transformAst_1.transformAst)(statement.alternate, filename, parser);
return statement;
},
};
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+16
View File
@@ -0,0 +1,16 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
return (0, transformAst_1.transformAst)(statement.expression, filename, parser);
},
};
@@ -0,0 +1,4 @@
declare const _default: {
toStatement(statement: any): any;
};
export default _default;
+15
View File
@@ -0,0 +1,15 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = {
toStatement(statement) {
return statement;
},
};
+5
View File
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, _: string, parser: Parser): object;
};
export default _default;
+21
View File
@@ -0,0 +1,21 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const makeStatePropertyAccessor_1 = require("../Parser/makeStatePropertyAccessor");
exports.default = {
toStatement(statement, _, parser) {
if ((parser.options.localVariables || []).indexOf(statement.name) > -1 ||
parser.stack.has(statement.name) ||
global[statement.name] !== undefined) {
return statement;
}
return (0, makeStatePropertyAccessor_1.makeStatePropertyAccessor)(parser.options.statePropertyName, statement);
},
};
+4
View File
@@ -0,0 +1,4 @@
declare const _default: {
toStatement(statement: any): any;
};
export default _default;
+15
View File
@@ -0,0 +1,15 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = {
toStatement(statement) {
return statement;
},
};
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+18
View File
@@ -0,0 +1,18 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
statement.left = (0, transformAst_1.transformAst)(statement.left, filename, parser);
statement.right = (0, transformAst_1.transformAst)(statement.right, filename, parser);
return statement;
},
};
+5
View File
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+26
View File
@@ -0,0 +1,26 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
statement.object = (0, transformAst_1.transformAst)(statement.object, filename, parser);
/**
* Making the following expressions work
*
* user[Object.keys(user).find((k) => k === 'id')]
* [num1, num2, num3].filter((num) => num % 2 === 0)
*/
if (statement.property.type !== 'Identifier') {
statement.property = (0, transformAst_1.transformAst)(statement.property, filename, parser);
}
return statement;
},
};
+5
View File
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+19
View File
@@ -0,0 +1,19 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
statement.arguments = statement.arguments.map((expression) => {
return (0, transformAst_1.transformAst)(expression, filename, parser);
});
return statement;
},
};
+5
View File
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+41
View File
@@ -0,0 +1,41 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
const edge_error_1 = require("edge-error");
exports.default = {
toStatement(statement, filename, parser) {
statement.properties = statement.properties.map((node) => {
if (node.type === 'Property') {
/**
* Since we change the structure of node.value, we have to
* turnoff shorthand objects, so that the astring outputs
* the key name explicitly
*/
node.shorthand = false;
if (node.computed === true) {
node.key = (0, transformAst_1.transformAst)(node.key, filename, parser);
}
node.value = (0, transformAst_1.transformAst)(node.value, filename, parser);
return node;
}
if (node.type === 'SpreadElement') {
return (0, transformAst_1.transformAst)(node, filename, parser);
}
const { line, col } = parser.utils.getExpressionLoc(node);
throw new edge_error_1.EdgeError(`Report this error to the maintainers: Unexpected object property type "${node.type}"`, 'E_PARSER_ERROR', {
line,
col,
filename,
});
});
return statement;
},
};
+5
View File
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+17
View File
@@ -0,0 +1,17 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
statement.argument = (0, transformAst_1.transformAst)(statement.argument, filename, parser);
return statement;
},
};
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+19
View File
@@ -0,0 +1,19 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
statement.expressions = statement.expressions.map((expression) => {
return (0, transformAst_1.transformAst)(expression, filename, parser);
});
return statement;
},
};
+5
View File
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): object;
};
export default _default;
+16
View File
@@ -0,0 +1,16 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = {
toStatement(statement, filename, parser) {
statement.argument = parser.utils.transformAst(statement.argument, filename, parser);
return statement;
},
};
+5
View File
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+19
View File
@@ -0,0 +1,19 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
statement.expressions = statement.expressions.map((expression) => {
return (0, transformAst_1.transformAst)(expression, filename, parser);
});
return statement;
},
};
+4
View File
@@ -0,0 +1,4 @@
declare const _default: {
toStatement(statement: any): any;
};
export default _default;
+15
View File
@@ -0,0 +1,15 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = {
toStatement(statement) {
return statement;
},
};
+5
View File
@@ -0,0 +1,5 @@
import { Parser } from '../Parser';
declare const _default: {
toStatement(statement: any, filename: string, parser: Parser): any;
};
export default _default;
+17
View File
@@ -0,0 +1,17 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const transformAst_1 = require("../Parser/transformAst");
exports.default = {
toStatement(statement, filename, parser) {
statement.argument = (0, transformAst_1.transformAst)(statement.argument, filename, parser);
return statement;
},
};
+23
View File
@@ -0,0 +1,23 @@
export { default as Identifier } from './Identifier';
export { default as MemberExpression } from './MemberExpression';
export { default as ExpressionStatement } from './ExpressionStatement';
export { default as CallExpression } from './CallExpression';
export { default as ArrowFunctionExpression } from './ArrowFunctionExpression';
export { default as Literal } from './Literal';
export { default as TemplateLiteral } from './TemplateLiteral';
export { default as BinaryExpression } from './BinaryExpression';
export { default as ArrayExpression } from './ArrayExpression';
export { default as ObjectExpression } from './ObjectExpression';
export { default as UnaryExpression } from './UnaryExpression';
export { default as FunctionDeclaration } from './FunctionDeclaration';
export { default as ConditionalExpression } from './ConditionalExpression';
export { default as LogicalExpression } from './LogicalExpression';
export { default as SequenceExpression } from './SequenceExpression';
export { default as AssignmentExpression } from './AssignmentExpression';
export { default as AwaitExpression } from './AwaitExpression';
export { default as NewExpression } from './NewExpression';
export { default as BlockStatement } from './BlockStatement';
export { default as ReturnStatement } from './ReturnStatement';
export { default as ThisExpression } from './ThisExpression';
export { default as ChainExpression } from './ChainExpression';
export { default as SpreadElement } from './SpreadElement';
+60
View File
@@ -0,0 +1,60 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SpreadElement = exports.ChainExpression = exports.ThisExpression = exports.ReturnStatement = exports.BlockStatement = exports.NewExpression = exports.AwaitExpression = exports.AssignmentExpression = exports.SequenceExpression = exports.LogicalExpression = exports.ConditionalExpression = exports.FunctionDeclaration = exports.UnaryExpression = exports.ObjectExpression = exports.ArrayExpression = exports.BinaryExpression = exports.TemplateLiteral = exports.Literal = exports.ArrowFunctionExpression = exports.CallExpression = exports.ExpressionStatement = exports.MemberExpression = exports.Identifier = void 0;
var Identifier_1 = require("./Identifier");
Object.defineProperty(exports, "Identifier", { enumerable: true, get: function () { return __importDefault(Identifier_1).default; } });
var MemberExpression_1 = require("./MemberExpression");
Object.defineProperty(exports, "MemberExpression", { enumerable: true, get: function () { return __importDefault(MemberExpression_1).default; } });
var ExpressionStatement_1 = require("./ExpressionStatement");
Object.defineProperty(exports, "ExpressionStatement", { enumerable: true, get: function () { return __importDefault(ExpressionStatement_1).default; } });
var CallExpression_1 = require("./CallExpression");
Object.defineProperty(exports, "CallExpression", { enumerable: true, get: function () { return __importDefault(CallExpression_1).default; } });
var ArrowFunctionExpression_1 = require("./ArrowFunctionExpression");
Object.defineProperty(exports, "ArrowFunctionExpression", { enumerable: true, get: function () { return __importDefault(ArrowFunctionExpression_1).default; } });
var Literal_1 = require("./Literal");
Object.defineProperty(exports, "Literal", { enumerable: true, get: function () { return __importDefault(Literal_1).default; } });
var TemplateLiteral_1 = require("./TemplateLiteral");
Object.defineProperty(exports, "TemplateLiteral", { enumerable: true, get: function () { return __importDefault(TemplateLiteral_1).default; } });
var BinaryExpression_1 = require("./BinaryExpression");
Object.defineProperty(exports, "BinaryExpression", { enumerable: true, get: function () { return __importDefault(BinaryExpression_1).default; } });
var ArrayExpression_1 = require("./ArrayExpression");
Object.defineProperty(exports, "ArrayExpression", { enumerable: true, get: function () { return __importDefault(ArrayExpression_1).default; } });
var ObjectExpression_1 = require("./ObjectExpression");
Object.defineProperty(exports, "ObjectExpression", { enumerable: true, get: function () { return __importDefault(ObjectExpression_1).default; } });
var UnaryExpression_1 = require("./UnaryExpression");
Object.defineProperty(exports, "UnaryExpression", { enumerable: true, get: function () { return __importDefault(UnaryExpression_1).default; } });
var FunctionDeclaration_1 = require("./FunctionDeclaration");
Object.defineProperty(exports, "FunctionDeclaration", { enumerable: true, get: function () { return __importDefault(FunctionDeclaration_1).default; } });
var ConditionalExpression_1 = require("./ConditionalExpression");
Object.defineProperty(exports, "ConditionalExpression", { enumerable: true, get: function () { return __importDefault(ConditionalExpression_1).default; } });
var LogicalExpression_1 = require("./LogicalExpression");
Object.defineProperty(exports, "LogicalExpression", { enumerable: true, get: function () { return __importDefault(LogicalExpression_1).default; } });
var SequenceExpression_1 = require("./SequenceExpression");
Object.defineProperty(exports, "SequenceExpression", { enumerable: true, get: function () { return __importDefault(SequenceExpression_1).default; } });
var AssignmentExpression_1 = require("./AssignmentExpression");
Object.defineProperty(exports, "AssignmentExpression", { enumerable: true, get: function () { return __importDefault(AssignmentExpression_1).default; } });
var AwaitExpression_1 = require("./AwaitExpression");
Object.defineProperty(exports, "AwaitExpression", { enumerable: true, get: function () { return __importDefault(AwaitExpression_1).default; } });
var NewExpression_1 = require("./NewExpression");
Object.defineProperty(exports, "NewExpression", { enumerable: true, get: function () { return __importDefault(NewExpression_1).default; } });
var BlockStatement_1 = require("./BlockStatement");
Object.defineProperty(exports, "BlockStatement", { enumerable: true, get: function () { return __importDefault(BlockStatement_1).default; } });
var ReturnStatement_1 = require("./ReturnStatement");
Object.defineProperty(exports, "ReturnStatement", { enumerable: true, get: function () { return __importDefault(ReturnStatement_1).default; } });
var ThisExpression_1 = require("./ThisExpression");
Object.defineProperty(exports, "ThisExpression", { enumerable: true, get: function () { return __importDefault(ThisExpression_1).default; } });
var ChainExpression_1 = require("./ChainExpression");
Object.defineProperty(exports, "ChainExpression", { enumerable: true, get: function () { return __importDefault(ChainExpression_1).default; } });
var SpreadElement_1 = require("./SpreadElement");
Object.defineProperty(exports, "SpreadElement", { enumerable: true, get: function () { return __importDefault(SpreadElement_1).default; } });
@@ -0,0 +1,2 @@
export declare function collectObjectExpressionProperties(expression: any): string[];
export declare function collectArrayExpressionProperties(expression: any): string[];
@@ -0,0 +1,29 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.collectArrayExpressionProperties = exports.collectObjectExpressionProperties = void 0;
function collectObjectExpressionProperties(expression) {
return expression.properties.map((prop) => {
if (prop.value.type !== 'Identifier') {
throw new Error('Object destructuring should not reference dynamic properties');
}
return prop.value.name;
});
}
exports.collectObjectExpressionProperties = collectObjectExpressionProperties;
function collectArrayExpressionProperties(expression) {
return expression.elements.map((prop) => {
if (prop.type !== 'Identifier') {
throw new Error('Array destructuring should not reference dynamic properties');
}
return prop.name;
});
}
exports.collectArrayExpressionProperties = collectArrayExpressionProperties;
+7
View File
@@ -0,0 +1,7 @@
import { LexerLoc } from 'edge-lexer';
/**
* Generates and returns the acorn AST for a given Javascript expression. Assuming
* the Javascript expression is embedded into the edge lexer token, this method
* expects you to pass the token loc and the filename.
*/
export declare function generateAST(jsArg: string, lexerLoc: LexerLoc, filename: string): any;
+60
View File
@@ -0,0 +1,60 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateAST = void 0;
const edge_error_1 = require("edge-error");
const acorn_1 = require("acorn");
/**
* Patch the acorn loc to point to the correct line number
* inside the original template engine
*/
function patchLoc(loc, lexerLoc) {
/**
* Patch the column also, when it's the first line. The reason we do this, since
* the first line in the actual edge file may contain the Javascript expression
* at a different column all together
*/
if (loc.start.line === 1) {
loc.start.column = loc.start.column + lexerLoc.start.col;
}
loc.start.line = loc.start.line + lexerLoc.start.line - 1;
loc.end.line = loc.end.line + lexerLoc.start.line - 1;
}
/**
* Generates and returns the acorn AST for a given Javascript expression. Assuming
* the Javascript expression is embedded into the edge lexer token, this method
* expects you to pass the token loc and the filename.
*/
function generateAST(jsArg, lexerLoc, filename) {
const acornOptions = {
locations: true,
ecmaVersion: 2020,
allowAwaitOutsideFunction: true,
onToken: (token) => patchLoc(token.loc, lexerLoc),
};
try {
const ast = (0, acorn_1.parse)(jsArg, acornOptions);
return ast['body'][0];
}
catch (error) {
/**
* The error loc is not passed via `onToken` event, so need
* to patch is here seperately
*/
const line = error.loc.line + lexerLoc.start.line - 1;
const col = error.loc.line === 1 ? error.loc.column + lexerLoc.start.col : error.loc.column;
throw new edge_error_1.EdgeError(error.message.replace(/\(\d+:\d+\)/, ''), 'E_ACORN_ERROR', {
line,
col,
filename,
});
}
}
exports.generateAST = generateAST;
+89
View File
@@ -0,0 +1,89 @@
import { Token } from 'edge-lexer';
import { Stack } from '../Stack';
import { stringify } from './stringify';
import { EdgeBuffer } from '../EdgeBuffer';
import { generateAST } from './generateAst';
import { transformAst } from './transformAst';
import { makeEscapeCallable } from './makeEscapeCallable';
import { makeStatePropertyAccessor } from './makeStatePropertyAccessor';
import { ParserTagDefinitionContract, ParserOptions } from '../Contracts';
import { collectObjectExpressionProperties, collectArrayExpressionProperties } from './collectObjectExpressionProperties';
/**
* Edge parser converts template strings to an invokable function. This module
* uses [edge-lexer](https://github.com/edge-js/lexer) to generate a list
* of tokens and process them against [acorn](https://npm.im/acorn).
*
* Edge has concepts of Tags, which are not implemented by this module and must
* be provided by the consumer.
*
* ```js
* // Tags are optional
* const tags = {}
*
* // File name is required for better error reporting
* const options = { filename: 'welcome.edge' }
*
* const parser = new Parser(tags, options)
* const template = require('fs').readFileSync('welcome.edge', 'utf-8')
*
* const tokens = parser.parse(template)
* console.log(fn)
* ```
*/
export declare class Parser {
tags: {
[key: string]: ParserTagDefinitionContract;
};
stack: Stack;
options: ParserOptions;
/**
* A boolean to know if async mode is enabled
*/
asyncMode: boolean;
constructor(tags: {
[key: string]: ParserTagDefinitionContract;
}, stack: Stack, options: ParserOptions);
/**
* Parser utilities work with the AST
*/
utils: {
generateAST: typeof generateAST;
transformAst: typeof transformAst;
stringify: typeof stringify;
makeEscapeCallable: typeof makeEscapeCallable;
makeStatePropertyAccessor: typeof makeStatePropertyAccessor;
collectObjectExpressionProperties: typeof collectObjectExpressionProperties;
collectArrayExpressionProperties: typeof collectArrayExpressionProperties;
getExpressionLoc(expression: any): {
line: number;
col: number;
};
};
/**
* Returns the options to be passed to the tokenizer
*/
private getTokenizerOptions;
/**
* Process escaped tag token by writing it as it is. However, the children
* inside a tag are still processed.
*/
private processEscapedTagToken;
/**
* Process escaped muscahe block by writing it as it is.
*/
private processEscapedMustache;
/**
* Process mustache token
*/
private processMustache;
/**
* Convert template to tokens
*/
tokenize(template: string, options: {
filename: string;
}): Token[];
/**
* Process a lexer token. The output gets written to the buffer
*/
processToken(token: Token, buffer: EdgeBuffer): void;
}
+180
View File
@@ -0,0 +1,180 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Parser = void 0;
const os_1 = require("os");
const edge_lexer_1 = require("edge-lexer");
const Stack_1 = require("../Stack");
const stringify_1 = require("./stringify");
const generateAst_1 = require("./generateAst");
const transformAst_1 = require("./transformAst");
const makeEscapeCallable_1 = require("./makeEscapeCallable");
const makeStatePropertyAccessor_1 = require("./makeStatePropertyAccessor");
const collectObjectExpressionProperties_1 = require("./collectObjectExpressionProperties");
/**
* Edge parser converts template strings to an invokable function. This module
* uses [edge-lexer](https://github.com/edge-js/lexer) to generate a list
* of tokens and process them against [acorn](https://npm.im/acorn).
*
* Edge has concepts of Tags, which are not implemented by this module and must
* be provided by the consumer.
*
* ```js
* // Tags are optional
* const tags = {}
*
* // File name is required for better error reporting
* const options = { filename: 'welcome.edge' }
*
* const parser = new Parser(tags, options)
* const template = require('fs').readFileSync('welcome.edge', 'utf-8')
*
* const tokens = parser.parse(template)
* console.log(fn)
* ```
*/
class Parser {
constructor(tags, stack = new Stack_1.Stack(), options) {
this.tags = tags;
this.stack = stack;
this.options = options;
/**
* A boolean to know if async mode is enabled
*/
this.asyncMode = !!this.options.async;
/**
* Parser utilities work with the AST
*/
this.utils = {
generateAST: generateAst_1.generateAST,
transformAst: transformAst_1.transformAst,
stringify: stringify_1.stringify,
makeEscapeCallable: makeEscapeCallable_1.makeEscapeCallable,
makeStatePropertyAccessor: makeStatePropertyAccessor_1.makeStatePropertyAccessor,
collectObjectExpressionProperties: collectObjectExpressionProperties_1.collectObjectExpressionProperties,
collectArrayExpressionProperties: collectObjectExpressionProperties_1.collectArrayExpressionProperties,
getExpressionLoc(expression) {
const loc = expression.loc || expression.property?.loc;
return {
line: loc.start.line,
col: loc.start.column,
};
},
};
}
/**
* Returns the options to be passed to the tokenizer
*/
getTokenizerOptions(options) {
if (!this.options) {
return options;
}
return {
claimTag: this.options.claimTag,
onLine: this.options.onLine,
filename: options.filename,
};
}
/**
* Process escaped tag token by writing it as it is. However, the children
* inside a tag are still processed.
*/
processEscapedTagToken(token, buffer) {
/**
* Since `jsArg` can span over multiple lines, we split it into multiple lines
* and write one line at a time to maintain the original shape.
*/
const lines = `@${token.properties.name}(${token.properties.jsArg})`.split('\n');
lines.forEach((line) => buffer.outputRaw(line));
/**
* Process all inner children of the tag
*/
token.children.forEach((child) => this.processToken(child, buffer));
/**
* Close the tag
*/
buffer.outputRaw(`@end${token.properties.name}`);
}
/**
* Process escaped muscahe block by writing it as it is.
*/
processEscapedMustache(token, buffer) {
const lines = token.type === edge_lexer_1.MustacheTypes.EMUSTACHE
? `{{${token.properties.jsArg}}}`.split('\n')
: `{{{${token.properties.jsArg}}}}`.split('\n');
lines.forEach((line) => buffer.outputRaw(line));
}
/**
* Process mustache token
*/
processMustache({ properties, loc, filename, type }, buffer) {
const node = (0, transformAst_1.transformAst)((0, generateAst_1.generateAST)(properties.jsArg, loc, filename), filename, this);
/**
* Wrap mustache output to an escape call for preventing XSS attacks
*/
const expression = type === edge_lexer_1.MustacheTypes.MUSTACHE
? (0, makeEscapeCallable_1.makeEscapeCallable)(this.options.escapeCallPath, [node])
: node;
/**
* Template literal, so there is no need to wrap it inside another
* template string
*/
if (node.type === 'TemplateLiteral') {
buffer.outputExpression((0, stringify_1.stringify)(expression), filename, loc.start.line, false);
}
else if (node.type === 'FunctionDeclaration') {
buffer.outputExpression((0, stringify_1.stringify)(node), filename, loc.start.line, false);
}
else {
buffer.outputExpression((0, stringify_1.stringify)(expression), filename, loc.start.line, true);
}
}
/**
* Convert template to tokens
*/
tokenize(template, options) {
const tokenizer = new edge_lexer_1.Tokenizer(template, this.tags, this.getTokenizerOptions(options));
tokenizer.parse();
return tokenizer.tokens;
}
/**
* Process a lexer token. The output gets written to the buffer
*/
processToken(token, buffer) {
switch (token.type) {
case 'raw':
buffer.outputRaw(token.value);
break;
case 'newline':
buffer.outputRaw(os_1.EOL === '\n' ? '\n' : '\r\n');
break;
case edge_lexer_1.TagTypes.TAG:
if (typeof this.options.onTag === 'function') {
this.options.onTag(token);
}
this.tags[token.properties.name].compile(this, buffer, token);
break;
case edge_lexer_1.TagTypes.ETAG:
this.processEscapedTagToken(token, buffer);
break;
case edge_lexer_1.MustacheTypes.EMUSTACHE:
case edge_lexer_1.MustacheTypes.ESMUSTACHE:
this.processEscapedMustache(token, buffer);
break;
case edge_lexer_1.MustacheTypes.SMUSTACHE:
case edge_lexer_1.MustacheTypes.MUSTACHE:
if (typeof this.options.onMustache === 'function') {
this.options.onMustache(token);
}
this.processMustache(token, buffer);
}
}
}
exports.Parser = Parser;
+4
View File
@@ -0,0 +1,4 @@
/**
* Returns Acorn complaint AST for a callable expression
*/
export declare function makeEscapeCallable(paths: string | [string, string], args: object[]): any;
+42
View File
@@ -0,0 +1,42 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeEscapeCallable = void 0;
/**
* Returns Acorn complaint AST for a callable expression
*/
function makeEscapeCallable(paths, args) {
if (typeof paths === 'string') {
return {
type: 'CallExpression',
callee: {
type: 'Identifier',
name: paths,
},
arguments: args,
};
}
return {
type: 'CallExpression',
callee: {
type: 'MemberExpression',
object: {
type: 'Identifier',
name: paths[0],
},
property: {
type: 'Identifier',
name: paths[1],
},
},
arguments: args,
};
}
exports.makeEscapeCallable = makeEscapeCallable;
@@ -0,0 +1,4 @@
/**
* Returns Acorn complaint AST for a collable expression
*/
export declare function makeStatePropertyAccessor(propertyName: string, args: object): any;
+26
View File
@@ -0,0 +1,26 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeStatePropertyAccessor = void 0;
/**
* Returns Acorn complaint AST for a collable expression
*/
function makeStatePropertyAccessor(propertyName, args) {
return {
type: 'MemberExpression',
object: {
type: 'Identifier',
name: propertyName,
},
computed: false,
property: args,
};
}
exports.makeStatePropertyAccessor = makeStatePropertyAccessor;
+4
View File
@@ -0,0 +1,4 @@
/**
* Convert the acorn AST to a Javascript expression string
*/
export declare function stringify(astExpression: any): string;
+19
View File
@@ -0,0 +1,19 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.stringify = void 0;
const astring_1 = require("astring");
/**
* Convert the acorn AST to a Javascript expression string
*/
function stringify(astExpression) {
return (0, astring_1.generate)(astExpression);
}
exports.stringify = stringify;
+6
View File
@@ -0,0 +1,6 @@
import { Parser } from '../Parser';
/**
* Transform acorn AST to Edge AST. This must always be performed before
* writing it to the compiled template buffer.
*/
export declare function transformAst(astExpression: any, filename: string, parser: Parser): any;
+52
View File
@@ -0,0 +1,52 @@
"use strict";
/*
* edge-lexer
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformAst = void 0;
const edge_error_1 = require("edge-error");
const Expressions = __importStar(require("../Expressions"));
/**
* Transform acorn AST to Edge AST. This must always be performed before
* writing it to the compiled template buffer.
*/
function transformAst(astExpression, filename, parser) {
if (Expressions[astExpression.type]) {
return Expressions[astExpression.type].toStatement(astExpression, filename, parser);
}
const { type, loc } = astExpression;
throw new edge_error_1.EdgeError(`"${type}" is not supported`, 'E_UNALLOWED_EXPRESSION', {
line: loc.start.line,
col: loc.start.column,
filename: filename,
});
}
exports.transformAst = transformAst;
+44
View File
@@ -0,0 +1,44 @@
/**
* Stack exposes the API to define variables and scopes. This is used by the parser
* to decide the syntax for resolving variables.
*/
export declare class Stack {
private localVariables;
private scopes;
/**
* Returns the recent scope of the local variables array
*/
private getRecentScope;
/**
* Finds item inside the list or `needle in haystack`
*/
private isInList;
/**
* Define a new custom scope
*/
defineScope(): void;
/**
* Clear recently created scope
*/
clearScope(): void;
/**
* Define variable inside the stack.
*/
defineVariable(variableName: string): void;
/**
* Returns a boolean telling if a variable is defined inside
* the stack
*/
has(variableName: string): boolean;
/**
* Returns the state tree for the stack
*/
getState(): {
localVariables: string[];
scopes: string[][];
};
/**
* Returns a flat list of defined variables
*/
list(): string[];
}
+78
View File
@@ -0,0 +1,78 @@
"use strict";
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Stack = void 0;
/**
* Stack exposes the API to define variables and scopes. This is used by the parser
* to decide the syntax for resolving variables.
*/
class Stack {
constructor() {
this.localVariables = [];
this.scopes = [];
}
/**
* Returns the recent scope of the local variables array
*/
getRecentScope() {
const hasScopes = this.scopes.length;
return hasScopes ? this.scopes[this.scopes.length - 1] : this.localVariables;
}
/**
* Finds item inside the list or `needle in haystack`
*/
isInList(list, item) {
return !!list.find((listItem) => listItem === item);
}
/**
* Define a new custom scope
*/
defineScope() {
this.scopes.push([]);
}
/**
* Clear recently created scope
*/
clearScope() {
this.scopes.pop();
}
/**
* Define variable inside the stack.
*/
defineVariable(variableName) {
this.getRecentScope().push(variableName);
}
/**
* Returns a boolean telling if a variable is defined inside
* the stack
*/
has(variableName) {
if (this.isInList(this.localVariables, variableName)) {
return true;
}
return !!this.scopes.find((scope) => this.isInList(scope, variableName));
}
/**
* Returns the state tree for the stack
*/
getState() {
return {
localVariables: this.localVariables,
scopes: this.scopes,
};
}
/**
* Returns a flat list of defined variables
*/
list() {
return this.scopes.flat().concat(this.localVariables);
}
}
exports.Stack = Stack;