44 */
55'use strict'
66
7+ /**
8+ * @typedef {import('vue-eslint-parser').AST.ESLintExpression } Expression
9+ * @typedef {import('vue-eslint-parser').AST.ESLintObjectExpression } ObjectExpression
10+ * @typedef {import('vue-eslint-parser').AST.ESLintPattern } Pattern
11+ */
12+ /**
13+ * @typedef {import('../utils').ComponentObjectProp } ComponentObjectProp
14+ * @typedef {ComponentObjectProp & { value: ObjectExpression} } ComponentObjectPropObject
15+ */
16+
717const utils = require ( '../utils' )
818
919const NATIVE_TYPES = new Set ( [
@@ -39,14 +49,14 @@ module.exports = {
3949
4050 /**
4151 * Checks if the passed prop is required
42- * @param {Property } prop - Property AST node for a single prop
52+ * @param {ComponentObjectPropObject } prop - Property AST node for a single prop
4353 * @return {boolean }
4454 */
4555 function propIsRequired ( prop ) {
4656 const propRequiredNode = prop . value . properties
4757 . find ( p =>
4858 p . type === 'Property' &&
49- p . key . name === 'required' &&
59+ utils . getStaticPropertyName ( p ) === 'required' &&
5060 p . value . type === 'Literal' &&
5161 p . value . value === true
5262 )
@@ -56,38 +66,38 @@ module.exports = {
5666
5767 /**
5868 * Checks if the passed prop has a default value
59- * @param {Property } prop - Property AST node for a single prop
69+ * @param {ComponentObjectPropObject } prop - Property AST node for a single prop
6070 * @return {boolean }
6171 */
6272 function propHasDefault ( prop ) {
6373 const propDefaultNode = prop . value . properties
6474 . find ( p =>
65- p . key &&
66- ( p . key . name === 'default' || p . key . value === 'default' )
75+ p . type === 'Property' && utils . getStaticPropertyName ( p ) === 'default'
6776 )
6877
6978 return Boolean ( propDefaultNode )
7079 }
7180
7281 /**
7382 * Finds all props that don't have a default value set
74- * @param {Array } props - Vue component's "props" node
75- * @return {Array } Array of props without "default" value
83+ * @param {ComponentObjectProp[] } props - Vue component's "props" node
84+ * @return {ComponentObjectProp[] } Array of props without "default" value
7685 */
7786 function findPropsWithoutDefaultValue ( props ) {
7887 return props
7988 . filter ( prop => {
8089 if ( prop . value . type !== 'ObjectExpression' ) {
81- return ( prop . value . type !== 'CallExpression' && prop . value . type !== 'Identifier' ) || NATIVE_TYPES . has ( prop . value . name )
90+ return ( prop . value . type !== 'CallExpression' && prop . value . type !== 'Identifier' ) ||
91+ ( prop . value . type === 'Identifier' && NATIVE_TYPES . has ( prop . value . name ) )
8292 }
8393
84- return ! propIsRequired ( prop ) && ! propHasDefault ( prop )
94+ return ! propIsRequired ( /** @type { ComponentObjectPropObject } */ ( prop ) ) && ! propHasDefault ( /** @type { ComponentObjectPropObject } */ ( prop ) )
8595 } )
8696 }
8797
8898 /**
8999 * Detects whether given value node is a Boolean type
90- * @param {Node } value
100+ * @param {Expression | Pattern } value
91101 * @return {Boolean }
92102 */
93103 function isValueNodeOfBooleanType ( value ) {
@@ -104,15 +114,16 @@ module.exports = {
104114
105115 /**
106116 * Detects whether given prop node is a Boolean
107- * @param {Node } prop
117+ * @param {ComponentObjectProp } prop
108118 * @return {Boolean }
109119 */
110120 function isBooleanProp ( prop ) {
111121 const value = utils . unwrapTypes ( prop . value )
112122
113123 return isValueNodeOfBooleanType ( value ) || (
114124 value . type === 'ObjectExpression' &&
115- value . properties . find ( p =>
125+ value . properties . some ( p =>
126+ p . type === 'Property' &&
116127 p . key . type === 'Identifier' &&
117128 p . key . name === 'type' &&
118129 isValueNodeOfBooleanType ( p . value )
@@ -122,8 +133,8 @@ module.exports = {
122133
123134 /**
124135 * Excludes purely Boolean props from the Array
125- * @param {Array } props - Array with props
126- * @return {Array }
136+ * @param {ComponentObjectProp[] } props - Array with props
137+ * @return {ComponentObjectProp[] }
127138 */
128139 function excludeBooleanProps ( props ) {
129140 return props . filter ( prop => ! isBooleanProp ( prop ) )
@@ -135,9 +146,9 @@ module.exports = {
135146
136147 return utils . executeOnVue ( context , ( obj ) => {
137148 const props = utils . getComponentProps ( obj )
138- . filter ( prop => prop . key && prop . value && ! prop . node . shorthand )
149+ . filter ( prop => prop . key && prop . value && ! ( prop . node . type === 'Property' && prop . node . shorthand ) )
139150
140- const propsWithoutDefault = findPropsWithoutDefaultValue ( props )
151+ const propsWithoutDefault = findPropsWithoutDefaultValue ( /** @type { ComponentObjectProp[] } */ ( props ) )
141152 const propsToReport = excludeBooleanProps ( propsWithoutDefault )
142153
143154 for ( const prop of propsToReport ) {
0 commit comments