11import { pad } from "../utils/string-utils" ;
22import CommentsGenerator from "../generators/comments-generator" ;
33
4- const generator = new CommentsGenerator ( ) ;
4+ // regexps
5+ const generatedCommentRegex = new RegExp ( '/// @([a-zA-Z]*)\\b' ) ;
6+ const parameterCommentRegex = '/// @param' ;
57
6- export function insertComment ( contract , node ) {
7- let comment = generator . generate ( node ) . trim ( ) ;
8- if ( ! comment ) return ;
9- let commentLines = comment . split ( '\n' ) ;
10- if ( updateComment ( contract , commentLines , node . loc ) ) return ;
11- commentLines = pad (
12- node . loc . start . column ,
13- commentLines ,
14- isTab ( contract . getOriginalLineAt ( node . loc . start . line - 1 ) )
15- ) ;
16- contract . insertLinesBefore ( commentLines , node . loc . start . line - 1 ) ;
17- }
8+ export class ContractComment {
189
19- function updateComment ( contract , commentLines , location ) {
20- let line = location . start . line ;
21- if ( hasComment ( contract , line ) ) {
22- // extract old comments
23- let oldCommentsParams = [ ] ;
24- let oldCommentsMap = { } ;
25- let oldCommentPosition = line - 2 ;
26- while ( true ) {
27- let comment = contract . getLineAt ( oldCommentPosition ) . trim ( ) ;
28- if ( comment . startsWith ( '/// @param' ) ) {
29- oldCommentsParams . push ( { line : oldCommentPosition , value : comment } )
30- } else if ( comment . startsWith ( '//' ) ) {
31- oldCommentsMap [ comment . match ( / \/ \/ \/ @ ( [ a - z A - Z ] * ) \b / g) [ 0 ] ] = comment
32- } else if ( ! comment . startsWith ( 'function' ) ) {
33- break ;
34- }
35- oldCommentPosition -- ;
36- }
37- // check if old comment is generated comment
38- if ( isEmptyObject ( oldCommentsMap ) ) {
39- return true ;
40- }
41- // extract new comments
42- let newCommentsParams = [ ] ;
43- let newCommentsMap = commentLines . reduce ( function ( map , obj ) {
44- let key = obj . match ( / \/ \/ \/ @ ( [ a - z A - Z ] * ) \b / g) [ 0 ] ;
45- if ( key === "/// @param" ) {
46- newCommentsParams . push ( obj ) ;
47- } else map [ key ] = obj ;
48- return map ;
49- } , { } ) ;
50- // update params if changed
51- if ( newCommentsParams . length ) {
52- for ( let k in oldCommentsMap ) {
53- if ( ! k in newCommentsMap ) {
54- return true ;
10+ constructor ( contract ) {
11+ this . contract = contract ;
12+ this . generator = new CommentsGenerator ( ) ;
13+ }
14+
15+ insertComment ( node ) {
16+ const comment = this . generator . generate ( node ) . trim ( ) ;
17+ if ( ! comment ) return ;
18+ let commentLines = comment . split ( '\n' ) ;
19+ if ( this . updateComment ( commentLines , node . loc ) ) return ;
20+ commentLines = pad (
21+ node . loc . start . column ,
22+ commentLines ,
23+ this . isTab ( this . contract . getOriginalLineAt ( node . loc . start . line - 1 ) )
24+ ) ;
25+ this . contract . insertLinesBefore ( commentLines , node . loc . start . line - 1 ) ;
26+ }
27+
28+ updateComment ( commentLines , location ) {
29+ let line = location . start . line ;
30+ if ( this . hasComment ( line ) ) {
31+ // extract old comments
32+ let oldCommentsParams = [ ] ;
33+ let oldCommentsMap = { } ;
34+ let oldCommentPosition = line - 2 ;
35+ while ( true ) {
36+ let comment = this . contract . getLineAt ( oldCommentPosition ) . trim ( ) ;
37+ if ( comment . startsWith ( parameterCommentRegex ) ) {
38+ oldCommentsParams . push ( { line : oldCommentPosition , value : comment } )
39+ } else if ( comment . startsWith ( '//' ) ) {
40+ oldCommentsMap [ comment . match ( generatedCommentRegex ) [ 0 ] ] = comment
41+ } else if ( ! comment . startsWith ( 'function' ) ) {
42+ break ;
5543 }
44+ oldCommentPosition -- ;
5645 }
57- let firstCommentLine = oldCommentsParams
58- . reduce ( ( min , b ) => Math . min ( min , b . line ) , oldCommentsParams [ 0 ] . line ) ;
59- // remove old params comments and save additional information about params
60- let savedComments = { } ;
61- for ( let oldComment of oldCommentsParams ) {
62- contract . removeLine ( firstCommentLine ) ;
63- // save old right part of comment
64- let c = oldComment . value . toString ( ) . trim ( ) . split ( ' ' ) ;
65- if ( c . length > 3 ) {
66- savedComments [ c [ 2 ] ] = c . slice ( 3 ) . join ( ' ' ) ;
67- }
46+ // check if old comment is generated comment
47+ if ( this . isEmptyObject ( oldCommentsMap ) ) {
48+ return true ;
6849 }
69- // insert new params comments
70- newCommentsParams = pad (
71- location . start . column ,
72- newCommentsParams ,
73- isTab ( contract . getOriginalLineAt ( location . start . line - 1 ) )
74- ) ;
75- for ( let newComment of newCommentsParams . reverse ( ) ) {
76- let oldCommentParamName = newComment . trim ( ) . split ( ' ' ) [ 2 ] ;
77- let savedComment = savedComments [ oldCommentParamName ] ;
78- if ( typeof savedComment !== "undefined" ) {
79- newComment = newComment + " " + savedComment ;
50+ // extract new comments
51+ let newCommentsParams = [ ] ;
52+ let newCommentsMap = commentLines . reduce ( function ( map , obj ) {
53+ let key = obj . match ( generatedCommentRegex ) [ 0 ] ;
54+ if ( key === parameterCommentRegex ) {
55+ newCommentsParams . push ( obj ) ;
56+ } else map [ key ] = obj ;
57+ return map ;
58+ } , { } ) ;
59+ // update params if changed
60+ if ( newCommentsParams . length ) {
61+ for ( let k in oldCommentsMap ) {
62+ if ( ! k in newCommentsMap ) {
63+ return true ;
64+ }
8065 }
81- contract . insertLinesBeforeWithoutCalculatingAndAddingOffset ( newComment . split ( ) , firstCommentLine ) ;
66+ let firstCommentLine = oldCommentsParams
67+ . reduce ( ( min , b ) => Math . min ( min , b . line ) , oldCommentsParams [ 0 ] . line ) ;
68+ // remove old params comments and save additional information about params
69+ let savedComments = { } ;
70+ for ( let oldComment of oldCommentsParams ) {
71+ this . contract . removeLine ( firstCommentLine ) ;
72+ // save old right part of comment
73+ let c = oldComment . value . toString ( ) . trim ( ) . split ( ' ' ) ;
74+ if ( c . length > 3 ) {
75+ savedComments [ c [ 2 ] ] = c . slice ( 3 ) . join ( ' ' ) ;
76+ }
77+ }
78+ // insert new params comments
79+ newCommentsParams = pad (
80+ location . start . column ,
81+ newCommentsParams ,
82+ this . isTab ( this . contract . getOriginalLineAt ( location . start . line - 1 ) )
83+ ) ;
84+ for ( let newComment of newCommentsParams . reverse ( ) ) {
85+ let oldCommentParamName = newComment . trim ( ) . split ( ' ' ) [ 2 ] ;
86+ let savedComment = savedComments [ oldCommentParamName ] ;
87+ if ( typeof savedComment !== "undefined" ) {
88+ newComment = newComment + " " + savedComment ;
89+ }
90+ this . contract . insertLinesBeforeWithoutCalculatingAndAddingOffset ( newComment . split ( ) , firstCommentLine ) ;
91+ }
92+ this . contract . addOffset ( firstCommentLine , newCommentsParams . length - oldCommentsParams . length ) ;
93+ return true ;
8294 }
83- contract . addOffset ( firstCommentLine , newCommentsParams . length - oldCommentsParams . length ) ;
8495 return true ;
8596 }
86- return true ;
97+ return false ;
8798 }
88- return false ;
89- }
9099
91- function hasComment ( contract , line ) {
92- let counter = 1 ;
93- while ( true ) {
94- counter ++ ;
95- let lineText = contract . getOriginalLineAt ( line - counter ) ;
96- if ( lineText . trim ( ) . startsWith ( 'function' ) ) {
97- lineText = contract . getOriginalLineAt ( line - counter - 1 ) ;
100+ hasComment ( line ) {
101+ let counter = 1 ;
102+ while ( true ) {
103+ counter ++ ;
104+ let lineText = this . contract . getOriginalLineAt ( line - counter ) ;
105+ if ( lineText . trim ( ) . startsWith ( 'function' ) ) {
106+ lineText = this . contract . getOriginalLineAt ( line - counter - 1 ) ;
107+ }
108+ if ( lineText === undefined ) return false ;
109+ lineText = lineText . trim ( ) ;
110+ if ( lineText . startsWith ( '*' ) || lineText . startsWith ( '//' ) ) return true ;
111+ if ( ! lineText . replace ( / \s / g, '' ) . length ) continue ;
112+ return false ;
98113 }
99- if ( lineText === undefined ) return false ;
100- lineText = lineText . trim ( ) ;
101- if ( lineText . startsWith ( '*' ) || lineText . startsWith ( '//' ) ) return true ;
102- if ( ! lineText . replace ( / \s / g, '' ) . length ) continue ;
103- return false ;
104114 }
105- }
106115
107- function isEmptyObject ( obj ) {
108- for ( let name in obj ) {
109- return false ;
116+ isEmptyObject ( obj ) {
117+ for ( let name in obj ) {
118+ return false ;
119+ }
120+ return true ;
121+ }
122+
123+ isTab ( originalLineAt ) {
124+ return originalLineAt . startsWith ( '\t' ) ;
110125 }
111- return true ;
112126}
113127
114- function isTab ( originalLineAt ) {
115- return originalLineAt . startsWith ( '\t' ) ;
116- }
128+
129+
0 commit comments