UNPKG

@aurahelper/languages

Version:

Language Libraries to work with XML, Aura, Apex... files. tokenizers, parsers, system classes and much more

333 lines 14 kB
"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