From 59653b705b6fda12370c06b66d6449ba3b377c0f Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY <974153916@qq.com> Date: Wed, 9 Jun 2021 18:01:47 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20finish=20sort=20orde?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component-name-in-template-casing.js | 3 +- lib/rules/component-tags-order.js | 83 ++++++++++++++-- tests/lib/rules/component-tags-order.js | 99 +++++++++++++++---- 3 files changed, 159 insertions(+), 26 deletions(-) diff --git a/lib/rules/component-name-in-template-casing.js b/lib/rules/component-name-in-template-casing.js index b2f60a637..dffca0c88 100644 --- a/lib/rules/component-name-in-template-casing.js +++ b/lib/rules/component-name-in-template-casing.js @@ -30,7 +30,8 @@ module.exports = { description: 'enforce specific casing for the component naming style in template', categories: undefined, - url: 'https://eslint.vuejs.org/rules/component-name-in-template-casing.html' + url: + 'https://eslint.vuejs.org/rules/component-name-in-template-casing.html' }, fixable: 'code', schema: [ diff --git a/lib/rules/component-tags-order.js b/lib/rules/component-tags-order.js index dc7da9725..729b5e10d 100644 --- a/lib/rules/component-tags-order.js +++ b/lib/rules/component-tags-order.js @@ -24,7 +24,7 @@ module.exports = { categories: ['vue3-recommended', 'recommended'], url: 'https://eslint.vuejs.org/rules/component-tags-order.html' }, - fixable: null, + fixable: 'code', schema: [ { type: 'object', @@ -87,12 +87,43 @@ module.exports = { return [] } + /** + * + * + * @param {{name: string, index: number}[]} list component tag list of the SFC + */ + function getSortedTagList(list) { + list.sort((a, b) => { + const ao = getOrderPosition(a.name) + const bo = getOrderPosition(b.name) + // 1. if the tag is customize keep the original position + // 2. if two tag has same order, keep the original position + if (ao === -1 || bo === -1 || ao === bo) { + return 0 + } else { + // else sort the tag position by asc + return ao - bo + } + }) + return list + } + /** * @param {VElement} element * @param {VElement} firstUnorderedElement + * @param {string} code + * @param {number[]} replaceRange + * @param {boolean} fixable */ - function report(element, firstUnorderedElement) { - context.report({ + function report( + element, + firstUnorderedElement, + code, + replaceRange, + fixable + ) { + /**@type{Rule.ReportDescriptor} */ + const descriptor = { node: element, loc: element.loc, messageId: 'unexpected', @@ -101,7 +132,16 @@ module.exports = { firstUnorderedName: firstUnorderedElement.name, line: firstUnorderedElement.loc.start.line } - }) + } + if (fixable) { + descriptor.fix = function (fixer) { + return fixer.replaceTextRange( + [replaceRange[0], replaceRange[1]], + code + ) + } + } + context.report(descriptor) } return { @@ -110,7 +150,8 @@ module.exports = { return } const elements = getTopLevelHTMLElements() - + /** @type {{element: VElement, firstUnordered: VElement}[]} */ + const reportCandidates = [] elements.forEach((element, index) => { const expectedIndex = getOrderPosition(element.name) if (expectedIndex < 0) { @@ -123,9 +164,39 @@ module.exports = { (e1, e2) => getOrderPosition(e1.name) - getOrderPosition(e2.name) )[0] if (firstUnordered) { - report(element, firstUnordered) + reportCandidates.push({ element, firstUnordered }) } }) + if (reportCandidates.length) { + const replaceRange = [ + elements[0].range[0], + elements[elements.length - 1].range[1] + ] + const sortTagList = getSortedTagList( + elements.map((element, index) => ({ + name: element.name, + index + })) + ) + const sourceCode = context.getSourceCode().text + const reOrderedCode = Array.from( + { length: elements.length }, + (_, i) => { + const [start, end] = elements[sortTagList[i].index].range + const code = sourceCode.slice(start, end) + return code + } + ).join('\n') + reportCandidates.forEach((error, index) => { + report( + error.element, + error.firstUnordered, + reOrderedCode, + replaceRange, + index === 0 + ) + }) + } } } } diff --git a/tests/lib/rules/component-tags-order.js b/tests/lib/rules/component-tags-order.js index 0c40d4997..b016c1c34 100644 --- a/tests/lib/rules/component-tags-order.js +++ b/tests/lib/rules/component-tags-order.js @@ -73,17 +73,20 @@ tester.run('component-tags-order', rule, { options: [{ order: ['template', 'docs', 'script', 'style'] }] }, { - code: '', + code: + '', output: null, options: [{ order: ['template', 'script', 'style'] }] }, { - code: '
text

', + code: + '
text

', output: null, options: [{ order: ['docs', 'script', 'template', 'style'] }] }, { - code: '', + code: + '', output: null, options: [{ order: [['docs', 'script', 'template'], 'style'] }] }, @@ -108,7 +111,10 @@ tester.run('component-tags-order', rule, { line: 1, column: 37 } - ] + ], + output: ` + +` }, { code: '', @@ -119,7 +125,10 @@ tester.run('component-tags-order', rule, { line: 1, column: 22 } - ] + ], + output: ` + +` }, { code: ` @@ -133,7 +142,11 @@ tester.run('component-tags-order', rule, { message: 'The +` }, { code: ` @@ -147,7 +160,12 @@ tester.run('component-tags-order', rule, { message: 'The + + + ` }, { code: ` @@ -161,7 +179,12 @@ tester.run('component-tags-order', rule, { message: 'The