eslint-plugin-mpx 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/configs/base.js
CHANGED
|
@@ -17,7 +17,14 @@ module.exports = {
|
|
|
17
17
|
globals: {
|
|
18
18
|
wx: 'readonly',
|
|
19
19
|
my: 'readonly',
|
|
20
|
+
swan: 'readonly',
|
|
21
|
+
qq: 'readonly',
|
|
22
|
+
tt: 'readonly',
|
|
23
|
+
jd: 'readonly',
|
|
24
|
+
qa: 'readonly',
|
|
25
|
+
dd: 'readonly',
|
|
20
26
|
getCurrentPages: 'readonly',
|
|
27
|
+
getRegExp: 'readonly',
|
|
21
28
|
getApp: 'readonly',
|
|
22
29
|
App: 'readonly',
|
|
23
30
|
Page: 'readonly',
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* IMPORTANT!
|
|
3
|
+
* This file has been automatically generated,
|
|
4
|
+
* in order to update it's content execute "npm run update"
|
|
5
|
+
*/
|
|
6
|
+
module.exports = {
|
|
7
|
+
extends: require.resolve('./base'),
|
|
8
|
+
rules: {
|
|
9
|
+
'mpx/html-end-tags': 'error',
|
|
10
|
+
'mpx/no-dupe-wx-elif': 'error',
|
|
11
|
+
'mpx/no-duplicate-attributes': 'error',
|
|
12
|
+
'mpx/valid-wx-if': 'error',
|
|
13
|
+
'mpx/valid-wx-else': 'error',
|
|
14
|
+
'mpx/valid-wx-elif': 'error',
|
|
15
|
+
'mpx/valid-wx-model': 'error',
|
|
16
|
+
'mpx/script-setup-uses-vars': 'error'
|
|
17
|
+
}
|
|
18
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -23,11 +23,13 @@ module.exports = {
|
|
|
23
23
|
'valid-wx-else': require('./rules/valid-wx-else'),
|
|
24
24
|
'valid-wx-if': require('./rules/valid-wx-if'),
|
|
25
25
|
'valid-wx-model': require('./rules/valid-wx-model'),
|
|
26
|
+
'script-setup-uses-vars': require('./rules/script-setup-uses-vars'),
|
|
26
27
|
eqeqeq: require('./rules/eqeqeq')
|
|
27
28
|
},
|
|
28
29
|
configs: {
|
|
29
30
|
base: require('./configs/base'),
|
|
30
|
-
'mpx-essential': require('./configs/mpx-essential')
|
|
31
|
+
'mpx-essential': require('./configs/mpx-essential'),
|
|
32
|
+
'composition-api-essential': require('./configs/composition-api-essential')
|
|
31
33
|
},
|
|
32
34
|
processors: {
|
|
33
35
|
'.mpx': require('./processor')
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author pagnkelly
|
|
3
|
+
* See LICENSE file in root directory for full license.
|
|
4
|
+
*/
|
|
5
|
+
'use strict'
|
|
6
|
+
|
|
7
|
+
// ------------------------------------------------------------------------------
|
|
8
|
+
// Requirements
|
|
9
|
+
// ------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
const utils = require('../utils')
|
|
12
|
+
// const casing = require('../utils/casing')
|
|
13
|
+
|
|
14
|
+
// ------------------------------------------------------------------------------
|
|
15
|
+
// Rule Definition
|
|
16
|
+
// ------------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
meta: {
|
|
20
|
+
type: 'problem',
|
|
21
|
+
docs: {
|
|
22
|
+
description:
|
|
23
|
+
'prevent `<script setup>` variables used in `<template>` to be marked as unused', // eslint-disable-line eslint-plugin/require-meta-docs-description
|
|
24
|
+
categories: undefined,
|
|
25
|
+
url: 'https://eslint.vuejs.org/rules/script-setup-uses-vars.html'
|
|
26
|
+
},
|
|
27
|
+
deprecated: true,
|
|
28
|
+
schema: []
|
|
29
|
+
},
|
|
30
|
+
/**
|
|
31
|
+
* @param {RuleContext} context - The rule context.
|
|
32
|
+
* @returns {RuleListener} AST event handlers.
|
|
33
|
+
*/
|
|
34
|
+
create(context) {
|
|
35
|
+
if (!utils.isScriptSetup(context)) {
|
|
36
|
+
return {}
|
|
37
|
+
}
|
|
38
|
+
/** @type {Set<string>} */
|
|
39
|
+
const scriptVariableNames = new Set()
|
|
40
|
+
const globalScope = context.getSourceCode().scopeManager.globalScope
|
|
41
|
+
if (globalScope) {
|
|
42
|
+
for (const variable of globalScope.variables) {
|
|
43
|
+
scriptVariableNames.add(variable.name)
|
|
44
|
+
}
|
|
45
|
+
const moduleScope = globalScope.childScopes.find(
|
|
46
|
+
(scope) => scope.type === 'module'
|
|
47
|
+
)
|
|
48
|
+
for (const variable of (moduleScope && moduleScope.variables) || []) {
|
|
49
|
+
scriptVariableNames.add(variable.name)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @see https://github.com/vuejs/vue-next/blob/2749c15170ad4913e6530a257db485d4e7ed2283/packages/compiler-core/src/transforms/transformElement.ts#L333
|
|
55
|
+
* @param {string} name
|
|
56
|
+
*/
|
|
57
|
+
function markSetupReferenceVariableAsUsed(name) {
|
|
58
|
+
if (scriptVariableNames.has(name)) {
|
|
59
|
+
context.markVariableAsUsed(name)
|
|
60
|
+
return true
|
|
61
|
+
}
|
|
62
|
+
return false
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return utils.defineTemplateBodyVisitor(
|
|
66
|
+
context,
|
|
67
|
+
{
|
|
68
|
+
VExpressionContainer(node) {
|
|
69
|
+
for (const ref of node.references.filter(
|
|
70
|
+
(ref) => ref.variable == null
|
|
71
|
+
)) {
|
|
72
|
+
context.markVariableAsUsed(ref.id.name)
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
VElement(node) {
|
|
76
|
+
if (utils.isMpElementName(node.rawName)) {
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
markSetupReferenceVariableAsUsed(node.rawName)
|
|
80
|
+
},
|
|
81
|
+
/** @param {VAttribute} node */
|
|
82
|
+
'VAttribute[directive=false]'(node) {
|
|
83
|
+
if (node.value) {
|
|
84
|
+
let val = node.value.value
|
|
85
|
+
val = val.replace(/(\{\{)|\s|(\}\})/g, '')
|
|
86
|
+
context.markVariableAsUsed(val)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{},
|
|
91
|
+
{
|
|
92
|
+
templateBodyTriggerSelector: 'Program'
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
}
|
package/lib/utils/index.js
CHANGED
|
@@ -567,9 +567,7 @@ module.exports = {
|
|
|
567
567
|
* @param {string} [value] The attribute value to check.
|
|
568
568
|
* @returns {boolean} `true` if the start tag has the attribute.
|
|
569
569
|
*/
|
|
570
|
-
hasAttribute
|
|
571
|
-
return Boolean(this.getAttribute(node, name, value))
|
|
572
|
-
},
|
|
570
|
+
hasAttribute,
|
|
573
571
|
|
|
574
572
|
/**
|
|
575
573
|
* Check whether the given start tag has specific directive.
|
|
@@ -669,24 +667,7 @@ module.exports = {
|
|
|
669
667
|
* @param {string} [value] The attribute value to check.
|
|
670
668
|
* @returns {VAttribute | null} The found attribute.
|
|
671
669
|
*/
|
|
672
|
-
getAttribute
|
|
673
|
-
return (
|
|
674
|
-
node.startTag.attributes.find(
|
|
675
|
-
/**
|
|
676
|
-
* @param {VAttribute | VDirective} node
|
|
677
|
-
* @returns {node is VAttribute}
|
|
678
|
-
*/
|
|
679
|
-
(node) => {
|
|
680
|
-
return (
|
|
681
|
-
!node.directive &&
|
|
682
|
-
node.key.name === name &&
|
|
683
|
-
(value === undefined ||
|
|
684
|
-
(node.value != null && node.value.value === value))
|
|
685
|
-
)
|
|
686
|
-
}
|
|
687
|
-
) || null
|
|
688
|
-
)
|
|
689
|
-
},
|
|
670
|
+
getAttribute,
|
|
690
671
|
|
|
691
672
|
/**
|
|
692
673
|
* Get the directive list which has the given name.
|
|
@@ -873,7 +854,11 @@ module.exports = {
|
|
|
873
854
|
},
|
|
874
855
|
|
|
875
856
|
isMpxFile,
|
|
876
|
-
|
|
857
|
+
/**
|
|
858
|
+
* Checks whether the current file is uses `<script setup>`
|
|
859
|
+
* @param {RuleContext} context The ESLint rule context object.
|
|
860
|
+
*/
|
|
861
|
+
isScriptSetup,
|
|
877
862
|
/**
|
|
878
863
|
* 检测当前文件是否是mpx文件且是创建mpx方法
|
|
879
864
|
* @param {RuleContext} context The ESLint rule context object.
|
|
@@ -1562,12 +1547,14 @@ function createRequire(filename) {
|
|
|
1562
1547
|
* @param {RuleContext} context The rule context to use parser services.
|
|
1563
1548
|
* @param {TemplateListener} templateBodyVisitor The visitor to traverse the template body.
|
|
1564
1549
|
* @param {RuleListener} [scriptVisitor] The visitor to traverse the script.
|
|
1550
|
+
* @param { { templateBodyTriggerSelector: "Program" | "Program:exit" } } [options] The options.
|
|
1565
1551
|
* @returns {RuleListener} The merged visitor.
|
|
1566
1552
|
*/
|
|
1567
1553
|
function defineTemplateBodyVisitor(
|
|
1568
1554
|
context,
|
|
1569
1555
|
templateBodyVisitor,
|
|
1570
|
-
scriptVisitor
|
|
1556
|
+
scriptVisitor,
|
|
1557
|
+
options
|
|
1571
1558
|
) {
|
|
1572
1559
|
if (context.parserServices.defineTemplateBodyVisitor == null) {
|
|
1573
1560
|
const filename = context.getFilename()
|
|
@@ -1582,7 +1569,8 @@ function defineTemplateBodyVisitor(
|
|
|
1582
1569
|
}
|
|
1583
1570
|
return context.parserServices.defineTemplateBodyVisitor(
|
|
1584
1571
|
templateBodyVisitor,
|
|
1585
|
-
scriptVisitor
|
|
1572
|
+
scriptVisitor,
|
|
1573
|
+
options
|
|
1586
1574
|
)
|
|
1587
1575
|
}
|
|
1588
1576
|
|
|
@@ -1857,7 +1845,73 @@ function getVExpressionContainer(node) {
|
|
|
1857
1845
|
function isMpxFile(path) {
|
|
1858
1846
|
return path.endsWith('.mpx')
|
|
1859
1847
|
}
|
|
1860
|
-
|
|
1848
|
+
/**
|
|
1849
|
+
* Checks whether the current file is uses `<script setup>`
|
|
1850
|
+
* @param {RuleContext} context The ESLint rule context object.
|
|
1851
|
+
*/
|
|
1852
|
+
function isScriptSetup(context) {
|
|
1853
|
+
return Boolean(getScriptSetupElement(context))
|
|
1854
|
+
}
|
|
1855
|
+
/**
|
|
1856
|
+
* Gets the element of `<script setup>`
|
|
1857
|
+
* @param {RuleContext} context The ESLint rule context object.
|
|
1858
|
+
* @returns {VElement | null} the element of `<script setup>`
|
|
1859
|
+
*/
|
|
1860
|
+
function getScriptSetupElement(context) {
|
|
1861
|
+
const df =
|
|
1862
|
+
context.parserServices.getDocumentFragment &&
|
|
1863
|
+
context.parserServices.getDocumentFragment()
|
|
1864
|
+
if (!df) {
|
|
1865
|
+
return null
|
|
1866
|
+
}
|
|
1867
|
+
const scripts = df.children
|
|
1868
|
+
.filter(isVElement)
|
|
1869
|
+
.filter((e) => e.name === 'script')
|
|
1870
|
+
if (scripts.length === 2) {
|
|
1871
|
+
return scripts.find((e) => hasAttribute(e, 'setup')) || null
|
|
1872
|
+
} else {
|
|
1873
|
+
const script = scripts[0]
|
|
1874
|
+
if (script && hasAttribute(script, 'setup')) {
|
|
1875
|
+
return script
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
return null
|
|
1879
|
+
}
|
|
1880
|
+
/**
|
|
1881
|
+
* Check whether the given start tag has specific directive.
|
|
1882
|
+
* @param {VElement} node The start tag node to check.
|
|
1883
|
+
* @param {string} name The attribute name to check.
|
|
1884
|
+
* @param {string} [value] The attribute value to check.
|
|
1885
|
+
* @returns {boolean} `true` if the start tag has the attribute.
|
|
1886
|
+
*/
|
|
1887
|
+
function hasAttribute(node, name, value) {
|
|
1888
|
+
return Boolean(getAttribute(node, name, value))
|
|
1889
|
+
}
|
|
1890
|
+
/**
|
|
1891
|
+
* Get the attribute which has the given name.
|
|
1892
|
+
* @param {VElement} node The start tag node to check.
|
|
1893
|
+
* @param {string} name The attribute name to check.
|
|
1894
|
+
* @param {string} [value] The attribute value to check.
|
|
1895
|
+
* @returns {VAttribute | null} The found attribute.
|
|
1896
|
+
*/
|
|
1897
|
+
function getAttribute(node, name, value) {
|
|
1898
|
+
return (
|
|
1899
|
+
node.startTag.attributes.find(
|
|
1900
|
+
/**
|
|
1901
|
+
* @param {VAttribute | VDirective} node
|
|
1902
|
+
* @returns {node is VAttribute}
|
|
1903
|
+
*/
|
|
1904
|
+
(node) => {
|
|
1905
|
+
return (
|
|
1906
|
+
!node.directive &&
|
|
1907
|
+
node.key.name === name &&
|
|
1908
|
+
(value === undefined ||
|
|
1909
|
+
(node.value != null && node.value.value === value))
|
|
1910
|
+
)
|
|
1911
|
+
}
|
|
1912
|
+
) || null
|
|
1913
|
+
)
|
|
1914
|
+
}
|
|
1861
1915
|
/** @param {CallExpression} node */
|
|
1862
1916
|
function isObjectArgument(node) {
|
|
1863
1917
|
return (
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-mpx",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Official ESLint plugin for Mpx.js",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"eslint-utils": "^2.1.0",
|
|
51
|
-
"mpx-eslint-parser": "0.0.
|
|
51
|
+
"mpx-eslint-parser": "0.0.9",
|
|
52
52
|
"natural-compare": "^1.4.0",
|
|
53
53
|
"semver": "^7.3.2",
|
|
54
54
|
"vue-eslint-parser": "^7.1.0"
|