Skip to content
This repository was archived by the owner on Mar 19, 2024. It is now read-only.

Commit 96ce607

Browse files
committedDec 5, 2018
feat: add rule no-this-in-async-data
1 parent e09a871 commit 96ce607

File tree

4 files changed

+155
-9
lines changed

4 files changed

+155
-9
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/**
2+
* @fileoverview Prevent using this in asyncData
3+
* @author Clark Du
4+
*/
5+
'use strict'
6+
7+
// ------------------------------------------------------------------------------
8+
// Requirements
9+
// ------------------------------------------------------------------------------
10+
11+
var rule = require('../no-this-in-async-data')
12+
13+
var RuleTester = require('eslint').RuleTester
14+
15+
const parserOptions = {
16+
ecmaVersion: 2018,
17+
sourceType: 'module'
18+
}
19+
20+
// ------------------------------------------------------------------------------
21+
// Tests
22+
// ------------------------------------------------------------------------------
23+
24+
var ruleTester = new RuleTester()
25+
ruleTester.run('no-this-in-async-data', rule, {
26+
27+
valid: [
28+
{
29+
filename: 'test.vue',
30+
code: `
31+
export default {
32+
...foo,
33+
asyncData() {
34+
}
35+
}
36+
`,
37+
parserOptions
38+
}
39+
],
40+
41+
invalid: [
42+
{
43+
filename: 'test.vue',
44+
code: `
45+
export default {
46+
...foo,
47+
asyncData() {
48+
if(this.$route.path === 'foo') {}
49+
}
50+
}
51+
`,
52+
errors: [{
53+
message: 'Unexpected this in asyncData.',
54+
type: 'Identifier'
55+
}],
56+
parserOptions
57+
},
58+
{
59+
filename: 'test.vue',
60+
code: `
61+
export default {
62+
...foo,
63+
async asyncData() {
64+
if(this.$route.path === 'foo') {}
65+
}
66+
}
67+
`,
68+
errors: [{
69+
message: 'Unexpected this in asyncData.',
70+
type: 'Identifier'
71+
}],
72+
parserOptions
73+
},
74+
{
75+
filename: 'test.vue',
76+
code: `
77+
export default {
78+
...foo,
79+
asyncData: () => {
80+
if(this.$route.path === 'foo') {}
81+
}
82+
}
83+
`,
84+
errors: [{
85+
message: 'Unexpected this in asyncData.',
86+
type: 'Identifier'
87+
}],
88+
parserOptions
89+
},
90+
{
91+
filename: 'test.vue',
92+
code: `
93+
export default {
94+
...foo,
95+
asyncData: function test() {
96+
if(this.$route.path === 'foo') {}
97+
}
98+
}
99+
`,
100+
errors: [{
101+
message: 'Unexpected this in asyncData.',
102+
type: 'Identifier'
103+
}],
104+
parserOptions
105+
}
106+
]
107+
})

‎lib/rules/no-this-in-async-data.js

+45-6
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@
44
*/
55
'use strict'
66

7+
const utils = require('../utils')
8+
79
// ------------------------------------------------------------------------------
810
// Rule Definition
911
// ------------------------------------------------------------------------------
1012

1113
module.exports = {
1214
meta: {
1315
docs: {
14-
description: 'Prevent using this in asyncData',
15-
category: 'Fill me in',
16-
recommended: false
16+
description: 'disallow `this` in asyncData',
17+
category: 'base'
1718
},
1819
fixable: null, // or "code" or "whitespace"
1920
schema: [
@@ -26,20 +27,58 @@ module.exports = {
2627

2728
create: function (context) {
2829
// variables should be defined here
30+
const forbiddenNodes = []
31+
let isThisUsed
2932

3033
// ----------------------------------------------------------------------
3134
// Helpers
3235
// ----------------------------------------------------------------------
3336

37+
function enterFunction () {
38+
isThisUsed = false
39+
}
40+
41+
function exitFunction (node) {
42+
if (isThisUsed) {
43+
forbiddenNodes.push(node)
44+
}
45+
}
46+
47+
function markThisUsed () {
48+
isThisUsed = true
49+
}
50+
51+
function getFuncNodeWithName (node, name) {
52+
return node.properties.find(item => item.type === 'Property' &&
53+
utils.getStaticPropertyName(item) === name &&
54+
(item.value.type === 'ArrowFunctionExpression' || item.value.type === 'FunctionExpression')
55+
)
56+
}
57+
3458
// ----------------------------------------------------------------------
3559
// Public
3660
// ----------------------------------------------------------------------
3761

3862
return {
39-
'FunctionExpression:exit' (node) {
63+
FunctionExpression: enterFunction,
64+
'FunctionExpression:exit': exitFunction,
65+
ArrowFunctionExpression: enterFunction,
66+
'ArrowFunctionExpression:exit': exitFunction,
67+
ThisExpression: markThisUsed,
68+
Super: markThisUsed,
69+
...utils.executeOnVue(context, obj => {
70+
const node = getFuncNodeWithName(obj, 'asyncData')
71+
if (!node) return
4072

41-
// give me methods
42-
}
73+
forbiddenNodes.forEach(el => {
74+
if (node.value === el) {
75+
context.report({
76+
node: node.key,
77+
messageId: 'noThis'
78+
})
79+
}
80+
})
81+
})
4382
}
4483
}
4584
}

‎lib/rules/no-this-in-fetch.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@
1111
module.exports = {
1212
meta: {
1313
docs: {
14-
description: 'Prevent using this in fetch',
15-
category: 'Fill me in',
16-
recommended: false
14+
description: 'disallow `this` in fetch',
15+
category: 'base'
1716
},
1817
fixable: null, // or "code" or "whitespace"
1918
schema: [

‎lib/utils/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('eslint-plugin-vue/lib/utils')

0 commit comments

Comments
 (0)
This repository has been archived.