diff --git a/server/common/parser/strings.go b/server/common/parser/strings.go index 7e3f95b..607be11 100644 --- a/server/common/parser/strings.go +++ b/server/common/parser/strings.go @@ -67,15 +67,21 @@ func TrimWhitespace( ) } - value := raw + value := strings.TrimSpace(raw) currentIndex := 0 for { nextStart, found := findNextDoubleQuote(value, currentIndex) if found { - part := value[:nextStart] - value = strings.TrimSpace(part) + value[nextStart:] + part := trimPattern.ReplaceAllString( + value[:nextStart], + " ", + ) + + value = modifyString(value, 0, nextStart, part) + } else { + break } nextEnd, found := findNextDoubleQuote(value, nextStart+1) @@ -91,7 +97,7 @@ func TrimWhitespace( if currentIndex < len(value) { part := value[currentIndex:] - value = value[:currentIndex] + strings.TrimSpace(part) + value = modifyString(value, currentIndex, len(value), part) } return value diff --git a/server/common/virtual-line.go b/server/common/virtual-line.go index 27f7341..574da75 100644 --- a/server/common/virtual-line.go +++ b/server/common/virtual-line.go @@ -49,7 +49,8 @@ func (l VirtualLine) GetSubset(start uint32, end uint32) VirtualLine { if end <= partEnd { rangeEnd = end - partStart } else { - rangeEnd = partEnd + // End of the part + rangeEnd = partEnd - partStart } parts = append(parts, VirtualLinePart{ @@ -100,27 +101,27 @@ func (l VirtualLine) ConvertRangeToTextRange(start uint32, end uint32) []Locatio return ranges } -func (l VirtualLine) AsTrimmed() VirtualLine { - if len(l.Parts) == 0 { - // There's nothing that could be trimmed, so we can also just - // return the original line, as it's identical - return l - } - - parts := make([]VirtualLinePart, len(l.Parts)) - - for index, part := range l.Parts { - parts[index] = part.AsTrimmed() - } - - return VirtualLine{ - LocationRange: LocationRange{ - Start: parts[0].Start, - End: parts[len(parts)-1].End, - }, - Parts: parts, - } -} +// func (l VirtualLine) AsTrimmed() VirtualLine { +// if len(l.Parts) == 0 { +// // There's nothing that could be trimmed, so we can also just +// // return the original line, as it's identical +// return l +// } +// +// parts := make([]VirtualLinePart, len(l.Parts)) +// +// for index, part := range l.Parts { +// parts[index] = part.AsTrimmed() +// } +// +// return VirtualLine{ +// LocationRange: LocationRange{ +// Start: parts[0].Start, +// End: parts[len(parts)-1].End, +// }, +// Parts: parts, +// } +// } type VirtualLinePart struct { // This is the true location of the text @@ -129,34 +130,39 @@ type VirtualLinePart struct { Text string } -func (p VirtualLinePart) AsTrimmed() VirtualLinePart { - firstNonWhitespace := utils.FindFirstNonMatch(p.Text, UnicodeWhitespace, 0) - - if firstNonWhitespace == -1 { - // Empty line - return p - } - - lastNonWhitespace := utils.FindLastNonMatch(p.Text, UnicodeWhitespace, len(p.Text)-1) - - if lastNonWhitespace == -1 { - lastNonWhitespace = len(p.Text) - 1 - } - - return VirtualLinePart{ - LocationRange: LocationRange{ - Start: Location{ - Line: p.Start.Line, - Character: p.Start.Character + uint32(firstNonWhitespace), - }, - End: Location{ - Line: p.Start.Line, - Character: p.Start.Character + uint32(lastNonWhitespace) + 1, - }, - }, - Text: p.Text[firstNonWhitespace : lastNonWhitespace+1], - } -} +// func (p VirtualLinePart) AsTrimmed() VirtualLinePart { +// firstNonWhitespace := utils.FindFirstNonMatch(p.Text, UnicodeWhitespace, 0) +// +// if firstNonWhitespace == -1 { +// // Empty line +// return p +// } +// +// var text string +// lastNonWhitespace := utils.FindLastNonMatch(p.Text, UnicodeWhitespace, len(p.Text)-1) +// +// // Allow one space at the end +// if lastNonWhitespace == -1 { +// lastNonWhitespace = len(p.Text) - 1 +// text = p.Text[firstNonWhitespace:] +// } else { +// text = p.Text[firstNonWhitespace : lastNonWhitespace+1] +// } +// +// return VirtualLinePart{ +// LocationRange: LocationRange{ +// Start: Location{ +// Line: p.Start.Line, +// Character: p.Start.Character + uint32(firstNonWhitespace), +// }, +// End: Location{ +// Line: p.Start.Line, +// Character: p.Start.Character + uint32(lastNonWhitespace) + 1, +// }, +// }, +// Text: text, +// } +// } func SplitIntoVirtualLines(input string) []VirtualLine { stringLines := utils.SplitIntoVirtualLines(input) diff --git a/server/common/virtual-line_test.go b/server/common/virtual-line_test.go index c7aa748..5451439 100644 --- a/server/common/virtual-line_test.go +++ b/server/common/virtual-line_test.go @@ -133,50 +133,50 @@ how are you } } -func TestSplitIntoVirtualLinesIndentedExample( - t *testing.T, -) { - // 4 spaces - input := utils.Dedent(` - Hello -`) - expected := []VirtualLine{ - { - LocationRange: LocationRange{ - Start: Location{ - Line: 0, - Character: 4, - }, - End: Location{ - Line: 0, - Character: 9, - }, - }, - Parts: []VirtualLinePart{ - { - LocationRange: LocationRange{ - Start: Location{ - Line: 0, - Character: 4, - }, - End: Location{ - Line: 0, - Character: 9, - }, - }, - Text: "Hello", - }, - }, - }, - } - - actual := SplitIntoVirtualLines(input) - - for index, line := range actual { - actual[index] = line.AsTrimmed() - } - - if !cmp.Equal(expected, actual) { - t.Fatalf("Expected %v, got %v", expected, actual) - } -} +// func TestSplitIntoVirtualLinesIndentedExample( +// t *testing.T, +// ) { +// // 4 spaces +// input := utils.Dedent(` +// Hello +// `) +// expected := []VirtualLine{ +// { +// LocationRange: LocationRange{ +// Start: Location{ +// Line: 0, +// Character: 4, +// }, +// End: Location{ +// Line: 0, +// Character: 9, +// }, +// }, +// Parts: []VirtualLinePart{ +// { +// LocationRange: LocationRange{ +// Start: Location{ +// Line: 0, +// Character: 4, +// }, +// End: Location{ +// Line: 0, +// Character: 9, +// }, +// }, +// Text: "Hello", +// }, +// }, +// }, +// } +// +// actual := SplitIntoVirtualLines(input) +// +// for index, line := range actual { +// actual[index] = line.AsTrimmed() +// } +// +// if !cmp.Equal(expected, actual) { +// t.Fatalf("Expected %v, got %v", expected, actual) +// } +// } diff --git a/server/handlers/gitconfig/Config.g4 b/server/handlers/gitconfig/Config.g4 index 7638fed..df044e4 100644 --- a/server/handlers/gitconfig/Config.g4 +++ b/server/handlers/gitconfig/Config.g4 @@ -25,7 +25,7 @@ value ; string - : (QUOTED_STRING | (WHITESPACE? (STRING WHITESPACE)* STRING)) + : (WHITESPACE? ((STRING | QUOTED_STRING) WHITESPACE)* (STRING | QUOTED_STRING)) ; commentSymbol diff --git a/server/handlers/gitconfig/ast/listener.go b/server/handlers/gitconfig/ast/listener.go index 6040c02..1ef79e3 100644 --- a/server/handlers/gitconfig/ast/listener.go +++ b/server/handlers/gitconfig/ast/listener.go @@ -90,12 +90,12 @@ func (s *gitconfigParserListener) EnterValue(ctx *parser.ValueContext) { location := common.CharacterRangeFromCtx(ctx.BaseParserRuleContext) location.ChangeBothLines(s.gitconfigContext.line) - virtualLine := s.gitconfigContext.virtualLine.GetSubset(location.Start.Character, location.End.Character).AsTrimmed() + virtualLine := s.gitconfigContext.virtualLine.GetSubset(location.Start.Character, location.End.Character) value := commonparser.ParseRawString( virtualLine.GetText(), commonparser.ParseFeatures{ ParseDoubleQuotes: true, - TrimWhitespace: false, + TrimWhitespace: true, ParseEscapedCharacters: false, Replacements: &map[string]string{}, }, diff --git a/server/handlers/gitconfig/ast/parser/Config.interp b/server/handlers/gitconfig/ast/parser/Config.interp index 3648d06..520f237 100644 --- a/server/handlers/gitconfig/ast/parser/Config.interp +++ b/server/handlers/gitconfig/ast/parser/Config.interp @@ -28,4 +28,4 @@ commentSymbol atn: -[4, 1, 6, 78, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 1, 0, 3, 0, 18, 8, 0, 1, 0, 1, 0, 3, 0, 22, 8, 0, 1, 0, 3, 0, 25, 8, 0, 1, 0, 1, 0, 1, 1, 3, 1, 30, 8, 1, 1, 1, 3, 1, 33, 8, 1, 1, 1, 3, 1, 36, 8, 1, 1, 1, 3, 1, 39, 8, 1, 1, 1, 3, 1, 42, 8, 1, 1, 2, 1, 2, 3, 2, 46, 8, 2, 1, 2, 1, 2, 3, 2, 50, 8, 2, 4, 2, 52, 8, 2, 11, 2, 12, 2, 53, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 3, 6, 64, 8, 6, 1, 6, 1, 6, 5, 6, 68, 8, 6, 10, 6, 12, 6, 71, 9, 6, 1, 6, 3, 6, 74, 8, 6, 1, 7, 1, 7, 1, 7, 0, 0, 8, 0, 2, 4, 6, 8, 10, 12, 14, 0, 1, 1, 0, 2, 3, 83, 0, 17, 1, 0, 0, 0, 2, 29, 1, 0, 0, 0, 4, 43, 1, 0, 0, 0, 6, 55, 1, 0, 0, 0, 8, 57, 1, 0, 0, 0, 10, 59, 1, 0, 0, 0, 12, 73, 1, 0, 0, 0, 14, 75, 1, 0, 0, 0, 16, 18, 5, 4, 0, 0, 17, 16, 1, 0, 0, 0, 17, 18, 1, 0, 0, 0, 18, 19, 1, 0, 0, 0, 19, 21, 3, 2, 1, 0, 20, 22, 5, 4, 0, 0, 21, 20, 1, 0, 0, 0, 21, 22, 1, 0, 0, 0, 22, 24, 1, 0, 0, 0, 23, 25, 3, 4, 2, 0, 24, 23, 1, 0, 0, 0, 24, 25, 1, 0, 0, 0, 25, 26, 1, 0, 0, 0, 26, 27, 5, 0, 0, 1, 27, 1, 1, 0, 0, 0, 28, 30, 3, 6, 3, 0, 29, 28, 1, 0, 0, 0, 29, 30, 1, 0, 0, 0, 30, 32, 1, 0, 0, 0, 31, 33, 5, 4, 0, 0, 32, 31, 1, 0, 0, 0, 32, 33, 1, 0, 0, 0, 33, 35, 1, 0, 0, 0, 34, 36, 3, 8, 4, 0, 35, 34, 1, 0, 0, 0, 35, 36, 1, 0, 0, 0, 36, 38, 1, 0, 0, 0, 37, 39, 5, 4, 0, 0, 38, 37, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 41, 1, 0, 0, 0, 40, 42, 3, 10, 5, 0, 41, 40, 1, 0, 0, 0, 41, 42, 1, 0, 0, 0, 42, 3, 1, 0, 0, 0, 43, 45, 3, 14, 7, 0, 44, 46, 5, 4, 0, 0, 45, 44, 1, 0, 0, 0, 45, 46, 1, 0, 0, 0, 46, 51, 1, 0, 0, 0, 47, 49, 3, 12, 6, 0, 48, 50, 5, 4, 0, 0, 49, 48, 1, 0, 0, 0, 49, 50, 1, 0, 0, 0, 50, 52, 1, 0, 0, 0, 51, 47, 1, 0, 0, 0, 52, 53, 1, 0, 0, 0, 53, 51, 1, 0, 0, 0, 53, 54, 1, 0, 0, 0, 54, 5, 1, 0, 0, 0, 55, 56, 3, 12, 6, 0, 56, 7, 1, 0, 0, 0, 57, 58, 5, 1, 0, 0, 58, 9, 1, 0, 0, 0, 59, 60, 3, 12, 6, 0, 60, 11, 1, 0, 0, 0, 61, 74, 5, 6, 0, 0, 62, 64, 5, 4, 0, 0, 63, 62, 1, 0, 0, 0, 63, 64, 1, 0, 0, 0, 64, 69, 1, 0, 0, 0, 65, 66, 5, 5, 0, 0, 66, 68, 5, 4, 0, 0, 67, 65, 1, 0, 0, 0, 68, 71, 1, 0, 0, 0, 69, 67, 1, 0, 0, 0, 69, 70, 1, 0, 0, 0, 70, 72, 1, 0, 0, 0, 71, 69, 1, 0, 0, 0, 72, 74, 5, 5, 0, 0, 73, 61, 1, 0, 0, 0, 73, 63, 1, 0, 0, 0, 74, 13, 1, 0, 0, 0, 75, 76, 7, 0, 0, 0, 76, 15, 1, 0, 0, 0, 14, 17, 21, 24, 29, 32, 35, 38, 41, 45, 49, 53, 63, 69, 73] \ No newline at end of file +[4, 1, 6, 76, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 1, 0, 3, 0, 18, 8, 0, 1, 0, 1, 0, 3, 0, 22, 8, 0, 1, 0, 3, 0, 25, 8, 0, 1, 0, 1, 0, 1, 1, 3, 1, 30, 8, 1, 1, 1, 3, 1, 33, 8, 1, 1, 1, 3, 1, 36, 8, 1, 1, 1, 3, 1, 39, 8, 1, 1, 1, 3, 1, 42, 8, 1, 1, 2, 1, 2, 3, 2, 46, 8, 2, 1, 2, 1, 2, 3, 2, 50, 8, 2, 4, 2, 52, 8, 2, 11, 2, 12, 2, 53, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 3, 6, 63, 8, 6, 1, 6, 1, 6, 5, 6, 67, 8, 6, 10, 6, 12, 6, 70, 9, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 0, 0, 8, 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 1, 0, 5, 6, 1, 0, 2, 3, 80, 0, 17, 1, 0, 0, 0, 2, 29, 1, 0, 0, 0, 4, 43, 1, 0, 0, 0, 6, 55, 1, 0, 0, 0, 8, 57, 1, 0, 0, 0, 10, 59, 1, 0, 0, 0, 12, 62, 1, 0, 0, 0, 14, 73, 1, 0, 0, 0, 16, 18, 5, 4, 0, 0, 17, 16, 1, 0, 0, 0, 17, 18, 1, 0, 0, 0, 18, 19, 1, 0, 0, 0, 19, 21, 3, 2, 1, 0, 20, 22, 5, 4, 0, 0, 21, 20, 1, 0, 0, 0, 21, 22, 1, 0, 0, 0, 22, 24, 1, 0, 0, 0, 23, 25, 3, 4, 2, 0, 24, 23, 1, 0, 0, 0, 24, 25, 1, 0, 0, 0, 25, 26, 1, 0, 0, 0, 26, 27, 5, 0, 0, 1, 27, 1, 1, 0, 0, 0, 28, 30, 3, 6, 3, 0, 29, 28, 1, 0, 0, 0, 29, 30, 1, 0, 0, 0, 30, 32, 1, 0, 0, 0, 31, 33, 5, 4, 0, 0, 32, 31, 1, 0, 0, 0, 32, 33, 1, 0, 0, 0, 33, 35, 1, 0, 0, 0, 34, 36, 3, 8, 4, 0, 35, 34, 1, 0, 0, 0, 35, 36, 1, 0, 0, 0, 36, 38, 1, 0, 0, 0, 37, 39, 5, 4, 0, 0, 38, 37, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 41, 1, 0, 0, 0, 40, 42, 3, 10, 5, 0, 41, 40, 1, 0, 0, 0, 41, 42, 1, 0, 0, 0, 42, 3, 1, 0, 0, 0, 43, 45, 3, 14, 7, 0, 44, 46, 5, 4, 0, 0, 45, 44, 1, 0, 0, 0, 45, 46, 1, 0, 0, 0, 46, 51, 1, 0, 0, 0, 47, 49, 3, 12, 6, 0, 48, 50, 5, 4, 0, 0, 49, 48, 1, 0, 0, 0, 49, 50, 1, 0, 0, 0, 50, 52, 1, 0, 0, 0, 51, 47, 1, 0, 0, 0, 52, 53, 1, 0, 0, 0, 53, 51, 1, 0, 0, 0, 53, 54, 1, 0, 0, 0, 54, 5, 1, 0, 0, 0, 55, 56, 3, 12, 6, 0, 56, 7, 1, 0, 0, 0, 57, 58, 5, 1, 0, 0, 58, 9, 1, 0, 0, 0, 59, 60, 3, 12, 6, 0, 60, 11, 1, 0, 0, 0, 61, 63, 5, 4, 0, 0, 62, 61, 1, 0, 0, 0, 62, 63, 1, 0, 0, 0, 63, 68, 1, 0, 0, 0, 64, 65, 7, 0, 0, 0, 65, 67, 5, 4, 0, 0, 66, 64, 1, 0, 0, 0, 67, 70, 1, 0, 0, 0, 68, 66, 1, 0, 0, 0, 68, 69, 1, 0, 0, 0, 69, 71, 1, 0, 0, 0, 70, 68, 1, 0, 0, 0, 71, 72, 7, 0, 0, 0, 72, 13, 1, 0, 0, 0, 73, 74, 7, 1, 0, 0, 74, 15, 1, 0, 0, 0, 13, 17, 21, 24, 29, 32, 35, 38, 41, 45, 49, 53, 62, 68] \ No newline at end of file diff --git a/server/handlers/gitconfig/ast/parser/config_parser.go b/server/handlers/gitconfig/ast/parser/config_parser.go index 7b6610b..b812506 100644 --- a/server/handlers/gitconfig/ast/parser/config_parser.go +++ b/server/handlers/gitconfig/ast/parser/config_parser.go @@ -44,39 +44,38 @@ func configParserInit() { } staticData.PredictionContextCache = antlr.NewPredictionContextCache() staticData.serializedATN = []int32{ - 4, 1, 6, 78, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, + 4, 1, 6, 76, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 1, 0, 3, 0, 18, 8, 0, 1, 0, 1, 0, 3, 0, 22, 8, 0, 1, 0, 3, 0, 25, 8, 0, 1, 0, 1, 0, 1, 1, 3, 1, 30, 8, 1, 1, 1, 3, 1, 33, 8, 1, 1, 1, 3, 1, 36, 8, 1, 1, 1, 3, 1, 39, 8, 1, 1, 1, 3, 1, 42, 8, 1, 1, 2, 1, 2, 3, 2, 46, 8, 2, 1, 2, 1, 2, 3, 2, 50, 8, 2, 4, 2, 52, 8, 2, 11, 2, 12, 2, 53, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, - 1, 6, 3, 6, 64, 8, 6, 1, 6, 1, 6, 5, 6, 68, 8, 6, 10, 6, 12, 6, 71, 9, - 6, 1, 6, 3, 6, 74, 8, 6, 1, 7, 1, 7, 1, 7, 0, 0, 8, 0, 2, 4, 6, 8, 10, - 12, 14, 0, 1, 1, 0, 2, 3, 83, 0, 17, 1, 0, 0, 0, 2, 29, 1, 0, 0, 0, 4, - 43, 1, 0, 0, 0, 6, 55, 1, 0, 0, 0, 8, 57, 1, 0, 0, 0, 10, 59, 1, 0, 0, - 0, 12, 73, 1, 0, 0, 0, 14, 75, 1, 0, 0, 0, 16, 18, 5, 4, 0, 0, 17, 16, - 1, 0, 0, 0, 17, 18, 1, 0, 0, 0, 18, 19, 1, 0, 0, 0, 19, 21, 3, 2, 1, 0, - 20, 22, 5, 4, 0, 0, 21, 20, 1, 0, 0, 0, 21, 22, 1, 0, 0, 0, 22, 24, 1, - 0, 0, 0, 23, 25, 3, 4, 2, 0, 24, 23, 1, 0, 0, 0, 24, 25, 1, 0, 0, 0, 25, - 26, 1, 0, 0, 0, 26, 27, 5, 0, 0, 1, 27, 1, 1, 0, 0, 0, 28, 30, 3, 6, 3, - 0, 29, 28, 1, 0, 0, 0, 29, 30, 1, 0, 0, 0, 30, 32, 1, 0, 0, 0, 31, 33, - 5, 4, 0, 0, 32, 31, 1, 0, 0, 0, 32, 33, 1, 0, 0, 0, 33, 35, 1, 0, 0, 0, - 34, 36, 3, 8, 4, 0, 35, 34, 1, 0, 0, 0, 35, 36, 1, 0, 0, 0, 36, 38, 1, - 0, 0, 0, 37, 39, 5, 4, 0, 0, 38, 37, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, - 41, 1, 0, 0, 0, 40, 42, 3, 10, 5, 0, 41, 40, 1, 0, 0, 0, 41, 42, 1, 0, - 0, 0, 42, 3, 1, 0, 0, 0, 43, 45, 3, 14, 7, 0, 44, 46, 5, 4, 0, 0, 45, 44, - 1, 0, 0, 0, 45, 46, 1, 0, 0, 0, 46, 51, 1, 0, 0, 0, 47, 49, 3, 12, 6, 0, - 48, 50, 5, 4, 0, 0, 49, 48, 1, 0, 0, 0, 49, 50, 1, 0, 0, 0, 50, 52, 1, - 0, 0, 0, 51, 47, 1, 0, 0, 0, 52, 53, 1, 0, 0, 0, 53, 51, 1, 0, 0, 0, 53, - 54, 1, 0, 0, 0, 54, 5, 1, 0, 0, 0, 55, 56, 3, 12, 6, 0, 56, 7, 1, 0, 0, - 0, 57, 58, 5, 1, 0, 0, 58, 9, 1, 0, 0, 0, 59, 60, 3, 12, 6, 0, 60, 11, - 1, 0, 0, 0, 61, 74, 5, 6, 0, 0, 62, 64, 5, 4, 0, 0, 63, 62, 1, 0, 0, 0, - 63, 64, 1, 0, 0, 0, 64, 69, 1, 0, 0, 0, 65, 66, 5, 5, 0, 0, 66, 68, 5, - 4, 0, 0, 67, 65, 1, 0, 0, 0, 68, 71, 1, 0, 0, 0, 69, 67, 1, 0, 0, 0, 69, - 70, 1, 0, 0, 0, 70, 72, 1, 0, 0, 0, 71, 69, 1, 0, 0, 0, 72, 74, 5, 5, 0, - 0, 73, 61, 1, 0, 0, 0, 73, 63, 1, 0, 0, 0, 74, 13, 1, 0, 0, 0, 75, 76, - 7, 0, 0, 0, 76, 15, 1, 0, 0, 0, 14, 17, 21, 24, 29, 32, 35, 38, 41, 45, - 49, 53, 63, 69, 73, + 3, 6, 63, 8, 6, 1, 6, 1, 6, 5, 6, 67, 8, 6, 10, 6, 12, 6, 70, 9, 6, 1, + 6, 1, 6, 1, 7, 1, 7, 1, 7, 0, 0, 8, 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 1, + 0, 5, 6, 1, 0, 2, 3, 80, 0, 17, 1, 0, 0, 0, 2, 29, 1, 0, 0, 0, 4, 43, 1, + 0, 0, 0, 6, 55, 1, 0, 0, 0, 8, 57, 1, 0, 0, 0, 10, 59, 1, 0, 0, 0, 12, + 62, 1, 0, 0, 0, 14, 73, 1, 0, 0, 0, 16, 18, 5, 4, 0, 0, 17, 16, 1, 0, 0, + 0, 17, 18, 1, 0, 0, 0, 18, 19, 1, 0, 0, 0, 19, 21, 3, 2, 1, 0, 20, 22, + 5, 4, 0, 0, 21, 20, 1, 0, 0, 0, 21, 22, 1, 0, 0, 0, 22, 24, 1, 0, 0, 0, + 23, 25, 3, 4, 2, 0, 24, 23, 1, 0, 0, 0, 24, 25, 1, 0, 0, 0, 25, 26, 1, + 0, 0, 0, 26, 27, 5, 0, 0, 1, 27, 1, 1, 0, 0, 0, 28, 30, 3, 6, 3, 0, 29, + 28, 1, 0, 0, 0, 29, 30, 1, 0, 0, 0, 30, 32, 1, 0, 0, 0, 31, 33, 5, 4, 0, + 0, 32, 31, 1, 0, 0, 0, 32, 33, 1, 0, 0, 0, 33, 35, 1, 0, 0, 0, 34, 36, + 3, 8, 4, 0, 35, 34, 1, 0, 0, 0, 35, 36, 1, 0, 0, 0, 36, 38, 1, 0, 0, 0, + 37, 39, 5, 4, 0, 0, 38, 37, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 41, 1, + 0, 0, 0, 40, 42, 3, 10, 5, 0, 41, 40, 1, 0, 0, 0, 41, 42, 1, 0, 0, 0, 42, + 3, 1, 0, 0, 0, 43, 45, 3, 14, 7, 0, 44, 46, 5, 4, 0, 0, 45, 44, 1, 0, 0, + 0, 45, 46, 1, 0, 0, 0, 46, 51, 1, 0, 0, 0, 47, 49, 3, 12, 6, 0, 48, 50, + 5, 4, 0, 0, 49, 48, 1, 0, 0, 0, 49, 50, 1, 0, 0, 0, 50, 52, 1, 0, 0, 0, + 51, 47, 1, 0, 0, 0, 52, 53, 1, 0, 0, 0, 53, 51, 1, 0, 0, 0, 53, 54, 1, + 0, 0, 0, 54, 5, 1, 0, 0, 0, 55, 56, 3, 12, 6, 0, 56, 7, 1, 0, 0, 0, 57, + 58, 5, 1, 0, 0, 58, 9, 1, 0, 0, 0, 59, 60, 3, 12, 6, 0, 60, 11, 1, 0, 0, + 0, 61, 63, 5, 4, 0, 0, 62, 61, 1, 0, 0, 0, 62, 63, 1, 0, 0, 0, 63, 68, + 1, 0, 0, 0, 64, 65, 7, 0, 0, 0, 65, 67, 5, 4, 0, 0, 66, 64, 1, 0, 0, 0, + 67, 70, 1, 0, 0, 0, 68, 66, 1, 0, 0, 0, 68, 69, 1, 0, 0, 0, 69, 71, 1, + 0, 0, 0, 70, 68, 1, 0, 0, 0, 71, 72, 7, 0, 0, 0, 72, 13, 1, 0, 0, 0, 73, + 74, 7, 1, 0, 0, 74, 15, 1, 0, 0, 0, 13, 17, 21, 24, 29, 32, 35, 38, 41, + 45, 49, 53, 62, 68, } deserializer := antlr.NewATNDeserializer(nil) staticData.atn = deserializer.Deserialize(staticData.serializedATN) @@ -1068,9 +1067,10 @@ type IStringContext interface { GetParser() antlr.Parser // Getter signatures - QUOTED_STRING() antlr.TerminalNode AllSTRING() []antlr.TerminalNode STRING(i int) antlr.TerminalNode + AllQUOTED_STRING() []antlr.TerminalNode + QUOTED_STRING(i int) antlr.TerminalNode AllWHITESPACE() []antlr.TerminalNode WHITESPACE(i int) antlr.TerminalNode @@ -1110,10 +1110,6 @@ func NewStringContext(parser antlr.Parser, parent antlr.ParserRuleContext, invok func (s *StringContext) GetParser() antlr.Parser { return s.parser } -func (s *StringContext) QUOTED_STRING() antlr.TerminalNode { - return s.GetToken(ConfigParserQUOTED_STRING, 0) -} - func (s *StringContext) AllSTRING() []antlr.TerminalNode { return s.GetTokens(ConfigParserSTRING) } @@ -1122,6 +1118,14 @@ func (s *StringContext) STRING(i int) antlr.TerminalNode { return s.GetToken(ConfigParserSTRING, i) } +func (s *StringContext) AllQUOTED_STRING() []antlr.TerminalNode { + return s.GetTokens(ConfigParserQUOTED_STRING) +} + +func (s *StringContext) QUOTED_STRING(i int) antlr.TerminalNode { + return s.GetToken(ConfigParserQUOTED_STRING, i) +} + func (s *StringContext) AllWHITESPACE() []antlr.TerminalNode { return s.GetTokens(ConfigParserWHITESPACE) } @@ -1158,34 +1162,48 @@ func (p *ConfigParser) String_() (localctx IStringContext) { var _alt int p.EnterOuterAlt(localctx, 1) - p.SetState(73) + p.SetState(62) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit } + _la = p.GetTokenStream().LA(1) - switch p.GetTokenStream().LA(1) { - case ConfigParserQUOTED_STRING: + if _la == ConfigParserWHITESPACE { { p.SetState(61) - p.Match(ConfigParserQUOTED_STRING) + p.Match(ConfigParserWHITESPACE) if p.HasError() { // Recognition error - abort rule goto errorExit } } - case ConfigParserWHITESPACE, ConfigParserSTRING: - p.SetState(63) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == ConfigParserWHITESPACE { + } + p.SetState(68) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 12, p.GetParserRuleContext()) + if p.HasError() { + goto errorExit + } + for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { + if _alt == 1 { { - p.SetState(62) + p.SetState(64) + _la = p.GetTokenStream().LA(1) + + if !(_la == ConfigParserSTRING || _la == ConfigParserQUOTED_STRING) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + { + p.SetState(65) p.Match(ConfigParserWHITESPACE) if p.HasError() { // Recognition error - abort rule @@ -1194,7 +1212,7 @@ func (p *ConfigParser) String_() (localctx IStringContext) { } } - p.SetState(69) + p.SetState(70) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -1203,48 +1221,17 @@ func (p *ConfigParser) String_() (localctx IStringContext) { if p.HasError() { goto errorExit } - for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { - if _alt == 1 { - { - p.SetState(65) - p.Match(ConfigParserSTRING) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(66) - p.Match(ConfigParserWHITESPACE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } + } + { + p.SetState(71) + _la = p.GetTokenStream().LA(1) - } - p.SetState(71) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 12, p.GetParserRuleContext()) - if p.HasError() { - goto errorExit - } + if !(_la == ConfigParserSTRING || _la == ConfigParserQUOTED_STRING) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() } - { - p.SetState(72) - p.Match(ConfigParserSTRING) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - default: - p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) - goto errorExit } errorExit: @@ -1342,7 +1329,7 @@ func (p *ConfigParser) CommentSymbol() (localctx ICommentSymbolContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(75) + p.SetState(73) _la = p.GetTokenStream().LA(1) if !(_la == ConfigParserHASH || _la == ConfigParserSEMICOLON) { diff --git a/server/handlers/gitconfig/ast/parser_test.go b/server/handlers/gitconfig/ast/parser_test.go index bdeb887..eb3b45c 100644 --- a/server/handlers/gitconfig/ast/parser_test.go +++ b/server/handlers/gitconfig/ast/parser_test.go @@ -136,3 +136,39 @@ bare = false t.Fatalf("Expected 1 error, got %d", len(errors)) } } + +func TestLeadingLine(t *testing.T) { + input := utils.Dedent(` +[core] + command = git \ + commit \ + -m "Hello World" +`) + + config := NewGitConfig() + errors := config.Parse(input) + + if len(errors) > 0 { + t.Fatalf("Expected no errors, got %v", errors) + } + + if len(config.Sections) != 1 { + t.Fatalf("Expected 1 section, got %d", len(config.Sections)) + } + + section := config.Sections[0] + + if !(section.Title.Title == "core") { + t.Errorf("Expected core, got %s", section.Title.Title) + } + + rawFirstOption, _ := section.Entries.Get(uint32(1)) + firstOption := rawFirstOption.(*GitEntry) + if !(firstOption.Key.Value.Value == "command" && firstOption.Value.Value == "git commit -m Hello World") { + t.Errorf("Expected command, got %s", firstOption.Key.Value.Value) + } + + if !(firstOption.Value.Raw.Parts[0].Text == "git " && firstOption.Value.Raw.Parts[1].Text == "\t\tcommit " && firstOption.Value.Raw.Parts[2].Text == "\t\t-m \"Hello World\"") { + t.Errorf("Expected command, got %s", firstOption.Value.Raw.Parts) + } +}