@aurahelper/languages
Version:
Language Libraries to work with XML, Aura, Apex... files. tokenizers, parsers, system classes and much more
333 lines • 14 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.JSParser = void 0;
var core_1 = require("@aurahelper/core");
var utils_1 = require("../utils");
var tokenizer_1 = require("./tokenizer");
var Validator = core_1.CoreUtils.Validator;
/**
* Class to Parse Aura Javascript files to extract data from files
*/
var JSParser = /** @class */ (function () {
/**
* Create new JSParser instance to analize Aura Javscript file
* @param {string | Token[]} [filePathOrTokens] File path or Tokens (tokens from JSTokenizer class)
* @param {string} [fileName] File name
*/
function JSParser(filePathOrTokens, fileName) {
if (typeof filePathOrTokens !== 'string') {
this.tokens = filePathOrTokens || [];
this.tokensLength = this.tokens.length;
this.fileName = fileName;
}
else {
this.tokens = [];
this.tokensLength = 0;
this.filePath = filePathOrTokens;
this.fileName = fileName || (this.filePath ? core_1.PathUtils.removeFileExtension(core_1.PathUtils.getBasename(this.filePath)) : undefined);
}
this.content = undefined;
this.cursorPosition = undefined;
this.node = undefined;
this.tabSize = 4;
}
/**
* Method to set the tab size
* @param {number} tabSize Tab size value
* @returns {JSParser} Return the JSParser instance
*/
JSParser.prototype.setTabSize = function (tabSize) {
this.tabSize = tabSize;
return this;
};
/**
* Method to set the file tokens
* @param {Token[]} tokens File tokens
* @returns {JSParser} Return the JSParser instance
*/
JSParser.prototype.setTokens = function (tokens) {
this.tokens = tokens;
this.tokensLength = this.tokens.length;
return this;
};
/**
* Method to set the file path
* @param {string} filePath File path value
* @returns {JSParser} Return the JSParser instance
*/
JSParser.prototype.setFilePath = function (filePath) {
this.filePath = filePath;
return this;
};
/**
* Method to set the file name
* @param {string} fileName File name value
* @returns {JSParser} Return the JSParser instance
*/
JSParser.prototype.setFileName = function (fileName) {
this.fileName = fileName;
return this;
};
/**
* Method to set the file content
* @param {string} content File content value
* @returns {JSParser} Return the JSParser instance
*/
JSParser.prototype.setContent = function (content) {
this.content = content;
return this;
};
/**
* Method to set the cusor Position on file
* @param {Position} position Cursor Position object
* @returns {JSParser} Return the JSParser instance
*/
JSParser.prototype.setCursorPosition = function (position) {
this.cursorPosition = position;
return this;
};
/**
* Method to parse Aura Javascript file and get file information
* @returns Return the AuraJSFile node with file data
*/
JSParser.prototype.parse = function () {
if (this.node) {
return this.node;
}
if (this.filePath && !this.content && (!this.tokens || this.tokens.length === 0)) {
this.filePath = Validator.validateFilePath(this.filePath);
this.content = core_1.FileReader.readFileSync(this.filePath);
if (!core_1.FileChecker.isJavaScript(this.filePath)) {
throw new core_1.InvalidFilePathException(this.filePath, this.fileName);
}
this.tokens = tokenizer_1.JSTokenizer.tokenize(this.content);
this.tokensLength = this.tokens.length;
}
else if (this.content && (!this.tokens || this.tokens.length === 0)) {
this.tokens = tokenizer_1.JSTokenizer.tokenize(this.content);
this.tokensLength = this.tokens.length;
}
var methods = [];
var bracketIndent = 0;
var parenthesisIndent = 0;
var comment;
var positionData;
var strQueryStartIndex = -1;
var strQueryEndIndex = -1;
var strQueryFrom = false;
this.node = new core_1.AuraJSFile(this.fileName);
for (var index = 0; index < this.tokensLength; index++) {
var lastToken = utils_1.LanguageUtils.getLastToken(this.tokens, index);
var token = new core_1.Token(this.tokens[index]);
var nextToken = utils_1.LanguageUtils.getNextToken(this.tokens, index);
if (this.cursorPosition && this.node && !positionData) {
if (utils_1.LanguageUtils.isOnPosition(token, lastToken, nextToken, this.cursorPosition)) {
var startIndex = this.cursorPosition.character - token.range.start.character;
var startPart = token.text.substring(0, startIndex + 1);
var endPart = token.text.substring(startIndex + 1);
positionData = new core_1.PositionData(startPart, endPart, this.node.nodeType, undefined, 'JS');
positionData.onText = token.type === core_1.JSTokenTypes.PUNCTUATION.DOUBLE_QUOTTES_START || token.type === core_1.JSTokenTypes.PUNCTUATION.DOUBLE_QUOTTES_END || token.type === core_1.JSTokenTypes.LITERAL.STRING;
if (strQueryStartIndex !== -1 && strQueryEndIndex !== -1 && strQueryFrom) {
positionData.strQueryStartIndex = strQueryStartIndex;
positionData.strQueryEndIndex = strQueryEndIndex;
}
}
strQueryStartIndex = -1;
strQueryEndIndex = -1;
}
if (openBracket(token)) {
bracketIndent++;
}
else if (closeBracket(token)) {
bracketIndent--;
}
else if (openParenthesis(token)) {
parenthesisIndent++;
}
else if (closeParenthesis(token)) {
parenthesisIndent--;
}
else if (isCommentLine(token)) {
var newNode = new core_1.AuraJSComment();
index = processCommentLine(newNode, this.tokens, index);
comment = newNode;
}
else if (openCommentBlock(token)) {
var newNode = new core_1.AuraJSCommentBlock();
index = processCommentBlock(newNode, this.tokens, index);
comment = newNode;
}
else if (isQuery(token, lastToken)) {
var data = processQuery(this.tokens, index, this.cursorPosition);
if (data.positionData && !positionData) {
positionData = data.positionData;
}
else if (positionData) {
positionData.query = data.query;
}
}
else if (bracketIndent === 1 && parenthesisIndent === 1) {
if (lastToken && nextToken && isFunction(lastToken, token, nextToken)) {
var newNode = new core_1.AuraJSFunction(lastToken.text, lastToken, comment);
index = processFunction(newNode, this.tokens, index);
if (comment) {
comment = undefined;
}
methods.push(newNode);
}
}
}
this.node.methods = methods;
if (positionData) {
this.node.positionData = positionData;
}
return this.node;
};
return JSParser;
}());
exports.JSParser = JSParser;
function processFunction(newNode, tokens, index) {
var len = tokens.length;
var varNames = [];
for (; index < len; index++) {
var token = new core_1.Token(tokens[index]);
if (token.type === core_1.JSTokenTypes.BRACKET.PARENTHESIS_DECLARATION_PARAM_CLOSE) {
break;
}
if (token.type === core_1.JSTokenTypes.ENTITY.VARIABLE) {
varNames.push(token.text);
newNode.params.push(token);
}
}
newNode.signature = newNode.name + '(' + varNames.join(', ') + ')';
newNode.auraSignature = newNode.name + ' : function(' + varNames.join(', ') + ')';
return index;
}
function openBracket(token) {
return token && token.type === core_1.JSTokenTypes.BRACKET.CURLY_OPEN;
}
function closeBracket(token) {
return token && token.type === core_1.JSTokenTypes.BRACKET.CURLY_CLOSE;
}
function openParenthesis(token) {
return token && token.type === core_1.JSTokenTypes.OPERATOR.PRIORITY.PARENTHESIS_OPEN;
}
function closeParenthesis(token) {
return token && token.type === core_1.JSTokenTypes.OPERATOR.PRIORITY.PARENTHESIS_CLOSE;
}
function openCommentBlock(token) {
return token && token.type === core_1.JSTokenTypes.COMMENT.BLOCK_START;
}
function closeCommentBlock(token) {
return token && token.type === core_1.JSTokenTypes.COMMENT.BLOCK_END;
}
function isCommentLine(token) {
return token && (token.type === core_1.JSTokenTypes.COMMENT.LINE || token.type === core_1.JSTokenTypes.COMMENT.LINE_DOC);
}
function isFunction(lastToken, token, nextToken) {
return token.type === core_1.JSTokenTypes.PUNCTUATION.COLON && lastToken.type === core_1.JSTokenTypes.ENTITY.VARIABLE && nextToken && nextToken.type === core_1.JSTokenTypes.KEYWORD.DECLARATION.FUNCTION;
}
function processCommentBlock(node, tokens, index) {
var len = tokens.length;
for (; index < len; index++) {
var token = tokens[index];
if (!closeCommentBlock(token)) {
node.addToken(token);
}
else {
node.addToken(token);
break;
}
}
return index;
}
function processCommentLine(node, tokens, index) {
var len = tokens.length;
for (; index < len; index++) {
var token = tokens[index];
if (token.type === core_1.JSTokenTypes.COMMENT.LINE || token.type === core_1.JSTokenTypes.COMMENT.LINE_DOC || token.type === core_1.JSTokenTypes.COMMENT.CONTENT) {
node.addToken(token);
}
else {
break;
}
}
index--;
return index;
}
function isQuery(token, lastToken) {
if (lastToken && (lastToken.type === core_1.JSTokenTypes.PUNCTUATION.QUOTTES_START || lastToken.type === core_1.JSTokenTypes.PUNCTUATION.DOUBLE_QUOTTES_START) && token.textToLower === 'select') {
return true;
}
return false;
}
function processQuery(tokens, index, position) {
var len = tokens.length;
var token = tokens[index];
var lastToken = utils_1.LanguageUtils.getLastToken(tokens, index);
var positionData;
var query = new core_1.SOQLQuery('query', 'Query', token);
var onProjection = false;
var field = '';
var fieldStartToken;
for (; index < len; index++) {
lastToken = utils_1.LanguageUtils.getLastToken(tokens, index);
token = tokens[index];
var nextToken = utils_1.LanguageUtils.getNextToken(tokens, index);
if (position && query && !positionData) {
if (utils_1.LanguageUtils.isOnPosition(token, lastToken, nextToken, position)) {
var startIndex = position.character - token.range.start.character;
var startPart = token.text.substring(0, startIndex + 1);
var endPart = token.text.substring(startIndex + 1);
positionData = new core_1.PositionData(startPart, endPart, query.nodeType, query.id, 'Aura');
positionData.onText = token.type === core_1.JSTokenTypes.PUNCTUATION.DOUBLE_QUOTTES_START || token.type === core_1.JSTokenTypes.PUNCTUATION.QUOTTES_START || token.type === core_1.JSTokenTypes.PUNCTUATION.DOUBLE_QUOTTES_END || token.type === core_1.JSTokenTypes.PUNCTUATION.QUOTTES_END || token.type === core_1.JSTokenTypes.LITERAL.STRING;
}
}
if (token.textToLower === 'from') {
if (field) {
query.projection.push(new core_1.SOQLField(query.id + 'field_' + field, field, fieldStartToken));
field = '';
fieldStartToken = undefined;
}
onProjection = false;
query.from = nextToken;
}
else if (token.textToLower === 'select') {
onProjection = true;
}
else if ((token.type === core_1.JSTokenTypes.PUNCTUATION.QUOTTES_END || token.type === core_1.JSTokenTypes.PUNCTUATION.DOUBLE_QUOTTES_END)) {
query.endToken = token;
break;
}
else if (onProjection) {
if (token.textToLower === ',') {
query.projection.push(new core_1.SOQLField(query.id + 'field_' + field, field, fieldStartToken));
field = '';
fieldStartToken = undefined;
}
else if (isQuery(token, lastToken)) {
var data = processQuery(tokens, index, position);
index = data.index;
query.projection.push(data.query);
if (data.positionData && !positionData) {
positionData = data.positionData;
}
}
else {
field += token.text;
if (!fieldStartToken) {
fieldStartToken = token;
}
}
}
}
if (positionData) {
positionData.query = query;
}
return {
query: query,
positionData: positionData,
index: index
};
}
//# sourceMappingURL=parser.js.map