Skip to content

Commit

Permalink
⭐️New: Add vue/no-restricted-syntax rule (#758)
Browse files Browse the repository at this point in the history
* ⭐️New: Add `vue/no-restricted-syntax` rule

Close #689

* ⭐️New: Add `vue/no-restricted-syntax` rule

Close #689

* fixed
  • Loading branch information
ota-meshi authored and michalsnik committed Jan 9, 2019
1 parent 3b3fc6c commit 9c49dcc
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/rules/README.md
Expand Up @@ -144,6 +144,7 @@ For example:
| [vue/eqeqeq](./eqeqeq.md) | require the use of `===` and `!==` | :wrench: |
| [vue/key-spacing](./key-spacing.md) | enforce consistent spacing between keys and values in object literal properties | :wrench: |
| [vue/match-component-file-name](./match-component-file-name.md) | require component name property to match its file name | |
| [vue/no-restricted-syntax](./no-restricted-syntax.md) | disallow specified syntax | |
| [vue/object-curly-spacing](./object-curly-spacing.md) | enforce consistent spacing inside braces | :wrench: |
| [vue/require-direct-export](./require-direct-export.md) | require the component to be directly exported | |
| [vue/script-indent](./script-indent.md) | enforce consistent indentation in `<script>` | :wrench: |
Expand Down
55 changes: 55 additions & 0 deletions docs/rules/no-restricted-syntax.md
@@ -0,0 +1,55 @@
---
pageClass: rule-details
sidebarDepth: 0
title: vue/no-restricted-syntax
description: disallow specified syntax
---
# vue/no-restricted-syntax
> disallow specified syntax
This rule is the same rule as core [no-restricted-syntax] rule but it applies to the expressions in `<template>`.


## :wrench: Options

Please see [no-restricted-syntax] for detailed options.

You can include the AST created by [vue-eslint-parser] in the selector.
To know more about certain nodes in produced AST, please go [vue-eslint-parser - AST docs].

### `"VElement > VExpressionContainer CallExpression"`

Forbids call expressions inside mustache interpolation.

<eslint-code-block :rules="{'vue/no-restricted-syntax': ['error', 'VElement > VExpressionContainer CallExpression']}">

```vue
<template>
<!-- ✔ GOOD -->
<div> {{ foo }} </div>
<div> {{ foo.bar }} </div>
<!-- ✘ BAD -->
<div> {{ foo() }} </div>
<div> {{ foo.bar() }} </div>
<div> {{ foo().bar }} </div>
</template>
```

</eslint-code-block>

## :books: Further reading

- [no-restricted-syntax]
- [ESTree]
- [vue-eslint-parser]

[no-restricted-syntax]: https://eslint.org/docs/rules/no-restricted-syntax
[ESTree]: https://github.com/estree/estree
[vue-eslint-parser]: https://github.com/mysticatea/vue-eslint-parser
[vue-eslint-parser - AST docs]: https://github.com/mysticatea/vue-eslint-parser/blob/master/docs/ast.md

## :mag: Implementation

- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-restricted-syntax.js)
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-restricted-syntax.js)
1 change: 1 addition & 0 deletions lib/index.js
Expand Up @@ -33,6 +33,7 @@ module.exports = {
'no-multi-spaces': require('./rules/no-multi-spaces'),
'no-parsing-error': require('./rules/no-parsing-error'),
'no-reserved-keys': require('./rules/no-reserved-keys'),
'no-restricted-syntax': require('./rules/no-restricted-syntax'),
'no-shared-component-data': require('./rules/no-shared-component-data'),
'no-side-effects-in-computed-properties': require('./rules/no-side-effects-in-computed-properties'),
'no-spaces-around-equal-signs-in-attribute': require('./rules/no-spaces-around-equal-signs-in-attribute'),
Expand Down
9 changes: 9 additions & 0 deletions lib/rules/no-restricted-syntax.js
@@ -0,0 +1,9 @@
/**
* @author Yosuke Ota
*/
'use strict'

const { wrapCoreRule } = require('../utils')

// eslint-disable-next-line
module.exports = wrapCoreRule(require('eslint/lib/rules/no-restricted-syntax'))
118 changes: 118 additions & 0 deletions tests/lib/rules/no-restricted-syntax.js
@@ -0,0 +1,118 @@
/**
* @author Yosuke Ota
*/
'use strict'

const RuleTester = require('eslint').RuleTester
const rule = require('../../../lib/rules/no-restricted-syntax')

const tester = new RuleTester({
parser: 'vue-eslint-parser',
parserOptions: { ecmaVersion: 2015 }
})

tester.run('no-restricted-syntax', rule, {
valid: [
{
code: `
<template>
<input :value="value">
</template>`,
options: [
{
'selector': 'CallExpression',
'message': 'Call expressions are not allowed.'
}
]
}
],
invalid: [
{
code: `
<template>
<input :value="value()">
</template>`,
options: [
{
'selector': 'CallExpression',
'message': 'Call expressions are not allowed.'
}
],
errors: [
{
message: 'Call expressions are not allowed.',
line: 3,
column: 26,
endLine: 3,
endColumn: 33
}
]
},

// Forbids call expressions inside mustache interpolation.
{
code: `
<template>
<div> {{ foo() }} </div>
<div> {{ foo.bar() }} </div>
<div> {{ foo().bar }} </div>
</template>`,
options: [
{
'selector': 'VElement > VExpressionContainer CallExpression',
'message': 'Call expressions are not allowed inside mustache interpolation.'
}
],
errors: [
{
message: 'Call expressions are not allowed inside mustache interpolation.',
line: 3,
column: 20,
endLine: 3,
endColumn: 25
},
{
message: 'Call expressions are not allowed inside mustache interpolation.',
line: 4,
column: 20,
endLine: 4,
endColumn: 29
},
{
message: 'Call expressions are not allowed inside mustache interpolation.',
line: 5,
column: 20,
endLine: 5,
endColumn: 25
}
]
},

// Sample source code on issue 689
{
code: `
<template>
<div :foo="$gettext(\`bar\`)">{{$gettext(\`bar\`)}}</div>
</template>`,
options: [
"CallExpression[callee.type='Identifier'][callee.name='$gettext'] TemplateLiteral"
],
errors: [
{
message: 'Using \'CallExpression[callee.type=\'Identifier\'][callee.name=\'$gettext\'] TemplateLiteral\' is not allowed.',
line: 3,
column: 29,
endLine: 3,
endColumn: 34
},
{
message: 'Using \'CallExpression[callee.type=\'Identifier\'][callee.name=\'$gettext\'] TemplateLiteral\' is not allowed.',
line: 3,
column: 48,
endLine: 3,
endColumn: 53
}
]
}
]
})

0 comments on commit 9c49dcc

Please sign in to comment.