From 2d6114bdac6d30efa658de744feb08b7a491504a Mon Sep 17 00:00:00 2001 From: Eduard Deisling Date: Tue, 19 Apr 2022 14:44:42 +0300 Subject: [PATCH 1/8] Add new rule: vue/define-macros-order (#1855) --- docs/rules/README.md | 2 + docs/rules/define-macros-order.md | 72 +++++++ lib/index.js | 1 + lib/rules/define-macros-order.js | 248 ++++++++++++++++++++++ tests/lib/rules/define-macros-order.js | 275 +++++++++++++++++++++++++ 5 files changed, 598 insertions(+) create mode 100644 docs/rules/define-macros-order.md create mode 100644 lib/rules/define-macros-order.js create mode 100644 tests/lib/rules/define-macros-order.js diff --git a/docs/rules/README.md b/docs/rules/README.md index 3d2d113d7..e7ff5c423 100644 --- a/docs/rules/README.md +++ b/docs/rules/README.md @@ -12,6 +12,7 @@ sidebarDepth: 0 :bulb: Indicates that some problems reported by the rule are manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions). ::: + ## Base Rules (Enabling Correct ESLint Parsing) Enforce all the rules in this category, as well as all higher priority rules, with: @@ -312,6 +313,7 @@ For example: | [vue/component-name-in-template-casing](./component-name-in-template-casing.md) | enforce specific casing for the component naming style in template | :wrench: | | [vue/component-options-name-casing](./component-options-name-casing.md) | enforce the casing of component name in `components` options | :wrench::bulb: | | [vue/custom-event-name-casing](./custom-event-name-casing.md) | enforce specific casing for custom event name | | +| [vue/define-macros-order](./define-macros-order.md) | enforce order of `defineEmits` and `defineProps` compiler macros | :wrench: | | [vue/html-button-has-type](./html-button-has-type.md) | disallow usage of button without an explicit type attribute | | | [vue/html-comment-content-newline](./html-comment-content-newline.md) | enforce unified line brake in HTML comments | :wrench: | | [vue/html-comment-content-spacing](./html-comment-content-spacing.md) | enforce unified spacing in HTML comments | :wrench: | diff --git a/docs/rules/define-macros-order.md b/docs/rules/define-macros-order.md new file mode 100644 index 000000000..fdb506914 --- /dev/null +++ b/docs/rules/define-macros-order.md @@ -0,0 +1,72 @@ +--- +pageClass: rule-details +sidebarDepth: 0 +title: vue/define-macros-order +description: enforce order of `defineEmits` and `defineProps` compiler macros +--- +# vue/define-macros-order + +> enforce order of `defineEmits` and `defineProps` compiler macros + +- :exclamation: ***This rule has not been released yet.*** +- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. + +## :book: Rule Details + +This rule reports the situation when `defineProps` or `defineEmits` not on the top or have wrong order + +## :wrench: Options + +```json +{ + "vue/define-macros-order": ["error", { + "order": [ "defineEmits", "defineProps" ] + }] +} +``` + +- `order` (`string[]`) ... The order of defineEmits and defineProps macros + +### `{ "order": [ "defineEmits", "defineProps" ] }` (default) + + + +```vue + + +``` + + + + + +```vue + + +``` + + + + + +```vue + + +``` + + + +## :mag: Implementation + +- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/define-macros-order.js) +- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/define-macros-order.js) diff --git a/lib/index.js b/lib/index.js index d412a6bf1..39f91b515 100644 --- a/lib/index.js +++ b/lib/index.js @@ -27,6 +27,7 @@ module.exports = { 'component-options-name-casing': require('./rules/component-options-name-casing'), 'component-tags-order': require('./rules/component-tags-order'), 'custom-event-name-casing': require('./rules/custom-event-name-casing'), + 'define-macros-order': require('./rules/define-macros-order'), 'dot-location': require('./rules/dot-location'), 'dot-notation': require('./rules/dot-notation'), eqeqeq: require('./rules/eqeqeq'), diff --git a/lib/rules/define-macros-order.js b/lib/rules/define-macros-order.js new file mode 100644 index 000000000..dca9571b3 --- /dev/null +++ b/lib/rules/define-macros-order.js @@ -0,0 +1,248 @@ +/** + * @author Eduard Deisling + * See LICENSE file in root directory for full license. + */ +'use strict' + +// ------------------------------------------------------------------------------ +// Requirements +// ------------------------------------------------------------------------------ + +const utils = require('../utils') + +// ------------------------------------------------------------------------------ +// Helpers +// ------------------------------------------------------------------------------ + +const MACROS_EMITS = 'defineEmits' +const MACROS_PROPS = 'defineProps' +const ORDER = [MACROS_EMITS, MACROS_PROPS] +const DEFAULT_ORDER = [MACROS_EMITS, MACROS_PROPS] + +/** + * Get an index of the first statement after imports in order to place + * defineEmits and defineProps before this statement + * @param {Program} program + */ +function getStatementAfterImportsIndex(program) { + let index = -1 + + program.body.some((item, i) => { + index = i + return item.type !== 'ImportDeclaration' + }) + + return index +} + +/** + * We need to handle cases like "const props = defineProps(...)" + * Define macros must be used only on top, so we can look for "Program" type + * inside node.parent.type + * @param {CallExpression|ASTNode} node + * @return {ASTNode} + */ +function getDefineMacrosStatement(node) { + if (!node.parent) { + throw new Error('Macros has parent') + } + + if (node.parent.type === 'Program') { + return node + } + + return getDefineMacrosStatement(node.parent) +} + +// ------------------------------------------------------------------------------ +// Rule Definition +// ------------------------------------------------------------------------------ + +/** @param {RuleContext} context */ +function create(context) { + const scriptSetup = utils.getScriptSetupElement(context) + + if (!scriptSetup) { + return {} + } + + const sourceCode = context.getSourceCode() + const options = context.options + /** @type {[string, string]} */ + const order = (options[0] && options[0].order) || DEFAULT_ORDER + /** @type {Map} */ + const macrosNodes = new Map() + + return utils.compositingVisitors( + utils.defineScriptSetupVisitor(context, { + onDefinePropsExit(node) { + macrosNodes.set(MACROS_PROPS, getDefineMacrosStatement(node)) + }, + onDefineEmitsExit(node) { + macrosNodes.set(MACROS_EMITS, getDefineMacrosStatement(node)) + } + }), + { + 'Program:exit'(program) { + const shouldFirstNode = macrosNodes.get(order[0]) + const shouldSecondNode = macrosNodes.get(order[1]) + const firstStatementIndex = getStatementAfterImportsIndex(program) + const firstStatement = program.body[firstStatementIndex] + + // have both defineEmits and defineProps + if (shouldFirstNode && shouldSecondNode) { + const secondStatement = program.body[firstStatementIndex + 1] + + // need move only first + if (firstStatement === shouldSecondNode) { + reportNotOnTop(order[1], shouldFirstNode, firstStatement) + return + } + + // need move both defineEmits and defineProps + if (firstStatement !== shouldFirstNode) { + reportBothNotOnTop( + shouldFirstNode, + shouldSecondNode, + firstStatement + ) + return + } + + // need move only second + if (secondStatement !== shouldSecondNode) { + reportNotOnTop(order[1], shouldSecondNode, shouldFirstNode) + } + + return + } + + // have only first and need to move it + if (shouldFirstNode && firstStatement !== shouldFirstNode) { + reportNotOnTop(order[0], shouldFirstNode, firstStatement) + return + } + + // have only second and need to move it + if (shouldSecondNode && firstStatement !== shouldSecondNode) { + reportNotOnTop(order[1], shouldSecondNode, firstStatement) + } + } + } + ) + + /** + * @param {ASTNode} shouldFirstNode + * @param {ASTNode} shouldSecondNode + * @param {ASTNode} before + */ + function reportBothNotOnTop(shouldFirstNode, shouldSecondNode, before) { + context.report({ + node: shouldFirstNode, + loc: shouldFirstNode.loc, + messageId: 'macrosNotOnTop', + data: { + macro: order[0] + }, + fix(fixer) { + return [ + ...moveNodeBefore(fixer, shouldFirstNode, before), + ...moveNodeBefore(fixer, shouldSecondNode, before) + ] + } + }) + } + + /** + * @param {string} macro + * @param {ASTNode} node + * @param {ASTNode} before + */ + function reportNotOnTop(macro, node, before) { + context.report({ + node, + loc: node.loc, + messageId: 'macrosNotOnTop', + data: { + macro + }, + fix(fixer) { + return moveNodeBefore(fixer, node, before) + } + }) + } + + /** + * Move one newline with "node" to before the "beforeNode" + * @param {RuleFixer} fixer + * @param {ASTNode} node + * @param {ASTNode} beforeNode + */ + function moveNodeBefore(fixer, node, beforeNode) { + const beforeNodeToken = sourceCode.getTokenBefore(node, { + includeComments: true + }) + const beforeNodeIndex = getNewLineIndex(node) + const textNode = sourceCode.getText(node, node.range[0] - beforeNodeIndex) + /** @type {[number, number]} */ + const removeRange = [beforeNodeToken.range[1], node.range[1]] + const index = getNewLineIndex(beforeNode) + + return [ + fixer.insertTextAfterRange([index, index], textNode), + fixer.removeRange(removeRange) + ] + } + + /** + * Get index of first new line before the "node" + * @param {ASTNode} node + * @return {number} + */ + function getNewLineIndex(node) { + const after = sourceCode.getTokenBefore(node, { includeComments: true }) + const hasWhitespace = node.loc.start.line - after.loc.end.line > 1 + + if (!hasWhitespace) { + return after.range[1] + } + + return sourceCode.getIndexFromLoc({ + line: node.loc.start.line - 1, + column: 0 + }) + } +} + +module.exports = { + meta: { + type: 'layout', + docs: { + description: + 'enforce order of `defineEmits` and `defineProps` compiler macros', + categories: undefined, + url: 'https://eslint.vuejs.org/rules/define-macros-order.html' + }, + fixable: 'code', + schema: [ + { + type: 'object', + properties: { + order: { + type: 'array', + items: { + enum: Object.values(ORDER) + }, + uniqueItems: true, + additionalItems: false + } + }, + additionalProperties: false + } + ], + messages: { + macrosNotOnTop: '{{macro}} must be on top.' + } + }, + create +} diff --git a/tests/lib/rules/define-macros-order.js b/tests/lib/rules/define-macros-order.js new file mode 100644 index 000000000..d9de414f7 --- /dev/null +++ b/tests/lib/rules/define-macros-order.js @@ -0,0 +1,275 @@ +/** + * @author *****your name***** + * See LICENSE file in root directory for full license. + */ +'use strict' + +const RuleTester = require('eslint').RuleTester +const rule = require('../../../lib/rules/define-macros-order') + +const tester = new RuleTester({ + parser: require.resolve('vue-eslint-parser'), + parserOptions: { + ecmaVersion: 2020, + sourceType: 'module' + } +}) + +const optionsEmitsFirst = [ + { + order: ['defineEmits', 'defineProps'] + } +] + +const optionsPropsFirst = [ + { + order: ['defineProps', 'defineEmits'] + } +] + +tester.run('define-macros-order', rule, { + valid: [ + { + filename: 'test.vue', + code: ` + + `, + options: optionsPropsFirst + }, + { + filename: 'test.vue', + code: ` + + `, + parserOptions: { + parser: require.resolve('@typescript-eslint/parser') + } + }, + { + filename: 'test.vue', + code: ` + + `, + options: optionsPropsFirst + }, + { + filename: 'test.vue', + code: ` + + `, + options: optionsPropsFirst + }, + { + filename: 'test.vue', + code: ` + + `, + options: optionsPropsFirst + }, + { + filename: 'test.vue', + code: ` + + `, + options: optionsEmitsFirst + } + ], + invalid: [ + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + options: optionsEmitsFirst, + errors: [ + { + message: 'defineEmits must be on top.', + line: 5 + } + ] + }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + options: optionsPropsFirst, + errors: [ + { + message: 'defineProps must be on top.', + line: 8 + } + ] + }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + options: optionsPropsFirst, + errors: [ + { + message: 'defineEmits must be on top.', + line: 6 + } + ] + }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + options: optionsEmitsFirst, + errors: [ + { + message: 'defineEmits must be on top.', + line: 8 + } + ] + }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + parserOptions: { + parser: require.resolve('@typescript-eslint/parser') + }, + options: optionsEmitsFirst, + errors: [ + { + message: 'defineEmits must be on top.', + line: 12 + } + ] + } + ] +}) From c7d10ad3f9fcef67e88ebcb2e6f41ad88441d8e0 Mon Sep 17 00:00:00 2001 From: Eduard Deisling Date: Tue, 19 Apr 2022 15:48:53 +0300 Subject: [PATCH 2/8] Fix review comments --- docs/rules/define-macros-order.md | 7 +++---- lib/rules/define-macros-order.js | 3 ++- tests/lib/rules/define-macros-order.js | 14 +++++++++----- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/rules/define-macros-order.md b/docs/rules/define-macros-order.md index fdb506914..adc352700 100644 --- a/docs/rules/define-macros-order.md +++ b/docs/rules/define-macros-order.md @@ -13,21 +13,20 @@ description: enforce order of `defineEmits` and `defineProps` compiler macros ## :book: Rule Details -This rule reports the situation when `defineProps` or `defineEmits` not on the top or have wrong order - +This rule reports the `defineProps` and `defineEmits` compiler macros when they are not the first statements in ` `, parserOptions: { @@ -274,6 +275,42 @@ tester.run('define-macros-order', rule, { line: 12 } ] + }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + parserOptions: { + parser: require.resolve('@typescript-eslint/parser') + }, + errors: [ + { + message: message('defineProps'), + line: 10 + } + ] } ] }) From 44621beeab499064b5125c0218d2a3e89c85f040 Mon Sep 17 00:00:00 2001 From: Eduard Deisling Date: Tue, 19 Apr 2022 17:07:36 +0300 Subject: [PATCH 4/8] Fix review comments --- docs/rules/define-macros-order.md | 1 + lib/rules/define-macros-order.js | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/rules/define-macros-order.md b/docs/rules/define-macros-order.md index adc352700..318e12800 100644 --- a/docs/rules/define-macros-order.md +++ b/docs/rules/define-macros-order.md @@ -14,6 +14,7 @@ description: enforce order of `defineEmits` and `defineProps` compiler macros ## :book: Rule Details This rule reports the `defineProps` and `defineEmits` compiler macros when they are not the first statements in ` `, @@ -311,6 +311,79 @@ tester.run('define-macros-order', rule, { line: 10 } ] + }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + parserOptions: { + parser: require.resolve('@typescript-eslint/parser') + }, + options: optionsEmitsFirst, + errors: [ + { + message: message('defineEmits'), + line: 16 + } + ] + }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + options: optionsEmitsFirst, + errors: [ + { + message: message('defineEmits'), + line: 3 + } + ] } ] }) From 066b35c778be20ca7af402dc38ff8aeb4ad735af Mon Sep 17 00:00:00 2001 From: Eduard Deisling Date: Wed, 20 Apr 2022 13:29:45 +0300 Subject: [PATCH 6/8] Add semicolons --- tests/lib/rules/define-macros-order.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/lib/rules/define-macros-order.js b/tests/lib/rules/define-macros-order.js index d72e10c64..37b3b5e15 100644 --- a/tests/lib/rules/define-macros-order.js +++ b/tests/lib/rules/define-macros-order.js @@ -323,13 +323,13 @@ tester.run('define-macros-order', rule, { /** Description for props */ const props = withDefaults(defineProps(), { msg: 'hello' - }) + }); console.log('test2') // Description for emit // Description for emit line 2 - const emit = defineEmits<{(e: 'test'): void}>() + const emit = defineEmits<{(e: 'test'): void}>(); console.log('test3') @@ -340,11 +340,11 @@ tester.run('define-macros-order', rule, { // Description for emit // Description for emit line 2 - const emit = defineEmits<{(e: 'test'): void}>() + const emit = defineEmits<{(e: 'test'): void}>(); /** Description for props */ const props = withDefaults(defineProps(), { msg: 'hello' - }) + }); console.log('test1') From 2a5ca8f26f2c3a706f0a53d22f059e4038c78646 Mon Sep 17 00:00:00 2001 From: Eduard Deisling Date: Thu, 21 Apr 2022 11:41:27 +0300 Subject: [PATCH 7/8] Add some newline heuristics --- docs/rules/define-macros-order.md | 10 +-- lib/rules/define-macros-order.js | 86 +++++++++++--------------- tests/lib/rules/define-macros-order.js | 13 ++-- 3 files changed, 49 insertions(+), 60 deletions(-) diff --git a/docs/rules/define-macros-order.md b/docs/rules/define-macros-order.md index 318e12800..d928e003a 100644 --- a/docs/rules/define-macros-order.md +++ b/docs/rules/define-macros-order.md @@ -20,22 +20,22 @@ This rule reports the `defineProps` and `defineEmits` compiler macros when they ```json { "vue/define-macros-order": ["error", { - "order": ["defineEmits", "defineProps"] + "order": ["defineProps", "defineEmits"] }] } ``` - `order` (`string[]`) ... The order of defineEmits and defineProps macros -### `{ "order": ["defineEmits", "defineProps"] }` (default) +### `{ "order": ["defineProps", "defineEmits"] }` (default) ```vue ``` @@ -46,8 +46,8 @@ defineProps(/* ... */) ```vue ``` @@ -59,8 +59,8 @@ defineEmits(/* ... */) ``` diff --git a/lib/rules/define-macros-order.js b/lib/rules/define-macros-order.js index d90bb0a60..91349c3b4 100644 --- a/lib/rules/define-macros-order.js +++ b/lib/rules/define-macros-order.js @@ -191,76 +191,62 @@ function create(context) { } /** - * Move all lines of "node" with its comments to before the "beforeNode" + * Move all lines of "node" with its comments to before the "target" * @param {RuleFixer} fixer * @param {ASTNode} node - * @param {ASTNode} beforeNode + * @param {ASTNode} target */ - function moveNodeBefore(fixer, node, beforeNode) { - const insertIndex = getLineStartIndex(beforeNode) - const moveRange = getMoveRange(node) + function moveNodeBefore(fixer, node, target) { + // get comments under tokens(if any) + const beforeNodeToken = sourceCode.getTokenBefore(node) + const nodeComment = sourceCode.getTokenAfter(beforeNodeToken, { + includeComments: true + }) + const nextNodeComment = sourceCode.getTokenAfter(node, { + includeComments: true + }) + // get positions of what we need to remove + const cutStart = getLineStartIndex(nodeComment, beforeNodeToken) + const cutEnd = getLineStartIndex(nextNodeComment, node) + // get space before target + const beforeTargetToken = sourceCode.getTokenBefore(target) + const targetComment = sourceCode.getTokenAfter(beforeTargetToken, { + includeComments: true + }) + const textSpace = getTextBetweenTokens(beforeTargetToken, targetComment) + // make insert text: comments + node + space before target const textNode = sourceCode.getText( node, - node.range[0] - moveRange[0], - moveRange[1] - node.range[1] + node.range[0] - nodeComment.range[0] ) + const insertText = textNode + textSpace return [ - fixer.insertTextAfterRange([insertIndex, insertIndex], textNode), - fixer.removeRange(moveRange) + fixer.insertTextBefore(targetComment, insertText), + fixer.removeRange([cutStart, cutEnd]) ] } /** - * Get [start, end] range before/after node which we need to move - * @param {ASTNode} node - * @return {[number, number]} + * @param {ASTNode} tokenBefore + * @param {ASTNode} tokenAfter */ - function getMoveRange(node) { - const afterCutToken = sourceCode.getTokenBefore(node) - const startCutToken = sourceCode.getTokenAfter(afterCutToken, { - includeComments: true - }) - // start is the beginning of line of first comment before node - const start = getLineStartIndex(startCutToken) - // end is the position of new line after node - const end = getNextLineStartIndex(node) + function getTextBetweenTokens(tokenBefore, tokenAfter) { + const delta = tokenBefore.range[1] - tokenBefore.range[0] + const count = tokenAfter.range[0] - tokenBefore.range[1] - return [start, end] + return sourceCode.getText(tokenBefore, -delta, count) } /** - * Get position of the beginning of next empty line + * Get position of the beginning of the token's line(or prevToken end if no line) * @param {ASTNode} token + * @param {ASTNode} prevToken */ - function getNextLineStartIndex(token) { - const nextToken = sourceCode.getTokenAfter(token, { - includeComments: true - }) - + function getLineStartIndex(token, prevToken) { // if we have next token on the same line - get index right before that token - if (nextToken.loc.start.line === token.loc.end.line) { - return nextToken.range[0] - } - - return sourceCode.getIndexFromLoc({ - line: token.loc.end.line + 1, - column: 0 - }) - } - - /** - * Get position of the beginning of token's line - * @param {ASTNode | Token} token - */ - function getLineStartIndex(token) { - const prevIndex = sourceCode.getTokenBefore(token, { - includeComments: true - }) - - // if we have prev token on the same line - get index right after that token - if (prevIndex.loc.end.line === token.loc.start.line) { - return prevIndex.range[1] + if (token.loc.start.line === prevToken.loc.end.line) { + return prevToken.range[1] } return sourceCode.getIndexFromLoc({ diff --git a/tests/lib/rules/define-macros-order.js b/tests/lib/rules/define-macros-order.js index 37b3b5e15..ce5f30040 100644 --- a/tests/lib/rules/define-macros-order.js +++ b/tests/lib/rules/define-macros-order.js @@ -155,7 +155,9 @@ tester.run('define-macros-order', rule, { defineProps({ test: Boolean }) + defineEmits(['update:test']) + console.log('test1') console.log('test2') console.log('test3') @@ -190,8 +192,8 @@ tester.run('define-macros-order', rule, { defineProps({ test: Boolean }) - defineEmits(['update:test']) + defineEmits(['update:test']) console.log('test1') `, @@ -259,6 +261,7 @@ tester.run('define-macros-order', rule, { } const emit = defineEmits<{(e: 'update:test'): void}>() + const props = withDefaults(defineProps(), { msg: 'hello', labels: () => ['one', 'two'] @@ -295,8 +298,8 @@ tester.run('define-macros-order', rule, { import bla from 'bla'; interface Foo {}; type Bar = {}; - // <--- auto-fix should move \`defineProps\` here defineProps({ test: Boolean }); + // <--- auto-fix should move \`defineProps\` here const someOtherCode = ''; import foo from 'bar'; // not idiomatic, but allowed interface SomeOtherInterface {}; @@ -341,16 +344,16 @@ tester.run('define-macros-order', rule, { // Description for emit // Description for emit line 2 const emit = defineEmits<{(e: 'test'): void}>(); + /** Description for props */ const props = withDefaults(defineProps(), { msg: 'hello' }); - console.log('test1') + console.log('test1') console.log('test2') - console.log('test3') `, @@ -374,7 +377,7 @@ tester.run('define-macros-order', rule, { `, output: ` `, options: optionsEmitsFirst, From 19be4aea4d363616d3330e56723dce3cbccb631f Mon Sep 17 00:00:00 2001 From: Eduard Deisling Date: Thu, 21 Apr 2022 12:04:53 +0300 Subject: [PATCH 8/8] Fix slice review --- lib/rules/define-macros-order.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/rules/define-macros-order.js b/lib/rules/define-macros-order.js index 91349c3b4..9c8ea45e6 100644 --- a/lib/rules/define-macros-order.js +++ b/lib/rules/define-macros-order.js @@ -232,10 +232,7 @@ function create(context) { * @param {ASTNode} tokenAfter */ function getTextBetweenTokens(tokenBefore, tokenAfter) { - const delta = tokenBefore.range[1] - tokenBefore.range[0] - const count = tokenAfter.range[0] - tokenBefore.range[1] - - return sourceCode.getText(tokenBefore, -delta, count) + return sourceCode.text.slice(tokenBefore.range[1], tokenAfter.range[0]) } /**