@@ -181,6 +181,51 @@ func FormatWithConfig(in []byte, c Config) ([]byte, error) {
181181 return PrettyBytes (nodes , 0 ), nil
182182}
183183
184+ type bracketState struct {
185+ insideComment bool
186+ insideString bool
187+ insideTemplate bool
188+ insideTripleQuotedString bool
189+ stringDelimiter string
190+ isEscapedChar bool
191+ }
192+
193+ func (s * bracketState ) processChar (c byte , i int , in []byte , allowTripleQuotedStrings bool ) {
194+ switch c {
195+ case '#' :
196+ if ! s .insideString {
197+ s .insideComment = true
198+ }
199+ case '%' :
200+ if ! s .insideComment && ! s .insideString {
201+ s .insideTemplate = ! s .insideTemplate
202+ }
203+ case '"' , '\'' :
204+ if s .insideComment {
205+ return
206+ }
207+ delim := string (c )
208+ tripleQuoted := false
209+ if allowTripleQuotedStrings && i + 3 <= len (in ) {
210+ triple := string (in [i : i + 3 ])
211+ if triple == `"""` || triple == `'''` {
212+ delim = triple
213+ tripleQuoted = true
214+ }
215+ }
216+ if s .insideString {
217+ if s .stringDelimiter == delim && (s .insideTripleQuotedString || ! s .isEscapedChar ) {
218+ s .insideString = false
219+ s .insideTripleQuotedString = false
220+ }
221+ } else {
222+ s .insideString = true
223+ s .insideTripleQuotedString = tripleQuoted
224+ s .stringDelimiter = delim
225+ }
226+ }
227+ }
228+
184229// Return the byte-positions of each bracket which has the corresponding close on the
185230// same line as a set.
186231func sameLineBrackets (in []byte , allowTripleQuotedStrings bool ) (map [int ]bool , error ) {
@@ -191,24 +236,20 @@ func sameLineBrackets(in []byte, allowTripleQuotedStrings bool) (map[int]bool, e
191236 }
192237 open := []bracket {} // Stack.
193238 res := map [int ]bool {}
194- insideComment := false
195- insideString := false
196- insideTemplate := false
197- insideTripleQuotedString := false
198- var stringDelimiter string
199- isEscapedChar := false
239+ state := bracketState {}
200240 for i , c := range in {
241+ state .processChar (c , i , in , allowTripleQuotedStrings )
201242 switch c {
202243 case '\n' :
203244 line ++
204- insideComment = false
245+ state . insideComment = false
205246 case '{' , '<' :
206- if insideComment || insideString || insideTemplate {
247+ if state . insideComment || state . insideString || state . insideTemplate {
207248 continue
208249 }
209250 open = append (open , bracket {index : i , line : line })
210251 case '}' , '>' :
211- if insideComment || insideString || insideTemplate {
252+ if state . insideComment || state . insideString || state . insideTemplate {
212253 continue
213254 }
214255 if len (open ) == 0 {
@@ -220,55 +261,15 @@ func sameLineBrackets(in []byte, allowTripleQuotedStrings bool) (map[int]bool, e
220261 if br .line == line {
221262 res [br .index ] = true
222263 }
223- case '#' :
224- if insideString {
225- continue
226- }
227- insideComment = true
228- case '%' :
229- if insideComment || insideString {
230- continue
231- }
232- if insideTemplate {
233- insideTemplate = false
234- } else {
235- insideTemplate = true
236- }
237- case '"' , '\'' :
238- if insideComment {
239- continue
240- }
241- delim := string (c )
242- tripleQuoted := false
243- if allowTripleQuotedStrings && i + 3 <= len (in ) {
244- triple := string (in [i : i + 3 ])
245- if triple == `"""` || triple == `'''` {
246- delim = triple
247- tripleQuoted = true
248- }
249- }
250-
251- if insideString {
252- if stringDelimiter == delim && (insideTripleQuotedString || ! isEscapedChar ) {
253- insideString = false
254- insideTripleQuotedString = false
255- }
256- } else {
257- insideString = true
258- if tripleQuoted {
259- insideTripleQuotedString = true
260- }
261- stringDelimiter = delim
262- }
263264 }
264-
265- if isEscapedChar {
266- isEscapedChar = false
267- } else if c == '\\' && insideString && ! insideTripleQuotedString {
268- isEscapedChar = true
265+ if state .isEscapedChar {
266+ state .isEscapedChar = false
267+ } else if c == '\\' && state .insideString && ! state .insideTripleQuotedString {
268+ state .isEscapedChar = true
269269 }
270+
270271 }
271- if insideString {
272+ if state . insideString {
272273 return nil , fmt .Errorf ("unterminated string literal" )
273274 }
274275 return res , nil
0 commit comments