UNPKG

@codeque/core

Version:

Multiline code search for every language. Structural code search for JavaScript, TypeScript, HTML and CSS

225 lines (188 loc) 6.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.babelEslintParserSettings = void 0; var _eslintParser = require("@babel/eslint-parser"); var _JSFamilyCommon = require("../_common/JSFamilyCommon"); var _common = require("./common"); var _utils = require("../../utils"); var _afterWildcardsComparators = require("./afterWildcardsComparators"); var _beforeWildcardsComparators = require("./beforeWildcardsComparators"); const parseCode = (code, filePath = '') => { const maybeWrappedJSON = /\.json$/.test(filePath) ? `(${code})` : code; try { return (0, _eslintParser.parse)(maybeWrappedJSON, { filePath, sourceType: 'module', requireConfigFile: false, allowImportExportEverywhere: false, babelOptions: { babelrc: false, /** * ❗ Note that enabling config file makes babel look for package.json, which will crash in browser runtime * At some point we might need to enable resolving plugins from users config files, it might be blocking some syntaxes. * But since @babel/eslint-parser is bit retarded it terms of configuration, it might be an edge case which we will never run into. */ configFile: false, parserOpts: { plugins: ['jsx'] } } }); } catch (e) { return (0, _eslintParser.parse)(maybeWrappedJSON, { filePath, sourceType: 'module', requireConfigFile: false, allowImportExportEverywhere: false, babelOptions: { babelrc: false, configFile: false, parserOpts: { plugins: [] } } }); } }; /** * We mimic @babel/eslint-parser, but we don't use it directly, as it has not documented API * We need this only for purpose of eslint plugin and to make sure that output AST is searchable */ const getProgramNodeFromRootNode = fileOrProgramNode => 'program' in fileOrProgramNode ? fileOrProgramNode.program : fileOrProgramNode; const getProgramBodyFromRootNode = fileOrProgramNode => { return getProgramNodeFromRootNode(fileOrProgramNode).body; }; const isIdentifierNode = node => _common.identifierNodeTypes.includes((0, _common.getNodeType)(node)); const alternativeNodeTypes = { Identifier: _common.identifierNodeTypes, ChainExpression: ['MemberExpression'], MemberExpression: ['ChainExpression'], BlockStatement: ['Program'] }; const unwrapExpressionStatement = node => { if (typeof node !== 'object') { return node; } if (node.type === 'ExpressionStatement') { return node.expression; } return node; }; const createBlockStatementNode = (body, position) => ({ type: 'BlockStatement', body, loc: position.loc, range: [position.start, position.end] }); const isNode = maybeNode => { return typeof maybeNode?.type === 'string'; }; const astPropsToSkip = ['loc', 'range', 'raw', 'trailingComments', 'leadingComments', 'comments', 'tail', // Support for partial matching of template literals 'parent', // in eslint there is parent prop in node { type: 'ArrowFunctionExpression', key: 'expression' }, // flag on ArrowFunctionExpression 'tokens', 'start', 'end', 'extra']; const sanitizeTemplateElementValue = ({ raw, cooked }) => { return { raw: (0, _utils.normalizeText)(raw), cooked: (0, _utils.normalizeText)(cooked) }; }; const nodeValuesSanitizers = { ['JSXText']: { value: _utils.normalizeText, raw: _utils.normalizeText }, ['TemplateElement']: { value: sanitizeTemplateElementValue } }; const getSanitizedNodeValue = (nodeType, valueKey, value) => { const valueSanitizer = nodeValuesSanitizers?.[nodeType]?.[valueKey]; if (valueSanitizer) { return valueSanitizer(value); } return value; }; const shouldCompareNode = node => { if (node.type === 'JSXText') { const value = getSanitizedNodeValue('JSXText', 'value', node.value); return value.length > 0; } return true; }; const compareNodesBeforeWildcardsComparison = (...nodeComparatorParams) => { return (0, _utils.runNodesComparators)(_beforeWildcardsComparators.beforeWildcardsComparators, nodeComparatorParams); }; const compareNodesAfterWildcardsComparison = (...nodeComparatorParams) => { return (0, _utils.runNodesComparators)(_afterWildcardsComparators.afterWildcardsComparators, nodeComparatorParams); }; const isFirstCharStringStart = str => str.charAt(0) === `'` || str.charAt(0) === `"`; const stringLikeLiteralUtils = { isStringLikeLiteralNode: node => node.type === 'Literal' && isFirstCharStringStart(node.raw) || node.type === 'TemplateElement' || node.type === 'JSXText', getStringLikeLiteralValue: node => { if (node.type === 'TemplateElement') { const { raw } = sanitizeTemplateElementValue(node.value); return raw; } // (node.type === 'Literal' || node.type === 'JSXText' return (0, _utils.normalizeText)(node.value); } }; const numericLiteralUtils = { isNumericLiteralNode: node => node.type === 'Literal' && !isFirstCharStringStart(node.raw), getNumericLiteralValue: node => node.raw }; const programNodeAndBlockNodeUtils = { isProgramNode: node => node.type === 'Program', isBlockNode: node => node.type === 'BlockStatement', programNodeBodyKey: 'body', blockNodeBodyKey: 'body' }; const getNodePosition = node => ({ start: node.range[0], end: node.range[1], loc: node.loc }); const getParseErrorLocation = e => ({ line: e.lineNumber ?? 0, column: e.column ?? 0 }); const babelEslintParserSettings = { parseCode, getProgramNodeFromRootNode, getProgramBodyFromRootNode, isIdentifierNode, getNodeType: _common.getNodeType, wildcardUtils: _common.wildcardUtils, setIdentifierNodeName: _common.setIdentifierNodeName, alternativeNodeTypes, astPropsToSkip, supportedExtensions: _JSFamilyCommon.supportedExtensions, isNode, identifierNodeTypes: _common.identifierNodeTypes, getIdentifierNodeName: _common.getIdentifierNodeName, unwrapExpressionStatement, createBlockStatementNode, getSanitizedNodeValue, shouldCompareNode, compareNodesBeforeWildcardsComparison, compareNodesAfterWildcardsComparison, identifierTypeAnnotationFieldName: 'typeAnnotation', stringLikeLiteralUtils, numericLiteralUtils, programNodeAndBlockNodeUtils, getNodePosition, getParseErrorLocation }; exports.babelEslintParserSettings = babelEslintParserSettings; var _default = babelEslintParserSettings; exports.default = _default;