@@ -5,6 +5,16 @@ const extractParagraphs = (text) => {
55 return text . split ( / \n \n / ) ;
66} ;
77
8+ const extractSentences = ( text ) => {
9+ return text . split ( / \. \s * / ) . filter ( ( sentence ) => {
10+ // Ignore sentences with only whitespaces.
11+ return ! / ^ \s * $ / . test ( sentence ) ;
12+ } ) . map ( ( sentence ) => {
13+ // Re-add the dot.
14+ return sentence + '.' ;
15+ } ) ;
16+ } ;
17+
818const isNewLinePrecededByAPeriod = ( text ) => {
919 let lastLineEndsSentence ;
1020
@@ -25,26 +35,45 @@ const isCapitalized = (str) => {
2535 return str [ 0 ] === str [ 0 ] . toUpperCase ( ) ;
2636} ;
2737
28- const validateDescription = ( description , report ) => {
38+ const capitalize = ( str ) => {
39+ return str . charAt ( 0 ) . toUpperCase ( ) + str . slice ( 1 ) ;
40+ } ;
41+
42+ const validateDescription = ( description , report , jsdocNode , sourceCode ) => {
2943 if ( ! description ) {
3044 return false ;
3145 }
3246
3347 const paragraphs = extractParagraphs ( description ) ;
3448
35- return _ . some ( paragraphs , ( paragraph , index ) => {
36- if ( ! isCapitalized ( paragraph ) ) {
37- if ( index === 0 ) {
38- report ( 'Description must start with an uppercase character.' ) ;
39- } else {
40- report ( 'Paragraph must start with an uppercase character.' ) ;
41- }
49+ return _ . some ( paragraphs , ( paragraph ) => {
50+ const sentences = extractSentences ( paragraph ) ;
4251
43- return true ;
52+ if ( _ . some ( sentences , ( sentence ) => {
53+ return ! isCapitalized ( sentence ) ;
54+ } ) ) {
55+ report ( 'Sentence should start with an uppercase character.' , ( fixer ) => {
56+ let text = sourceCode . getText ( jsdocNode ) ;
57+
58+ for ( const sentence of sentences . filter ( ( sentence_ ) => {
59+ return ! isCapitalized ( sentence_ ) ;
60+ } ) ) {
61+ const beginning = sentence . split ( / \n / ) [ 0 ] ;
62+
63+ text = text . replace ( beginning , capitalize ( beginning ) ) ;
64+ }
65+
66+ return fixer . replaceText ( jsdocNode , text ) ;
67+ } ) ;
4468 }
4569
4670 if ( ! / \. $ / . test ( paragraph ) ) {
47- report ( 'Sentence must end with a period.' ) ;
71+ report ( 'Sentence must end with a period.' , ( fixer ) => {
72+ const line = _ . last ( paragraph . split ( '\n' ) ) ;
73+ const replacement = sourceCode . getText ( jsdocNode ) . replace ( line , line + '.' ) ;
74+
75+ return fixer . replaceText ( jsdocNode , replacement ) ;
76+ } ) ;
4877
4978 return true ;
5079 }
@@ -60,10 +89,12 @@ const validateDescription = (description, report) => {
6089} ;
6190
6291export default iterateJsdoc ( ( {
92+ sourceCode,
6393 jsdoc,
64- report
94+ report,
95+ jsdocNode
6596} ) => {
66- if ( validateDescription ( jsdoc . description , report ) ) {
97+ if ( validateDescription ( jsdoc . description , report , jsdocNode , sourceCode ) ) {
6798 return ;
6899 }
69100
@@ -74,6 +105,6 @@ export default iterateJsdoc(({
74105 _ . some ( tags , ( tag ) => {
75106 const description = _ . trimStart ( tag . description , '- ' ) ;
76107
77- return validateDescription ( description , report ) ;
108+ return validateDescription ( description , report , jsdocNode , sourceCode ) ;
78109 } ) ;
79110} ) ;
0 commit comments