diff --git a/.vscode/settings.json b/.vscode/settings.json
index e8e944bef..2c99a4943 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -9,5 +9,9 @@
"vue"
],
"typescript.tsdk": "node_modules/typescript/lib",
- "vetur.validation.script": false
+ "vetur.validation.script": false,
+ "[typescript]": {
+ "editor.formatOnSave": true,
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
}
diff --git a/lib/rules/require-slots-as-functions.js b/lib/rules/require-slots-as-functions.js
index 658071d22..0e83eeda7 100644
--- a/lib/rules/require-slots-as-functions.js
+++ b/lib/rules/require-slots-as-functions.js
@@ -113,6 +113,10 @@ module.exports = {
if (!utils.isThis(object.object, context)) {
return
}
+ if (node.property.type === 'PrivateIdentifier') {
+ // Unreachable
+ return
+ }
verify(node, node.property)
}
})
diff --git a/lib/utils/indent-common.js b/lib/utils/indent-common.js
index 5f1e23632..dafe58ad8 100644
--- a/lib/utils/indent-common.js
+++ b/lib/utils/indent-common.js
@@ -60,8 +60,10 @@ const KNOWN_NODES = new Set([
'NewExpression',
'ObjectExpression',
'ObjectPattern',
+ 'PrivateIdentifier',
'Program',
'Property',
+ 'PropertyDefinition',
'RestElement',
'ReturnStatement',
'SequenceExpression',
@@ -667,7 +669,7 @@ module.exports.defineVisitor = function create(
/**
* Collect prefix tokens of the given property.
* The prefix includes `async`, `get`, `set`, `static`, and `*`.
- * @param {Property|MethodDefinition} node The property node to collect prefix tokens.
+ * @param {Property|MethodDefinition|PropertyDefinition} node The property node to collect prefix tokens.
*/
function getPrefixTokens(node) {
const prefixes = []
@@ -1750,9 +1752,8 @@ module.exports.defineVisitor = function create(
setOffset([dotToken, propertyToken], 1, objectToken)
}
},
- /** @param {MethodDefinition | Property} node */
- 'MethodDefinition, Property'(node) {
- const isMethod = node.type === 'MethodDefinition' || node.method === true
+ /** @param {MethodDefinition | Property | PropertyDefinition} node */
+ 'MethodDefinition, Property, PropertyDefinition'(node) {
const prefixTokens = getPrefixTokens(node)
const hasPrefix = prefixTokens.length >= 1
@@ -1784,7 +1785,10 @@ module.exports.defineVisitor = function create(
}
}
- if (isMethod) {
+ if (
+ node.type === 'MethodDefinition' ||
+ (node.type === 'Property' && node.method === true)
+ ) {
const leftParenToken = tokenStore.getTokenAfter(lastKeyToken)
setOffset(leftParenToken, 1, lastKeyToken)
@@ -1793,6 +1797,11 @@ module.exports.defineVisitor = function create(
const valueToken = tokenStore.getTokenAfter(colonToken)
setOffset([colonToken, valueToken], 1, lastKeyToken)
+ } else if (node.type === 'PropertyDefinition' && node.value != null) {
+ const eqToken = tokenStore.getTokenAfter(lastKeyToken)
+ const initToken = tokenStore.getTokenAfter(eqToken)
+
+ setOffset([eqToken, initToken], 1, lastKeyToken)
}
},
/** @param {NewExpression} node */
diff --git a/lib/utils/index.js b/lib/utils/index.js
index 112297af1..05e45d99c 100644
--- a/lib/utils/index.js
+++ b/lib/utils/index.js
@@ -1848,23 +1848,24 @@ function skipChainExpression(node) {
*/
function getStaticPropertyName(node) {
if (node.type === 'Property' || node.type === 'MethodDefinition') {
- const key = node.key
-
if (!node.computed) {
+ const key = node.key
if (key.type === 'Identifier') {
return key.name
}
}
+ const key = node.key
// @ts-expect-error
return getStringLiteralValue(key)
} else if (node.type === 'MemberExpression') {
- const property = node.property
if (!node.computed) {
+ const property = node.property
if (property.type === 'Identifier') {
return property.name
}
return null
}
+ const property = node.property
// @ts-expect-error
return getStringLiteralValue(property)
}
diff --git a/package.json b/package.json
index 584a6eb81..d5b43b412 100644
--- a/package.json
+++ b/package.json
@@ -74,6 +74,7 @@
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "file:.",
"eslint4b": "^7.0.0",
+ "espree": "^8.0.0-0",
"lodash": "^4.17.15",
"mocha": "^7.1.2",
"nyc": "^15.0.1",
diff --git a/tests/fixtures/script-indent/class-fields-private-methods-01.vue b/tests/fixtures/script-indent/class-fields-private-methods-01.vue
new file mode 100644
index 000000000..46c6ae67c
--- /dev/null
+++ b/tests/fixtures/script-indent/class-fields-private-methods-01.vue
@@ -0,0 +1,64 @@
+
+
diff --git a/tests/fixtures/script-indent/class-fields-private-properties-01.vue b/tests/fixtures/script-indent/class-fields-private-properties-01.vue
new file mode 100644
index 000000000..c935f1904
--- /dev/null
+++ b/tests/fixtures/script-indent/class-fields-private-properties-01.vue
@@ -0,0 +1,22 @@
+
+
diff --git a/tests/fixtures/script-indent/class-fields-properties-01.vue b/tests/fixtures/script-indent/class-fields-properties-01.vue
new file mode 100644
index 000000000..ef193d1fe
--- /dev/null
+++ b/tests/fixtures/script-indent/class-fields-properties-01.vue
@@ -0,0 +1,16 @@
+
+
diff --git a/tests/fixtures/script-indent/class-fields-properties-02.vue b/tests/fixtures/script-indent/class-fields-properties-02.vue
new file mode 100644
index 000000000..3efe3bd25
--- /dev/null
+++ b/tests/fixtures/script-indent/class-fields-properties-02.vue
@@ -0,0 +1,12 @@
+
+
diff --git a/tests/lib/rules/script-indent.js b/tests/lib/rules/script-indent.js
index 865e73141..37fa67293 100644
--- a/tests/lib/rules/script-indent.js
+++ b/tests/lib/rules/script-indent.js
@@ -114,8 +114,9 @@ function unIndent(strings) {
const tester = new RuleTester({
parser: require.resolve('vue-eslint-parser'),
parserOptions: {
- ecmaVersion: 2020,
- sourceType: 'module'
+ ecmaVersion: 2022,
+ sourceType: 'module',
+ parser: require.resolve('espree') // espree v8.0.0-beta.x
}
})
diff --git a/typings/eslint-plugin-vue/global.d.ts b/typings/eslint-plugin-vue/global.d.ts
index aa23a1a21..5b185bb24 100644
--- a/typings/eslint-plugin-vue/global.d.ts
+++ b/typings/eslint-plugin-vue/global.d.ts
@@ -71,6 +71,7 @@ declare global {
// ---- ES Nodes ----
type Identifier = VAST.Identifier
+ type PrivateIdentifier = VAST.PrivateIdentifier
type Literal = VAST.Literal
type Program = VAST.Program
type SwitchCase = VAST.SwitchCase
@@ -135,6 +136,7 @@ declare global {
type AssignmentPattern = VAST.AssignmentPattern
type ClassBody = VAST.ClassBody
type MethodDefinition = VAST.MethodDefinition
+ type PropertyDefinition = VAST.PropertyDefinition
type ModuleDeclaration = VAST.ModuleDeclaration
type ImportDeclaration = VAST.ImportDeclaration
type ExportNamedDeclaration = VAST.ExportNamedDeclaration
diff --git a/typings/eslint-plugin-vue/util-types/ast/ast.ts b/typings/eslint-plugin-vue/util-types/ast/ast.ts
index d8f21315c..e29c199fe 100644
--- a/typings/eslint-plugin-vue/util-types/ast/ast.ts
+++ b/typings/eslint-plugin-vue/util-types/ast/ast.ts
@@ -179,6 +179,8 @@ export type NodeListenerMap = {
export type ESNodeListenerMap = {
Identifier: ES.Identifier
'Identifier:exit': ES.Identifier
+ PrivateIdentifier: ES.PrivateIdentifier
+ 'PrivateIdentifier:exit': ES.PrivateIdentifier
Literal: ES.Literal
'Literal:exit': ES.Literal
Program: ES.Program
@@ -317,6 +319,8 @@ export type ESNodeListenerMap = {
'ClassBody:exit': ES.ClassBody
MethodDefinition: ES.MethodDefinition
'MethodDefinition:exit': ES.MethodDefinition
+ PropertyDefinition: ES.PropertyDefinition
+ 'PropertyDefinition:exit': ES.PropertyDefinition
ImportDeclaration: ES.ImportDeclaration
'ImportDeclaration:exit': ES.ImportDeclaration
ExportNamedDeclaration: ES.ExportNamedDeclaration
diff --git a/typings/eslint-plugin-vue/util-types/ast/es-ast.ts b/typings/eslint-plugin-vue/util-types/ast/es-ast.ts
index 9af1e7d06..1a2519a1a 100644
--- a/typings/eslint-plugin-vue/util-types/ast/es-ast.ts
+++ b/typings/eslint-plugin-vue/util-types/ast/es-ast.ts
@@ -9,6 +9,7 @@ import * as TS from './ts-ast'
import * as JSX from './jsx-ast'
export type ESNode =
+ | PrivateIdentifier
| Identifier
| Literal
| Program
@@ -25,6 +26,7 @@ export type ESNode =
| Pattern
| ClassBody
| MethodDefinition
+ | PropertyDefinition
| ModuleDeclaration
| ModuleSpecifier
@@ -185,16 +187,61 @@ export interface ClassDeclaration extends HasParentNode {
}
export interface ClassBody extends HasParentNode {
type: 'ClassBody'
- body: MethodDefinition[]
+ body: (MethodDefinition | PropertyDefinition)[]
}
-export interface MethodDefinition extends HasParentNode {
+interface BaseMethodDefinition extends HasParentNode {
type: 'MethodDefinition'
+ // computed: boolean
+ static: boolean
+ // key: Expression
+ value: FunctionExpression
+ parent: ClassBody
+}
+export interface MethodDefinitionNonComputedName extends BaseMethodDefinition {
+ kind: 'constructor' | 'method' | 'get' | 'set'
+ computed: false
+ key: Identifier | Literal
+}
+export interface MethodDefinitionComputedName extends BaseMethodDefinition {
kind: 'constructor' | 'method' | 'get' | 'set'
- computed: boolean
+ computed: true
+ key: Expression
+}
+export interface MethodDefinitionPrivate extends BaseMethodDefinition {
+ kind: 'constructor'
+ computed: false
+ key: PrivateIdentifier
+}
+export type MethodDefinition =
+ | MethodDefinitionNonComputedName
+ | MethodDefinitionComputedName
+ | MethodDefinitionPrivate
+interface BasePropertyDefinition extends HasParentNode {
+ type: 'PropertyDefinition'
+ // key: Expression | PrivateIdentifier
+ value: Expression | null
+ // computed: boolean
static: boolean
+ parent: ClassBody
+}
+export interface PropertyDefinitionNonComputedName
+ extends BasePropertyDefinition {
+ computed: false
+ key: Identifier | Literal
+}
+export interface PropertyDefinitionComputedName extends BasePropertyDefinition {
+ computed: true
key: Expression
- value: FunctionExpression
}
+export interface PropertyDefinitionPrivate extends BasePropertyDefinition {
+ computed: false
+ key: PrivateIdentifier
+}
+export type PropertyDefinition =
+ | PropertyDefinitionNonComputedName
+ | PropertyDefinitionComputedName
+ | PropertyDefinitionPrivate
+
export type ModuleDeclaration =
| ImportDeclaration
| ExportNamedDeclaration
@@ -284,6 +331,10 @@ export interface Identifier extends HasParentNode {
type: 'Identifier'
name: string
}
+export interface PrivateIdentifier extends HasParentNode {
+ type: 'PrivateIdentifier'
+ name: string
+}
export interface Literal extends HasParentNode {
type: 'Literal'
value: string | boolean | null | number | RegExp | BigInt
@@ -304,16 +355,25 @@ export interface ObjectExpression extends HasParentNode {
type: 'ObjectExpression'
properties: (Property | SpreadElement)[]
}
-export interface Property extends HasParentNode {
+interface BaseProperty extends HasParentNode {
type: 'Property'
kind: 'init' | 'get' | 'set'
method: boolean
shorthand: boolean
- computed: boolean
- key: Expression
+ // computed: boolean
+ // key: Expression
value: Expression
parent: ObjectExpression
}
+export interface PropertyNonComputedName extends BaseProperty {
+ computed: false
+ key: Identifier | Literal
+}
+export interface PropertyComputedName extends BaseProperty {
+ computed: true
+ key: Expression
+}
+export type Property = PropertyNonComputedName | PropertyComputedName
export interface FunctionExpression extends HasParentNode {
type: 'FunctionExpression'
async: boolean
@@ -444,13 +504,32 @@ export interface NewExpression extends HasParentNode {
callee: Expression
arguments: (Expression | SpreadElement)[]
}
-export interface MemberExpression extends HasParentNode {
+interface BaseMemberExpression extends HasParentNode {
type: 'MemberExpression'
- computed: boolean
+ // computed: boolean
+ // object: Expression | Super
+ // property: Expression
+ optional: boolean
+}
+export interface MemberExpressionNonComputedName extends BaseMemberExpression {
+ computed: false
+ object: Expression | Super
+ property: Identifier
+}
+export interface MemberExpressionComputedName extends BaseMemberExpression {
+ computed: true
object: Expression | Super
property: Expression
- optional: boolean
}
+export interface MemberExpressionPrivate extends BaseMemberExpression {
+ computed: false
+ object: Expression
+ property: PrivateIdentifier
+}
+export type MemberExpression =
+ | MemberExpressionNonComputedName
+ | MemberExpressionComputedName
+ | MemberExpressionPrivate
export interface ChainExpression extends HasParentNode {
type: 'ChainExpression'
expression: ChainElement
@@ -506,16 +585,28 @@ export interface ObjectPattern extends HasParentNode {
type: 'ObjectPattern'
properties: (AssignmentProperty | RestElement)[]
}
-export interface AssignmentProperty extends HasParentNode {
+interface BaseAssignmentProperty extends HasParentNode {
type: 'Property'
kind: 'init'
method: false
shorthand: boolean
- computed: boolean
- key: Expression
+ // computed: boolean
+ // key: Expression
value: Pattern
parent: ObjectPattern
}
+export interface AssignmentPropertyNonComputedName
+ extends BaseAssignmentProperty {
+ computed: false
+ key: Identifier | Literal
+}
+export interface AssignmentPropertyComputedName extends BaseAssignmentProperty {
+ computed: true
+ key: Expression
+}
+export type AssignmentProperty =
+ | AssignmentPropertyNonComputedName
+ | AssignmentPropertyComputedName
export interface ArrayPattern extends HasParentNode {
type: 'ArrayPattern'
elements: Pattern[]