From 6b8ef9b9914f8934f6d19970ad4481b51bf331ff Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Thu, 26 May 2022 19:00:31 -0400 Subject: [PATCH] Fix for case when comments precede a statement containing an issue e.g. // foo set foo.bar to 6 This would mark the error on the comment rather than the set statement. Because participle includes comments in a node's Tokens, we need to strip them out before calculating where the issues are. --- amod/issue_log.go | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/amod/issue_log.go b/amod/issue_log.go index 51695d82..4530361e 100644 --- a/amod/issue_log.go +++ b/amod/issue_log.go @@ -25,8 +25,11 @@ func (l *Log) ErrorTR(tokens []lexer.Token, start, end int, s string, a ...inter // tokensToLocation takes the list of lexer tokens and converts it to our own // issues.Location struct. -func tokensToLocation(tokens []lexer.Token) *issues.Location { - // If we have space tokens on either side, strip them out +func tokensToLocation(t []lexer.Token) *issues.Location { + tokens := trimCommentsFromRange(t) + + // If we are in the middle of a pattern, we might have pattern spaces, + // so remove from beginning & end. if tokens[0].Type == lexer.TokenType(lexemePatternSpace) { tokens = tokens[1:] } @@ -52,12 +55,14 @@ func tokensToLocation(tokens []lexer.Token) *issues.Location { } } -func tokenRangeToLocation(tokens []lexer.Token, start, end int) *issues.Location { +func tokenRangeToLocation(t []lexer.Token, start, end int) *issues.Location { if start < 0 || end < 1 || start == end || end < start { fmt.Printf("Internal error (tokenRangeToLocation): start (%d) and/or end (%d) incorrect. Using full range.\n", start, end) - return tokensToLocation(tokens) + return tokensToLocation(t) } + tokens := trimCommentsFromRange(t) + numTokens := len(tokens) if end > numTokens-1 { fmt.Printf("Internal error (tokenRangeToLocation): end (%d - 0-indexed) greater than tokens len (%d). Using full range.\n", end, numTokens) @@ -68,3 +73,32 @@ func tokenRangeToLocation(tokens []lexer.Token, start, end int) *issues.Location return tokensToLocation(restricted) } + +// trimCommentsFromRange will remove any comment tokens from the beginning and end of the range. +// This is necessary because participle will include them with the Tokens in a struct. +func trimCommentsFromRange(t []lexer.Token) (tokens []lexer.Token) { + begin := 0 + for _, token := range t { + if token.Type == lexer.TokenType(lexemeComment) { + begin++ + continue + } + + break + } + + end := len(t) + for i := end - 1; i >= 0; i-- { + token := t[i] + + if token.Type == lexer.TokenType(lexemeComment) { + end-- + continue + } + + break + } + + tokens = t[begin:end] + return +}