diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | patterns.go | 86 | ||||
| -rw-r--r-- | rewrite.go | 10 |
3 files changed, 85 insertions, 13 deletions
@@ -1,3 +1,3 @@ -iku +iku* result .task diff --git a/patterns.go b/patterns.go index 5cd35ca..4bd2b57 100644 --- a/patterns.go +++ b/patterns.go @@ -1,18 +1,90 @@ package main -import "regexp" +func isWhitespace(character byte) bool { + return character == ' ' || character == '\t' || character == '\n' || character == '\r' || character == '\f' +} + +func isClosingBrace(sourceLine string) bool { + for characterIndex := 0; characterIndex < len(sourceLine); characterIndex++ { + character := sourceLine[characterIndex] + + if isWhitespace(character) { + continue + } + + return character == '}' || character == ')' + } + + return false +} -var ( - closingBracePattern = regexp.MustCompile(`^\s*[\}\)]`) - openingBracePattern = regexp.MustCompile(`[\{\(]\s*$`) - caseLabelPattern = regexp.MustCompile(`^\s*(case\s|default\s*:)|(^\s+.*:\s*$)`) -) +func isOpeningBrace(sourceLine string) bool { + for characterIndex := len(sourceLine) - 1; characterIndex >= 0; characterIndex-- { + character := sourceLine[characterIndex] + + if isWhitespace(character) { + continue + } + + return character == '{' || character == '(' + } + + return false +} + +func isCaseLabel(sourceLine string) bool { + firstNonWhitespaceIndex := 0 + + for firstNonWhitespaceIndex < len(sourceLine) && isWhitespace(sourceLine[firstNonWhitespaceIndex]) { + firstNonWhitespaceIndex++ + } + + if firstNonWhitespaceIndex >= len(sourceLine) { + return false + } + + contentAfterWhitespace := sourceLine[firstNonWhitespaceIndex:] + + if len(contentAfterWhitespace) >= 5 && contentAfterWhitespace[:4] == "case" && isWhitespace(contentAfterWhitespace[4]) { + return true + } + + if len(contentAfterWhitespace) >= 7 && contentAfterWhitespace[:7] == "default" { + for characterIndex := 7; characterIndex < len(contentAfterWhitespace); characterIndex++ { + character := contentAfterWhitespace[characterIndex] + + if isWhitespace(character) { + continue + } + + if character == ':' { + return true + } + + break + } + } + + if firstNonWhitespaceIndex > 0 { + lastNonWhitespaceIndex := len(sourceLine) - 1 + + for lastNonWhitespaceIndex >= 0 && isWhitespace(sourceLine[lastNonWhitespaceIndex]) { + lastNonWhitespaceIndex-- + } + + if lastNonWhitespaceIndex >= 0 && sourceLine[lastNonWhitespaceIndex] == ':' { + return true + } + } + + return false +} func isCommentOnly(sourceLine string) bool { for characterIndex := range len(sourceLine) { character := sourceLine[characterIndex] - if character == ' ' || character == '\t' { + if isWhitespace(character) { continue } @@ -33,9 +33,9 @@ func (f *Formatter) rewrite(formattedSource []byte, lineInformationMap map[int]* continue } - isClosingBrace := closingBracePattern.MatchString(currentLine) - isOpeningBrace := openingBracePattern.MatchString(currentLine) - isCaseLabel := caseLabelPattern.MatchString(currentLine) + isClosingBraceLine := isClosingBrace(currentLine) + isOpeningBraceLine := isOpeningBrace(currentLine) + isCaseLabelLine := isCaseLabel(currentLine) isCommentOnlyLine := isCommentOnly(currentLine) isPackageDeclaration := isPackageLine(trimmedLine) currentInformation := lineInformationMap[lineNumber] @@ -53,7 +53,7 @@ func (f *Formatter) rewrite(formattedSource []byte, lineInformationMap map[int]* currentIsTopLevel := currentInformation != nil && currentInformation.isTopLevel currentIsScoped := currentInformation != nil && currentInformation.isScoped - if len(resultLines) > 0 && !previousWasOpenBrace && !isClosingBrace && !isCaseLabel { + if len(resultLines) > 0 && !previousWasOpenBrace && !isClosingBraceLine && !isCaseLabelLine { if currentIsTopLevel && previousWasTopLevel && currentStatementType != previousStatementType { if f.CommentMode == CommentsFollow && previousWasComment { } else { @@ -98,7 +98,7 @@ func (f *Formatter) rewrite(formattedSource []byte, lineInformationMap map[int]* } resultLines = append(resultLines, currentLine) - previousWasOpenBrace = isOpeningBrace || isCaseLabel + previousWasOpenBrace = isOpeningBraceLine || isCaseLabelLine previousWasComment = isCommentOnlyLine if currentInformation != nil { |