-
-
Notifications
You must be signed in to change notification settings - Fork 681
New: add no-use-computed-property-like-method rules #1234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
b14d0f3
6b0b860
4d8ae20
7aaf02d
f5c426c
e97c749
c61acae
587d808
f460c6f
969120a
7ce7a03
cc7cde4
62b82be
c614b6d
13eff80
01c4f84
9c54158
00dc589
78c203d
96fecb1
3edce05
330d188
11b7ef1
8b825e5
2e316f8
d8a8af9
986648b
b06421b
7459eea
d885a36
ccbee98
c2bc020
c082183
3b77c4e
ce93fa6
60e7c48
7cb18fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
nodejs 12.18.0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
--- | ||
pageClass: rule-details | ||
sidebarDepth: 0 | ||
title: vue/no-use-computed-property-like-method | ||
description: disallow use computed property like method | ||
--- | ||
# vue/no-use-computed-property-like-method | ||
> disallow use computed property like method | ||
|
||
## :book: Rule Details | ||
|
||
This rule disallows to use computed property like method. | ||
|
||
<eslint-code-block :rules="{'vue/no-use-computed-property-like-method': ['error']}"> | ||
|
||
```vue | ||
<template> | ||
<div> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
export default { | ||
props: { | ||
name: { | ||
type: String | ||
}, | ||
}, | ||
computed: { | ||
isExpectedName() { | ||
return this.name === 'name'; | ||
} | ||
}, | ||
methods: { | ||
getName() { | ||
return this.isExpectedName | ||
}, | ||
getNameCallLikeMethod() { | ||
return this.isExpectedName() | ||
} | ||
} | ||
} | ||
</script> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
## :wrench: Options | ||
|
||
Nothing. | ||
|
||
## :mag: Implementation | ||
|
||
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-use-computed-property-like-method.js) | ||
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-use-computed-property-like-method.js) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/** | ||
* @author tyankatsu <https://github.com/tyankatsu0105> | ||
* See LICENSE file in root directory for full license. | ||
*/ | ||
'use strict' | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Requirements | ||
// ------------------------------------------------------------------------------ | ||
|
||
const { defineVueVisitor, getComputedProperties } = require('../utils') | ||
|
||
/** | ||
* @typedef {import('../utils').ComponentComputedProperty} ComponentComputedProperty | ||
* @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp | ||
*/ | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Rule Definition | ||
// ------------------------------------------------------------------------------ | ||
|
||
module.exports = { | ||
meta: { | ||
type: 'problem', | ||
docs: { | ||
description: 'disallow use computed property like method', | ||
categories: undefined, | ||
url: | ||
'https://eslint.vuejs.org/rules/no-use-computed-property-like-method.html' | ||
}, | ||
fixable: null, | ||
schema: [], | ||
messages: { | ||
unexpected: 'Does not allow to use computed with this expression.' | ||
} | ||
}, | ||
/** @param {RuleContext} context */ | ||
create(context) { | ||
/** | ||
* @typedef {object} ScopeStack | ||
* @property {ScopeStack | null} upper | ||
* @property {BlockStatement | Expression} body | ||
*/ | ||
/** @type {Map<ObjectExpression, ComponentComputedProperty[]>} */ | ||
const computedPropertiesMap = new Map() | ||
|
||
return defineVueVisitor(context, { | ||
onVueObjectEnter(node) { | ||
computedPropertiesMap.set(node, getComputedProperties(node)) | ||
}, | ||
|
||
/** @param {MemberExpression} node */ | ||
'MemberExpression[object.type="ThisExpression"]'( | ||
node, | ||
{ node: vueNode } | ||
) { | ||
if (node.property.type !== 'Identifier') return | ||
if (node.parent.type !== 'CallExpression') return | ||
|
||
const computedProperties = computedPropertiesMap | ||
.get(vueNode) | ||
.map((item) => item.key) | ||
|
||
if (!computedProperties.includes(node.property.name)) return | ||
|
||
context.report({ | ||
node: node.property, | ||
loc: node.property.loc, | ||
messageId: 'unexpected' | ||
}) | ||
} | ||
}) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/** | ||
* @author tyankatsu <https://github.com/tyankatsu0105> | ||
* See LICENSE file in root directory for full license. | ||
*/ | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Requirements | ||
// ------------------------------------------------------------------------------ | ||
|
||
const RuleTester = require('eslint').RuleTester | ||
const rule = require('../../../lib/rules/no-use-computed-property-like-method') | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Tests | ||
// ------------------------------------------------------------------------------ | ||
|
||
const tester = new RuleTester({ | ||
parser: require.resolve('vue-eslint-parser'), | ||
parserOptions: { ecmaVersion: 2015, sourceType: 'module' } | ||
}) | ||
|
||
tester.run('no-use-computed-property-like-method', rule, { | ||
valid: [ | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<script> | ||
export default { | ||
computed: { | ||
name() { | ||
return 'name'; | ||
} | ||
}, | ||
methods: { | ||
getName() { | ||
return this.name | ||
} | ||
}, | ||
} | ||
</script> | ||
` | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<script> | ||
export default { | ||
props: { | ||
name: { | ||
type: String | ||
}, | ||
}, | ||
computed: { | ||
isExpectedName() { | ||
return this.name === 'name'; | ||
} | ||
}, | ||
methods: { | ||
getName() { | ||
return this.isExpectedName | ||
} | ||
}, | ||
} | ||
</script> | ||
` | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<script> | ||
export default { | ||
computed: { | ||
name() { | ||
return 'name'; | ||
}, | ||
isExpectedName() { | ||
return this.name === 'name'; | ||
} | ||
}, | ||
methods: { | ||
getName() { | ||
return this.isExpectedName | ||
} | ||
}, | ||
} | ||
</script> | ||
` | ||
} | ||
], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have found an error in some cases. Could you add the following test cases? <script>
export default {
computed: {
bar() {
return
}
}
}
</script> <script>
export default {
methods: {
fn() {
this.foo()
}
}
}
</script> There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ota-meshi However, I will not support this case: <script>
export default {
methods: {
fn() {
this.foo()
}
}
}
</script> Because this rule only checkes whether computed properties are expected as property or not. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't want support. I've found that using a rule in that source code reports a crash or an incorrect error, so I just want to add test cases to tests if it's okay. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. |
||
invalid: [ | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<script> | ||
export default { | ||
computed: { | ||
name() { | ||
return 'name'; | ||
} | ||
}, | ||
methods: { | ||
getName() { | ||
return this.name() | ||
} | ||
} | ||
} | ||
</script> | ||
`, | ||
errors: ['Does not allow to use computed with this expression.'] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<script> | ||
export default { | ||
props: { | ||
name: { | ||
type: String | ||
}, | ||
}, | ||
computed: { | ||
isExpectedName() { | ||
return this.name === 'name'; | ||
} | ||
}, | ||
methods: { | ||
getName() { | ||
return this.isExpectedName() | ||
} | ||
} | ||
} | ||
</script> | ||
`, | ||
errors: ['Does not allow to use computed with this expression.'] | ||
} | ||
] | ||
}) |
Uh oh!
There was an error while loading. Please reload this page.