UNPKG

sql-formatter

Version:

Format whitespace in a SQL query to make it more readable

90 lines 4.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.disambiguateTokens = void 0; const token_js_1 = require("./token.js"); /** * Ensures that no keyword token (RESERVED_*) is preceded or followed by a dot (.) * or any other property-access operator. * * Ensures that all RESERVED_FUNCTION_NAME tokens are followed by "(". * If they're not, converts the token to IDENTIFIER. * * Converts RESERVED_DATA_TYPE tokens followed by "(" to RESERVED_PARAMETERIZED_DATA_TYPE. * * When IDENTIFIER or RESERVED_DATA_TYPE token is followed by "[" * converts it to ARRAY_IDENTIFIER or ARRAY_KEYWORD accordingly. * * This is needed to avoid ambiguity in parser which expects function names * to always be followed by open-paren, and to distinguish between * array accessor `foo[1]` and array literal `[1, 2, 3]`. */ function disambiguateTokens(tokens) { return tokens .map(propertyNameKeywordToIdent) .map(funcNameToIdent) .map(dataTypeToParameterizedDataType) .map(identToArrayIdent) .map(dataTypeToArrayKeyword); } exports.disambiguateTokens = disambiguateTokens; const propertyNameKeywordToIdent = (token, i, tokens) => { if ((0, token_js_1.isReserved)(token.type)) { const prevToken = prevNonCommentToken(tokens, i); if (prevToken && prevToken.type === token_js_1.TokenType.PROPERTY_ACCESS_OPERATOR) { return Object.assign(Object.assign({}, token), { type: token_js_1.TokenType.IDENTIFIER, text: token.raw }); } const nextToken = nextNonCommentToken(tokens, i); if (nextToken && nextToken.type === token_js_1.TokenType.PROPERTY_ACCESS_OPERATOR) { return Object.assign(Object.assign({}, token), { type: token_js_1.TokenType.IDENTIFIER, text: token.raw }); } } return token; }; const funcNameToIdent = (token, i, tokens) => { if (token.type === token_js_1.TokenType.RESERVED_FUNCTION_NAME) { const nextToken = nextNonCommentToken(tokens, i); if (!nextToken || !isOpenParen(nextToken)) { return Object.assign(Object.assign({}, token), { type: token_js_1.TokenType.IDENTIFIER, text: token.raw }); } } return token; }; const dataTypeToParameterizedDataType = (token, i, tokens) => { if (token.type === token_js_1.TokenType.RESERVED_DATA_TYPE) { const nextToken = nextNonCommentToken(tokens, i); if (nextToken && isOpenParen(nextToken)) { return Object.assign(Object.assign({}, token), { type: token_js_1.TokenType.RESERVED_PARAMETERIZED_DATA_TYPE }); } } return token; }; const identToArrayIdent = (token, i, tokens) => { if (token.type === token_js_1.TokenType.IDENTIFIER) { const nextToken = nextNonCommentToken(tokens, i); if (nextToken && isOpenBracket(nextToken)) { return Object.assign(Object.assign({}, token), { type: token_js_1.TokenType.ARRAY_IDENTIFIER }); } } return token; }; const dataTypeToArrayKeyword = (token, i, tokens) => { if (token.type === token_js_1.TokenType.RESERVED_DATA_TYPE) { const nextToken = nextNonCommentToken(tokens, i); if (nextToken && isOpenBracket(nextToken)) { return Object.assign(Object.assign({}, token), { type: token_js_1.TokenType.ARRAY_KEYWORD }); } } return token; }; const prevNonCommentToken = (tokens, index) => nextNonCommentToken(tokens, index, -1); const nextNonCommentToken = (tokens, index, dir = 1) => { let i = 1; while (tokens[index + i * dir] && isComment(tokens[index + i * dir])) { i++; } return tokens[index + i * dir]; }; const isOpenParen = (t) => t.type === token_js_1.TokenType.OPEN_PAREN && t.text === '('; const isOpenBracket = (t) => t.type === token_js_1.TokenType.OPEN_PAREN && t.text === '['; const isComment = (t) => t.type === token_js_1.TokenType.BLOCK_COMMENT || t.type === token_js_1.TokenType.LINE_COMMENT; //# sourceMappingURL=disambiguateTokens.js.map