@@ -45,33 +45,52 @@ module.exports = {
45
45
node . callee . property . type === 'Identifier' && node . callee . property . name === 'report'
46
46
) {
47
47
const reportInfo = utils . getReportInfo ( node . arguments , context ) ;
48
- if ( ! reportInfo || ! reportInfo . message ) {
48
+ if ( ! reportInfo ) {
49
49
return ;
50
50
}
51
51
52
- const messageStaticValue = getStaticValue ( reportInfo . message , context . getScope ( ) ) ;
53
- if (
54
- (
55
- ( reportInfo . message . type === 'Literal' && typeof reportInfo . message . value === 'string' ) ||
56
- ( messageStaticValue && typeof messageStaticValue . value === 'string' )
57
- ) &&
58
- ( ! reportInfo . data || reportInfo . data . type === 'ObjectExpression' )
59
- ) {
60
- // Same regex as the one ESLint uses
61
- // https://github.com/eslint/eslint/blob/e5446449d93668ccbdb79d78cc69f165ce4fde07/lib/eslint.js#L990
62
- const PLACEHOLDER_MATCHER = / { { \s * ( [ ^ { } ] + ?) \s * } } / g;
63
- let match ;
52
+ // Collect all violation/suggestion message nodes into a standardized array.
53
+ const messagesAndDataArray = [
54
+ // Violation message
55
+ { message : reportInfo . message , data : reportInfo . data } ,
56
+ // Suggestion messages
57
+ ...( ( reportInfo . suggest && reportInfo . suggest . elements ) || [ ] )
58
+ . map ( suggestObjNode => {
59
+ const propertyNodeDesc = suggestObjNode . properties . find ( prop => prop . key . type === 'Identifier' && prop . key . name === 'desc' ) ;
60
+ const propertyNodeData = suggestObjNode . properties . find ( prop => prop . key . type === 'Identifier' && prop . key . name === 'data' ) ;
61
+ return {
62
+ message : propertyNodeDesc ? propertyNodeDesc . value : undefined ,
63
+ data : propertyNodeData ? propertyNodeData . value : undefined ,
64
+ } ;
65
+ }
66
+ ) ,
67
+ ] . filter ( obj => obj . message ) ;
68
+
69
+ for ( const { message, data } of messagesAndDataArray ) {
70
+ const messageStaticValue = getStaticValue ( message , context . getScope ( ) ) ;
71
+ if (
72
+ (
73
+ ( message . type === 'Literal' && typeof message . value === 'string' ) ||
74
+ ( messageStaticValue && typeof messageStaticValue . value === 'string' )
75
+ ) &&
76
+ ( ! data || data . type === 'ObjectExpression' )
77
+ ) {
78
+ // Same regex as the one ESLint uses
79
+ // https://github.com/eslint/eslint/blob/e5446449d93668ccbdb79d78cc69f165ce4fde07/lib/eslint.js#L990
80
+ const PLACEHOLDER_MATCHER = / { { \s * ( [ ^ { } ] + ?) \s * } } / g;
81
+ let match ;
64
82
65
- while ( ( match = PLACEHOLDER_MATCHER . exec ( reportInfo . message . value || messageStaticValue . value ) ) ) { // eslint-disable-line no-extra-parens
66
- const matchingProperty = reportInfo . data &&
67
- reportInfo . data . properties . find ( prop => utils . getKeyName ( prop ) === match [ 1 ] ) ;
83
+ while ( ( match = PLACEHOLDER_MATCHER . exec ( message . value || messageStaticValue . value ) ) ) { // eslint-disable-line no-extra-parens
84
+ const matchingProperty = data &&
85
+ data . properties . find ( prop => utils . getKeyName ( prop ) === match [ 1 ] ) ;
68
86
69
- if ( ! matchingProperty ) {
70
- context . report ( {
71
- node : reportInfo . message ,
72
- messageId : 'placeholderDoesNotExist' ,
73
- data : { missingKey : match [ 1 ] } ,
74
- } ) ;
87
+ if ( ! matchingProperty ) {
88
+ context . report ( {
89
+ node : message ,
90
+ messageId : 'placeholderDoesNotExist' ,
91
+ data : { missingKey : match [ 1 ] } ,
92
+ } ) ;
93
+ }
75
94
}
76
95
}
77
96
}
0 commit comments