@@ -7,22 +7,19 @@ def match(tokens)
77 RBRACE : :LBRACE ,
88 RBRACK : :LBRACK ,
99 RPAREN : :LPAREN ,
10- HEREDOC : :HEREDOC_OPEN ,
11- HEREDOC_POST : :HEREDOC_OPEN ,
1210 }
1311 open = {
1412 LBRACE : [ ] ,
1513 LBRACK : [ ] ,
1614 LPAREN : [ ] ,
17- HEREDOC_OPEN : [ ] ,
1815 }
1916
2017 matches = { }
2118
2219 tokens . each do |token |
23- if %i[ LBRACE LBRACK LPAREN HEREDOC_OPEN ] . include? ( token . type )
20+ if %i[ LBRACE LBRACK LPAREN ] . include? ( token . type )
2421 open [ token . type ] << token
25- elsif %i[ RBRACE RBRACK RPAREN HEREDOC HEREDOC_POST ] . include? ( token . type )
22+ elsif %i[ RBRACE RBRACK RPAREN ] . include? ( token . type )
2623 match = open [ opening_token [ token . type ] ] . pop
2724 unless match . nil?
2825 matches [ token ] = match
@@ -138,13 +135,31 @@ def check
138135 end
139136
140137 # get actual indent
141- actual = 0
142- actual = if token . next_token . type == :INDENT
138+ actual = case token . next_token . type
139+ when :INDENT
143140 token . next_token . value . length
144- elsif !token . prev_token . nil? and token . prev_token . type == :HEREDOC
145- token . prev_token . value . split ( "\n " ) . last . length
146- elsif !token . prev_token . nil? and token . prev_token . type == :HEREDOC_OPEN
147- next_token . prev_token . value . split ( "\n " ) . last . length
141+ when :HEREDOC
142+ # Lines containing heredocs have no indent token as the indent is consumed by the heredoc token.
143+ # However the last line of the token value is the whitespace before the pipe in the termination line.
144+ # We use the length of this to get the indent.
145+ if token . next_token . value . end_with? ( "\n " )
146+ 0
147+ else
148+ token . next_token . value . split ( "\n " ) . last . length
149+ end
150+ when :HEREDOC_PRE
151+ # For interpolated heredocs the pipe whitespace is in the HEREDOC_POST token so we need scan forward
152+ # to this and get its length.
153+ next_token = token . next_token
154+ while !next_token . nil? and next_token . type != :NEWLINE and next_token . type != :HEREDOC_POST
155+ next_token = next_token . next_token
156+ end
157+ if next_token . type == :HEREDOC_POST
158+ next_token . value . split ( "\n " ) . last . length
159+ else
160+ # Should never get here return zero if we do
161+ 0
162+ end
148163 else
149164 0
150165 end
@@ -164,6 +179,7 @@ def check
164179 column : token . next_token . column ,
165180 token : token . next_token ,
166181 indent : expected ,
182+ actual : actual ,
167183 }
168184 end
169185 end
@@ -172,11 +188,50 @@ def fix(problem)
172188 char_for_indent = ' '
173189 if %i[ INDENT WHITESPACE ] . include? ( problem [ :token ] . type )
174190 problem [ :token ] . value = char_for_indent * problem [ :indent ]
191+ elsif problem [ :token ] . type == :HEREDOC
192+ change = problem [ :indent ] - problem [ :actual ]
193+ indent_heredoc ( problem [ :token ] , change )
194+ elsif problem [ :token ] . type == :HEREDOC_PRE
195+ change = problem [ :indent ] - problem [ :actual ]
196+ indent_heredoc ( problem [ :token ] , change )
197+ next_token = problem [ :token ] . next_token
198+ while !next_token . nil? and next_token . type != :HEREDOC_POST
199+ indent_heredoc ( next_token , change ) if next_token . type == :HEREDOC_MID
200+ next_token = next_token . next_token
201+ end
202+ indent_heredoc ( next_token , change ) if next_token . type == :HEREDOC_POST
175203 else
176204 tokens . insert (
177205 tokens . find_index ( problem [ :token ] ) ,
178206 PuppetLint ::Lexer ::Token . new ( :INDENT , char_for_indent * problem [ :indent ] , problem [ :line ] , problem [ :column ] ) ,
179207 )
180208 end
181209 end
210+
211+ def map_heredoc_lines ( value , change , skip )
212+ char_for_indent = ' '
213+ value . split ( "\n " ) . map! do |line |
214+ if skip or line . empty?
215+ skip = false
216+ line
217+ elsif change < 0
218+ line [ -change ..]
219+ else
220+ ( char_for_indent * change ) + line
221+ end
222+ end . join ( "\n " )
223+ end
224+
225+ def indent_heredoc ( token , change )
226+ case token . type
227+ when :HEREDOC
228+ token . raw = map_heredoc_lines ( token . raw , change , false )
229+ when :HEREDOC_PRE
230+ token . value = map_heredoc_lines ( token . value , change , false )
231+ when :HEREDOC_MID
232+ token . value = map_heredoc_lines ( token . value , change , true )
233+ when :HEREDOC_POST
234+ token . raw = map_heredoc_lines ( token . raw , change , true )
235+ end
236+ end
182237end
0 commit comments