Skip to content

⭐️New: Add vue/no-restricted-syntax rule #758

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

Merged
merged 3 commits into from
Jan 9, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/rules/README.md
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put link to the AST docs here?

Copy link
Member Author

@ota-meshi ota-meshi Jan 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is defined in line 50.


### `"VElement > VExpressionContainer CallExpression"`

Forbind call expressions on mustache interpolation.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
}
]
},

// Forbind call expressions on mustache interpolation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above ☝️

{
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 on mustache interpolation.'
}
],
errors: [
{
message: 'Call expressions are not allowed on mustache interpolation.',
line: 3,
column: 20,
endLine: 3,
endColumn: 25
},
{
message: 'Call expressions are not allowed on mustache interpolation.',
line: 4,
column: 20,
endLine: 4,
endColumn: 29
},
{
message: 'Call expressions are not allowed on 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
}
]
}
]
})