UNPKG

@rightcapital/phpdoc-parser

Version:

TypeScript version of PHPDoc parser with support for intersection types and generics

147 lines (146 loc) 8.26 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConstExprParser = void 0; const const_expr_array_item_node_1 = require("../ast/const-expr/const-expr-array-item-node"); const const_expr_array_node_1 = require("../ast/const-expr/const-expr-array-node"); const const_expr_false_node_1 = require("../ast/const-expr/const-expr-false-node"); const const_expr_float_node_1 = require("../ast/const-expr/const-expr-float-node"); const const_expr_integer_node_1 = require("../ast/const-expr/const-expr-integer-node"); const const_expr_null_node_1 = require("../ast/const-expr/const-expr-null-node"); const const_expr_string_node_1 = require("../ast/const-expr/const-expr-string-node"); const const_expr_true_node_1 = require("../ast/const-expr/const-expr-true-node"); const const_fetch_node_1 = require("../ast/const-expr/const-fetch-node"); const quote_aware_const_expr_string_node_1 = require("../ast/const-expr/quote-aware-const-expr-string-node"); const types_1 = require("../ast/types"); const lexer_1 = require("../lexer/lexer"); const parser_exception_1 = require("./parser-exception"); const string_unescaper_1 = require("./string-unescaper"); class ConstExprParser { constructor(unescapeStrings = false, quoteAwareConstExprString = false, usedAttributes = {}) { var _a, _b; this.unescapeStrings = unescapeStrings; this.quoteAwareConstExprString = quoteAwareConstExprString; this.useLinesAttributes = (_a = usedAttributes.lines) !== null && _a !== void 0 ? _a : false; this.useIndexAttributes = (_b = usedAttributes.indexes) !== null && _b !== void 0 ? _b : false; } parse(tokens, trimStrings = false) { const startLine = tokens.currentTokenLine(); const startIndex = tokens.currentTokenIndex(); if (tokens.isCurrentTokenType(lexer_1.Lexer.TOKEN_FLOAT)) { const value = tokens.currentTokenValue(); tokens.next(); return this.enrichWithAttributes(tokens, new const_expr_float_node_1.ConstExprFloatNode(value.replaceAll('_', '')), startLine, startIndex); } if (tokens.isCurrentTokenType(lexer_1.Lexer.TOKEN_INTEGER)) { const value = tokens.currentTokenValue(); tokens.next(); return this.enrichWithAttributes(tokens, new const_expr_integer_node_1.ConstExprIntegerNode(value.replaceAll('_', '')), startLine, startIndex); } if (tokens.isCurrentTokenType(lexer_1.Lexer.TOKEN_SINGLE_QUOTED_STRING, lexer_1.Lexer.TOKEN_DOUBLE_QUOTED_STRING)) { let value = tokens.currentTokenValue(); const type = tokens.currentTokenType(); if (trimStrings) { if (this.unescapeStrings) { value = string_unescaper_1.StringUnescaper.unescapeString(value); } else { value = value.substring(1, value.length - 1); } } tokens.next(); if (this.quoteAwareConstExprString) { return this.enrichWithAttributes(tokens, new quote_aware_const_expr_string_node_1.QuoteAwareConstExprStringNode(value, type === lexer_1.Lexer.TOKEN_SINGLE_QUOTED_STRING ? quote_aware_const_expr_string_node_1.QuoteAwareConstExprStringNode.SINGLE_QUOTED : quote_aware_const_expr_string_node_1.QuoteAwareConstExprStringNode.DOUBLE_QUOTED), startLine, startIndex); } return this.enrichWithAttributes(tokens, new const_expr_string_node_1.ConstExprStringNode(value), startLine, startIndex); } if (tokens.isCurrentTokenType(lexer_1.Lexer.TOKEN_IDENTIFIER)) { const identifier = tokens.currentTokenValue(); tokens.next(); switch (identifier.toLowerCase()) { case 'true': return this.enrichWithAttributes(tokens, new const_expr_true_node_1.ConstExprTrueNode(), startLine, startIndex); case 'false': return this.enrichWithAttributes(tokens, new const_expr_false_node_1.ConstExprFalseNode(), startLine, startIndex); case 'null': return this.enrichWithAttributes(tokens, new const_expr_null_node_1.ConstExprNullNode(), startLine, startIndex); case 'array': tokens.consumeTokenType(lexer_1.Lexer.TOKEN_OPEN_PARENTHESES); return this.parseArray(tokens, lexer_1.Lexer.TOKEN_CLOSE_PARENTHESES, startIndex); } if (tokens.tryConsumeTokenType(lexer_1.Lexer.TOKEN_DOUBLE_COLON)) { let classConstantName = ''; let lastType = null; while (true) { if (lastType !== lexer_1.Lexer.TOKEN_IDENTIFIER && tokens.currentTokenType() === lexer_1.Lexer.TOKEN_IDENTIFIER) { classConstantName += tokens.currentTokenValue(); tokens.consumeTokenType(lexer_1.Lexer.TOKEN_IDENTIFIER); lastType = lexer_1.Lexer.TOKEN_IDENTIFIER; continue; } if (lastType !== lexer_1.Lexer.TOKEN_WILDCARD && tokens.tryConsumeTokenType(lexer_1.Lexer.TOKEN_WILDCARD)) { classConstantName += '*'; lastType = lexer_1.Lexer.TOKEN_WILDCARD; if (tokens.getSkippedHorizontalWhiteSpaceIfAny() !== '') { break; } continue; } if (lastType === null) { tokens.consumeTokenType(lexer_1.Lexer.TOKEN_WILDCARD); } break; } return this.enrichWithAttributes(tokens, new const_fetch_node_1.ConstFetchNode(identifier, classConstantName), startLine, startIndex); } return this.enrichWithAttributes(tokens, new const_fetch_node_1.ConstFetchNode('', identifier), startLine, startIndex); } if (tokens.tryConsumeTokenType(lexer_1.Lexer.TOKEN_OPEN_SQUARE_BRACKET)) { return this.parseArray(tokens, lexer_1.Lexer.TOKEN_CLOSE_SQUARE_BRACKET, startIndex); } throw new parser_exception_1.ParserException(tokens.currentTokenValue(), tokens.currentTokenType(), tokens.currentTokenOffset(), lexer_1.Lexer.TOKEN_IDENTIFIER, null, tokens.currentTokenLine()); } parseArray(tokens, endToken, startIndex) { const items = []; const startLine = tokens.currentTokenLine(); if (!tokens.tryConsumeTokenType(endToken)) { do { items.push(this.parseArrayItem(tokens)); } while (tokens.tryConsumeTokenType(lexer_1.Lexer.TOKEN_COMMA) && !tokens.isCurrentTokenType(endToken)); tokens.consumeTokenType(endToken); } return this.enrichWithAttributes(tokens, new const_expr_array_node_1.ConstExprArrayNode(items), startLine, startIndex); } parseArrayItem(tokens) { const startLine = tokens.currentTokenLine(); const startIndex = tokens.currentTokenIndex(); const expr = this.parse(tokens); let key; let value; if (tokens.tryConsumeTokenType(lexer_1.Lexer.TOKEN_DOUBLE_ARROW)) { key = expr; value = this.parse(tokens); } else { key = null; value = expr; } return this.enrichWithAttributes(tokens, new const_expr_array_item_node_1.ConstExprArrayItemNode(key, value), startLine, startIndex); } enrichWithAttributes(tokens, node, startLine, startIndex) { if (this.useLinesAttributes) { node.setAttribute(types_1.Attribute.START_LINE, startLine); node.setAttribute(types_1.Attribute.END_LINE, tokens.currentTokenLine()); } if (this.useIndexAttributes) { node.setAttribute(types_1.Attribute.START_INDEX, startIndex); node.setAttribute(types_1.Attribute.END_INDEX, tokens.endIndexOfLastRelevantToken()); } return node; } } exports.ConstExprParser = ConstExprParser;