From 9d54bd6b311cd24f64515c3bcfd6f821882574fa Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Sun, 13 Jun 2021 16:50:06 +0900 Subject: [PATCH] Fix crash when using `objectsInObjects` option in `vue/object-curly-spacing` rule. (#1515) --- lib/utils/index.js | 46 +++++++++++++++++++ tests/lib/rules/object-curly-spacing.js | 60 +++++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/lib/utils/index.js b/lib/utils/index.js index e78238ee3..112297af1 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -101,6 +101,7 @@ const SVG_ELEMENT_NAMES = new Set(require('./svg-elements.json')) const VOID_ELEMENT_NAMES = new Set(require('./void-elements.json')) const path = require('path') const vueEslintParser = require('vue-eslint-parser') +const traverseNodes = vueEslintParser.AST.traverseNodes const { findVariable } = require('eslint-utils') /** @@ -142,11 +143,56 @@ function wrapContextToOverrideTokenMethods(context, tokenStore) { : [] return tokensAndComments } + + /** @param {number} index */ + function getNodeByRangeIndex(index) { + const templateBody = eslintSourceCode.ast.templateBody + if (!templateBody) { + return eslintSourceCode.ast + } + + /** @type {ASTNode} */ + let result = eslintSourceCode.ast + /** @type {ASTNode[]} */ + const skipNodes = [] + let breakFlag = false + + traverseNodes(templateBody, { + enterNode(node, parent) { + if (breakFlag) { + return + } + if (skipNodes[0] === parent) { + skipNodes.unshift(node) + return + } + if (node.range[0] <= index && index < node.range[1]) { + result = node + } else { + skipNodes.unshift(node) + } + }, + leaveNode(node) { + if (breakFlag) { + return + } + if (result === node) { + breakFlag = true + } else if (skipNodes[0] === node) { + skipNodes.shift() + } + } + }) + return result + } const sourceCode = new Proxy(Object.assign({}, eslintSourceCode), { get(_object, key) { if (key === 'tokensAndComments') { return getTokensAndComments() } + if (key === 'getNodeByRangeIndex') { + return getNodeByRangeIndex + } // @ts-expect-error return key in tokenStore ? tokenStore[key] : eslintSourceCode[key] } diff --git a/tests/lib/rules/object-curly-spacing.js b/tests/lib/rules/object-curly-spacing.js index 0aba0cb04..874f4dd41 100644 --- a/tests/lib/rules/object-curly-spacing.js +++ b/tests/lib/rules/object-curly-spacing.js @@ -26,6 +26,20 @@ tester.run('object-curly-spacing', rule, { { code: '', options: ['always'] + }, + { + code: ` + `, + options: [ + 'never', + { + objectsInObjects: true + } + ] } ], invalid: [ @@ -97,6 +111,52 @@ tester.run('object-curly-spacing', rule, { "A space is required after '{'.", "A space is required before '}'." ] + }, + { + code: ` + `, + options: [ + 'never', + { + objectsInObjects: true + } + ], + output: ` + `, + errors: [ + "There should be no space after '{'.", + "There should be no space after '{'.", + "There should be no space before '}'.", + "A space is required before '}'." + ] + }, + { + code: ` + `, + options: ['never'], + output: ` + `, + errors: [ + "There should be no space after '{'.", + "There should be no space after '{'.", + "There should be no space before '}'." + ] } ] })