diff options
| -rw-r--r-- | formatter.go | 292 | ||||
| -rw-r--r-- | formatter_bench_test.go | 48 | ||||
| -rw-r--r-- | formatter_test.go | 192 | ||||
| -rw-r--r-- | main.go | 90 |
4 files changed, 311 insertions, 311 deletions
diff --git a/formatter.go b/formatter.go index 2ac28b5..c03896e 100644 --- a/formatter.go +++ b/formatter.go @@ -16,78 +16,78 @@ var ( caseLabelPattern = regexp.MustCompile(`^\s*(case\s|default\s*:)|(^\s+.*:\s*$)`) ) -func isCommentOnly(line string) bool { - for index := range len(line) { - character := line[index] +func isCommentOnly(sourceLine string) bool { + for characterIndex := range len(sourceLine) { + character := sourceLine[characterIndex] if character == ' ' || character == '\t' { continue } - return len(line) > index+1 && line[index] == '/' && line[index+1] == '/' + return len(sourceLine) > characterIndex+1 && sourceLine[characterIndex] == '/' && sourceLine[characterIndex+1] == '/' } return false } -func isPackageLine(trimmed string) bool { - return len(trimmed) > 8 && trimmed[:8] == "package " +func isPackageLine(trimmedLine string) bool { + return len(trimmedLine) > 8 && trimmedLine[:8] == "package " } -func countRawStringDelimiters(line string) int { - count := 0 - inString := false - inCharacter := false +func countRawStringDelimiters(sourceLine string) int { + delimiterCount := 0 + insideDoubleQuotedString := false + insideCharacterLiteral := false - for index := 0; index < len(line); index++ { - character := line[index] + for characterIndex := 0; characterIndex < len(sourceLine); characterIndex++ { + character := sourceLine[characterIndex] - if inCharacter { - if character == '\\' && index+1 < len(line) { - index++ + if insideCharacterLiteral { + if character == '\\' && characterIndex+1 < len(sourceLine) { + characterIndex++ continue } if character == '\'' { - inCharacter = false + insideCharacterLiteral = false } continue } - if inString { - if character == '\\' && index+1 < len(line) { - index++ + if insideDoubleQuotedString { + if character == '\\' && characterIndex+1 < len(sourceLine) { + characterIndex++ continue } if character == '"' { - inString = false + insideDoubleQuotedString = false } continue } if character == '\'' { - inCharacter = true + insideCharacterLiteral = true continue } if character == '"' { - inString = true + insideDoubleQuotedString = true continue } if character == '`' { - count++ + delimiterCount++ } } - return count + return delimiterCount } type CommentMode int @@ -102,7 +102,7 @@ type Formatter struct { CommentMode CommentMode } -type lineInfo struct { +type lineInformation struct { statementType string isTopLevel bool isScoped bool @@ -110,28 +110,28 @@ type lineInfo struct { } func (f *Formatter) Format(source []byte) ([]byte, error) { - formatted, err := format.Source(source) + formattedSource, err := format.Source(source) if err != nil { return nil, err } - fileSet := token.NewFileSet() - file, err := parser.ParseFile(fileSet, "", formatted, parser.ParseComments) + tokenFileSet := token.NewFileSet() + parsedFile, err := parser.ParseFile(tokenFileSet, "", formattedSource, parser.ParseComments) if err != nil { return nil, err } - lineInfoMap := f.buildLineInfo(fileSet, file) + lineInformationMap := f.buildLineInfo(tokenFileSet, parsedFile) - return f.rewrite(formatted, lineInfoMap), nil + return f.rewrite(formattedSource, lineInformationMap), nil } -func isGenDeclScoped(genDecl *ast.GenDecl) bool { - for _, spec := range genDecl.Specs { - if typeSpec, ok := spec.(*ast.TypeSpec); ok { - switch typeSpec.Type.(type) { +func isGeneralDeclarationScoped(generalDeclaration *ast.GenDecl) bool { + for _, specification := range generalDeclaration.Specs { + if typeSpecification, isTypeSpecification := specification.(*ast.TypeSpec); isTypeSpecification { + switch typeSpecification.Type.(type) { case *ast.StructType, *ast.InterfaceType: return true } @@ -141,162 +141,162 @@ func isGenDeclScoped(genDecl *ast.GenDecl) bool { return false } -func (f *Formatter) buildLineInfo(fileSet *token.FileSet, file *ast.File) map[int]*lineInfo { - lineInfoMap := make(map[int]*lineInfo) - tokenFile := fileSet.File(file.Pos()) +func (f *Formatter) buildLineInfo(tokenFileSet *token.FileSet, parsedFile *ast.File) map[int]*lineInformation { + lineInformationMap := make(map[int]*lineInformation) + tokenFile := tokenFileSet.File(parsedFile.Pos()) if tokenFile == nil { - return lineInfoMap + return lineInformationMap } - for _, declaration := range file.Decls { + for _, declaration := range parsedFile.Decls { startLine := tokenFile.Line(declaration.Pos()) endLine := tokenFile.Line(declaration.End()) - typeName := "" + statementType := "" isScoped := false - switch declarationType := declaration.(type) { + switch typedDeclaration := declaration.(type) { case *ast.GenDecl: - typeName = declarationType.Tok.String() - isScoped = isGenDeclScoped(declarationType) + statementType = typedDeclaration.Tok.String() + isScoped = isGeneralDeclarationScoped(typedDeclaration) case *ast.FuncDecl: - typeName = "func" + statementType = "func" isScoped = true default: - typeName = reflect.TypeOf(declaration).String() + statementType = reflect.TypeOf(declaration).String() } - lineInfoMap[startLine] = &lineInfo{statementType: typeName, isTopLevel: true, isScoped: isScoped, isStartLine: true} - lineInfoMap[endLine] = &lineInfo{statementType: typeName, isTopLevel: true, isScoped: isScoped, isStartLine: false} + lineInformationMap[startLine] = &lineInformation{statementType: statementType, isTopLevel: true, isScoped: isScoped, isStartLine: true} + lineInformationMap[endLine] = &lineInformation{statementType: statementType, isTopLevel: true, isScoped: isScoped, isStartLine: false} } - ast.Inspect(file, func(node ast.Node) bool { - if node == nil { + ast.Inspect(parsedFile, func(astNode ast.Node) bool { + if astNode == nil { return true } - switch typedNode := node.(type) { + switch typedNode := astNode.(type) { case *ast.BlockStmt: - f.processBlock(tokenFile, typedNode, lineInfoMap) + f.processBlock(tokenFile, typedNode, lineInformationMap) case *ast.CaseClause: - f.processStatementList(tokenFile, typedNode.Body, lineInfoMap) + f.processStatementList(tokenFile, typedNode.Body, lineInformationMap) case *ast.CommClause: - f.processStatementList(tokenFile, typedNode.Body, lineInfoMap) + f.processStatementList(tokenFile, typedNode.Body, lineInformationMap) } return true }) - return lineInfoMap + return lineInformationMap } -func (f *Formatter) processBlock(tokenFile *token.File, block *ast.BlockStmt, lineInfoMap map[int]*lineInfo) { - if block == nil { +func (f *Formatter) processBlock(tokenFile *token.File, blockStatement *ast.BlockStmt, lineInformationMap map[int]*lineInformation) { + if blockStatement == nil { return } - f.processStatementList(tokenFile, block.List, lineInfoMap) + f.processStatementList(tokenFile, blockStatement.List, lineInformationMap) } -func (f *Formatter) processStatementList(tokenFile *token.File, statements []ast.Stmt, lineInfoMap map[int]*lineInfo) { +func (f *Formatter) processStatementList(tokenFile *token.File, statements []ast.Stmt, lineInformationMap map[int]*lineInformation) { for _, statement := range statements { startLine := tokenFile.Line(statement.Pos()) endLine := tokenFile.Line(statement.End()) - typeName := "" + statementType := "" isScoped := false - switch statementType := statement.(type) { + switch typedStatement := statement.(type) { case *ast.DeclStmt: - if genericDeclaration, ok := statementType.Decl.(*ast.GenDecl); ok { - typeName = genericDeclaration.Tok.String() + if generalDeclaration, isGeneralDeclaration := typedStatement.Decl.(*ast.GenDecl); isGeneralDeclaration { + statementType = generalDeclaration.Tok.String() } else { - typeName = reflect.TypeOf(statement).String() + statementType = reflect.TypeOf(statement).String() } case *ast.IfStmt, *ast.ForStmt, *ast.RangeStmt, *ast.SwitchStmt, *ast.TypeSwitchStmt, *ast.SelectStmt, *ast.BlockStmt: - typeName = reflect.TypeOf(statement).String() + statementType = reflect.TypeOf(statement).String() isScoped = true default: - typeName = reflect.TypeOf(statement).String() + statementType = reflect.TypeOf(statement).String() } - existingStart := lineInfoMap[startLine] + existingStart := lineInformationMap[startLine] if existingStart == nil || !existingStart.isStartLine { - lineInfoMap[startLine] = &lineInfo{statementType: typeName, isTopLevel: false, isScoped: isScoped, isStartLine: true} + lineInformationMap[startLine] = &lineInformation{statementType: statementType, isTopLevel: false, isScoped: isScoped, isStartLine: true} } - existingEnd := lineInfoMap[endLine] + existingEnd := lineInformationMap[endLine] if existingEnd == nil || !existingEnd.isStartLine { - lineInfoMap[endLine] = &lineInfo{statementType: typeName, isTopLevel: false, isScoped: isScoped, isStartLine: false} + lineInformationMap[endLine] = &lineInformation{statementType: statementType, isTopLevel: false, isScoped: isScoped, isStartLine: false} } switch typedStatement := statement.(type) { case *ast.IfStmt: - f.processBlock(tokenFile, typedStatement.Body, lineInfoMap) + f.processBlock(tokenFile, typedStatement.Body, lineInformationMap) if typedStatement.Else != nil { if elseBlock, isBlockStatement := typedStatement.Else.(*ast.BlockStmt); isBlockStatement { - f.processBlock(tokenFile, elseBlock, lineInfoMap) + f.processBlock(tokenFile, elseBlock, lineInformationMap) } else if elseIfStatement, isIfStatement := typedStatement.Else.(*ast.IfStmt); isIfStatement { - f.processIfStatement(tokenFile, elseIfStatement, lineInfoMap) + f.processIfStatement(tokenFile, elseIfStatement, lineInformationMap) } } case *ast.ForStmt: - f.processBlock(tokenFile, typedStatement.Body, lineInfoMap) + f.processBlock(tokenFile, typedStatement.Body, lineInformationMap) case *ast.RangeStmt: - f.processBlock(tokenFile, typedStatement.Body, lineInfoMap) + f.processBlock(tokenFile, typedStatement.Body, lineInformationMap) case *ast.SwitchStmt: - f.processBlock(tokenFile, typedStatement.Body, lineInfoMap) + f.processBlock(tokenFile, typedStatement.Body, lineInformationMap) case *ast.TypeSwitchStmt: - f.processBlock(tokenFile, typedStatement.Body, lineInfoMap) + f.processBlock(tokenFile, typedStatement.Body, lineInformationMap) case *ast.SelectStmt: - f.processBlock(tokenFile, typedStatement.Body, lineInfoMap) + f.processBlock(tokenFile, typedStatement.Body, lineInformationMap) case *ast.BlockStmt: - f.processBlock(tokenFile, typedStatement, lineInfoMap) + f.processBlock(tokenFile, typedStatement, lineInformationMap) } } } -func (f *Formatter) processIfStatement(tokenFile *token.File, ifStatement *ast.IfStmt, lineInfoMap map[int]*lineInfo) { +func (f *Formatter) processIfStatement(tokenFile *token.File, ifStatement *ast.IfStmt, lineInformationMap map[int]*lineInformation) { startLine := tokenFile.Line(ifStatement.Pos()) endLine := tokenFile.Line(ifStatement.End()) - existingStart := lineInfoMap[startLine] + existingStart := lineInformationMap[startLine] if existingStart == nil || !existingStart.isStartLine { - lineInfoMap[startLine] = &lineInfo{statementType: "*ast.IfStmt", isTopLevel: false, isScoped: true, isStartLine: true} + lineInformationMap[startLine] = &lineInformation{statementType: "*ast.IfStmt", isTopLevel: false, isScoped: true, isStartLine: true} } - existingEnd := lineInfoMap[endLine] + existingEnd := lineInformationMap[endLine] if existingEnd == nil || !existingEnd.isStartLine { - lineInfoMap[endLine] = &lineInfo{statementType: "*ast.IfStmt", isTopLevel: false, isScoped: true, isStartLine: false} + lineInformationMap[endLine] = &lineInformation{statementType: "*ast.IfStmt", isTopLevel: false, isScoped: true, isStartLine: false} } - f.processBlock(tokenFile, ifStatement.Body, lineInfoMap) + f.processBlock(tokenFile, ifStatement.Body, lineInformationMap) if ifStatement.Else != nil { if elseBlock, isBlockStatement := ifStatement.Else.(*ast.BlockStmt); isBlockStatement { - f.processBlock(tokenFile, elseBlock, lineInfoMap) + f.processBlock(tokenFile, elseBlock, lineInformationMap) } else if elseIfStatement, isIfStatement := ifStatement.Else.(*ast.IfStmt); isIfStatement { - f.processIfStatement(tokenFile, elseIfStatement, lineInfoMap) + f.processIfStatement(tokenFile, elseIfStatement, lineInformationMap) } } } -func (f *Formatter) rewrite(source []byte, lineInfoMap map[int]*lineInfo) []byte { - lines := strings.Split(string(source), "\n") - result := make([]string, 0, len(lines)) +func (f *Formatter) rewrite(formattedSource []byte, lineInformationMap map[int]*lineInformation) []byte { + sourceLines := strings.Split(string(formattedSource), "\n") + resultLines := make([]string, 0, len(sourceLines)) previousWasOpenBrace := false - previousType := "" + previousStatementType := "" previousWasComment := false previousWasTopLevel := false previousWasScoped := false insideRawString := false - for index, line := range lines { - backtickCount := countRawStringDelimiters(line) + for lineIndex, currentLine := range sourceLines { + backtickCount := countRawStringDelimiters(currentLine) wasInsideRawString := insideRawString if backtickCount%2 == 1 { @@ -304,119 +304,119 @@ func (f *Formatter) rewrite(source []byte, lineInfoMap map[int]*lineInfo) []byte } if wasInsideRawString { - result = append(result, line) + resultLines = append(resultLines, currentLine) continue } - lineNumber := index + 1 - trimmed := strings.TrimSpace(line) + lineNumber := lineIndex + 1 + trimmedLine := strings.TrimSpace(currentLine) - if trimmed == "" { + if trimmedLine == "" { continue } - isClosingBrace := closingBracePattern.MatchString(line) - isOpeningBrace := openingBracePattern.MatchString(line) - isCaseLabel := caseLabelPattern.MatchString(line) - isCommentOnlyLine := isCommentOnly(line) - isPackageLine := isPackageLine(trimmed) - info := lineInfoMap[lineNumber] - currentType := "" + isClosingBrace := closingBracePattern.MatchString(currentLine) + isOpeningBrace := openingBracePattern.MatchString(currentLine) + isCaseLabel := caseLabelPattern.MatchString(currentLine) + isCommentOnlyLine := isCommentOnly(currentLine) + isPackageDeclaration := isPackageLine(trimmedLine) + currentInformation := lineInformationMap[lineNumber] + currentStatementType := "" - if info != nil { - currentType = info.statementType + if currentInformation != nil { + currentStatementType = currentInformation.statementType } - if isPackageLine { - currentType = "package" + if isPackageDeclaration { + currentStatementType = "package" } - needsBlank := false - currentIsTopLevel := info != nil && info.isTopLevel - currentIsScoped := info != nil && info.isScoped + needsBlankLine := false + currentIsTopLevel := currentInformation != nil && currentInformation.isTopLevel + currentIsScoped := currentInformation != nil && currentInformation.isScoped - if len(result) > 0 && !previousWasOpenBrace && !isClosingBrace && !isCaseLabel { - if currentIsTopLevel && previousWasTopLevel && currentType != previousType { + if len(resultLines) > 0 && !previousWasOpenBrace && !isClosingBrace && !isCaseLabel { + if currentIsTopLevel && previousWasTopLevel && currentStatementType != previousStatementType { if f.CommentMode == CommentsFollow && previousWasComment { } else { - needsBlank = true + needsBlankLine = true } - } else if info != nil && (currentIsScoped || previousWasScoped) { + } else if currentInformation != nil && (currentIsScoped || previousWasScoped) { if f.CommentMode == CommentsFollow && previousWasComment { } else { - needsBlank = true + needsBlankLine = true } - } else if currentType != "" && previousType != "" && currentType != previousType { + } else if currentStatementType != "" && previousStatementType != "" && currentStatementType != previousStatementType { if f.CommentMode == CommentsFollow && previousWasComment { } else { - needsBlank = true + needsBlankLine = true } } if f.CommentMode == CommentsFollow && isCommentOnlyLine && !previousWasComment { - nextLineNumber := f.findNextNonCommentLine(lines, index+1) + nextLineNumber := f.findNextNonCommentLine(sourceLines, lineIndex+1) if nextLineNumber > 0 { - nextInfo := lineInfoMap[nextLineNumber] + nextInformation := lineInformationMap[nextLineNumber] - if nextInfo != nil { - nextIsTopLevel := nextInfo.isTopLevel - nextIsScoped := nextInfo.isScoped + if nextInformation != nil { + nextIsTopLevel := nextInformation.isTopLevel + nextIsScoped := nextInformation.isScoped - if nextIsTopLevel && previousWasTopLevel && nextInfo.statementType != previousType { - needsBlank = true + if nextIsTopLevel && previousWasTopLevel && nextInformation.statementType != previousStatementType { + needsBlankLine = true } else if nextIsScoped || previousWasScoped { - needsBlank = true - } else if nextInfo.statementType != "" && previousType != "" && nextInfo.statementType != previousType { - needsBlank = true + needsBlankLine = true + } else if nextInformation.statementType != "" && previousStatementType != "" && nextInformation.statementType != previousStatementType { + needsBlankLine = true } } } } } - if needsBlank { - result = append(result, "") + if needsBlankLine { + resultLines = append(resultLines, "") } - result = append(result, line) + resultLines = append(resultLines, currentLine) previousWasOpenBrace = isOpeningBrace || isCaseLabel previousWasComment = isCommentOnlyLine - if info != nil { - previousType = info.statementType - previousWasTopLevel = info.isTopLevel - previousWasScoped = info.isScoped - } else if currentType != "" { - previousType = currentType + if currentInformation != nil { + previousStatementType = currentInformation.statementType + previousWasTopLevel = currentInformation.isTopLevel + previousWasScoped = currentInformation.isScoped + } else if currentStatementType != "" { + previousStatementType = currentStatementType previousWasTopLevel = false previousWasScoped = false } } - output := strings.Join(result, "\n") + outputString := strings.Join(resultLines, "\n") - if !strings.HasSuffix(output, "\n") { - output += "\n" + if !strings.HasSuffix(outputString, "\n") { + outputString += "\n" } - return []byte(output) + return []byte(outputString) } -func (f *Formatter) findNextNonCommentLine(lines []string, startIndex int) int { - for index := startIndex; index < len(lines); index++ { - trimmed := strings.TrimSpace(lines[index]) +func (f *Formatter) findNextNonCommentLine(sourceLines []string, startLineIndex int) int { + for lineIndex := startLineIndex; lineIndex < len(sourceLines); lineIndex++ { + trimmedLine := strings.TrimSpace(sourceLines[lineIndex]) - if trimmed == "" { + if trimmedLine == "" { continue } - if isCommentOnly(lines[index]) { + if isCommentOnly(sourceLines[lineIndex]) { continue } - return index + 1 + return lineIndex + 1 } return 0 diff --git a/formatter_bench_test.go b/formatter_bench_test.go index 53f607b..2a6d3cd 100644 --- a/formatter_bench_test.go +++ b/formatter_bench_test.go @@ -5,8 +5,8 @@ import ( "testing" ) -func BenchmarkFormat_Small(b *testing.B) { - input := []byte(`package main +func BenchmarkFormat_Small(benchmarkRunner *testing.B) { + inputSource := []byte(`package main func main() { x := 1 y := 2 @@ -16,34 +16,34 @@ func main() { a := 4 } `) - f := &Formatter{CommentMode: CommentsFollow} + formatter := &Formatter{CommentMode: CommentsFollow} - for b.Loop() { - _, _ = f.Format(input) + for benchmarkRunner.Loop() { + _, _ = formatter.Format(inputSource) } } -func BenchmarkFormat_Large(b *testing.B) { - var sb strings.Builder - - sb.WriteString("package main\n\n") - - for i := range 100 { - sb.WriteString("func foo") - sb.WriteString(string(rune('A' + i%26))) - sb.WriteString("() {\n") - sb.WriteString("\tx := 1\n") - sb.WriteString("\tif x > 0 {\n") - sb.WriteString("\t\ty := 2\n") - sb.WriteString("\t}\n") - sb.WriteString("\tz := 3\n") - sb.WriteString("}\n\n") +func BenchmarkFormat_Large(benchmarkRunner *testing.B) { + var sourceBuilder strings.Builder + + sourceBuilder.WriteString("package main\n\n") + + for functionIndex := range 100 { + sourceBuilder.WriteString("func foo") + sourceBuilder.WriteString(string(rune('A' + functionIndex%26))) + sourceBuilder.WriteString("() {\n") + sourceBuilder.WriteString("\tx := 1\n") + sourceBuilder.WriteString("\tif x > 0 {\n") + sourceBuilder.WriteString("\t\ty := 2\n") + sourceBuilder.WriteString("\t}\n") + sourceBuilder.WriteString("\tz := 3\n") + sourceBuilder.WriteString("}\n\n") } - input := []byte(sb.String()) - f := &Formatter{CommentMode: CommentsFollow} + inputSource := []byte(sourceBuilder.String()) + formatter := &Formatter{CommentMode: CommentsFollow} - for b.Loop() { - _, _ = f.Format(input) + for benchmarkRunner.Loop() { + _, _ = formatter.Format(inputSource) } } diff --git a/formatter_test.go b/formatter_test.go index e88d9f5..eadcbae 100644 --- a/formatter_test.go +++ b/formatter_test.go @@ -4,8 +4,8 @@ import ( "testing" ) -func TestFormat_RemovesExtraBlankLines(t *testing.T) { - input := `package main +func TestFormat_RemovesExtraBlankLines(testRunner *testing.T) { + inputSource := `package main func main() { x := 1 @@ -14,27 +14,27 @@ func main() { y := 2 } ` - expected := `package main + expectedOutput := `package main func main() { x := 1 y := 2 } ` - f := &Formatter{CommentMode: CommentsFollow} - result, err := f.Format([]byte(input)) + formatter := &Formatter{CommentMode: CommentsFollow} + formattedResult, err := formatter.Format([]byte(inputSource)) if err != nil { - t.Fatalf("Format error: %v", err) + testRunner.Fatalf("Format error: %v", err) } - if string(result) != expected { - t.Errorf("got:\n%s\nwant:\n%s", result, expected) + if string(formattedResult) != expectedOutput { + testRunner.Errorf("got:\n%s\nwant:\n%s", formattedResult, expectedOutput) } } -func TestFormat_AddsBlankLineAroundScopedStatements(t *testing.T) { - input := `package main +func TestFormat_AddsBlankLineAroundScopedStatements(testRunner *testing.T) { + inputSource := `package main func main() { x := 1 @@ -44,7 +44,7 @@ func main() { z := 3 } ` - expected := `package main + expectedOutput := `package main func main() { x := 1 @@ -56,20 +56,20 @@ func main() { z := 3 } ` - f := &Formatter{CommentMode: CommentsFollow} - result, err := f.Format([]byte(input)) + formatter := &Formatter{CommentMode: CommentsFollow} + formattedResult, err := formatter.Format([]byte(inputSource)) if err != nil { - t.Fatalf("Format error: %v", err) + testRunner.Fatalf("Format error: %v", err) } - if string(result) != expected { - t.Errorf("got:\n%s\nwant:\n%s", result, expected) + if string(formattedResult) != expectedOutput { + testRunner.Errorf("got:\n%s\nwant:\n%s", formattedResult, expectedOutput) } } -func TestFormat_NestedScopes(t *testing.T) { - input := `package main +func TestFormat_NestedScopes(testRunner *testing.T) { + inputSource := `package main func main() { if true { @@ -81,7 +81,7 @@ func main() { } } ` - expected := `package main + expectedOutput := `package main func main() { if true { @@ -95,20 +95,20 @@ func main() { } } ` - f := &Formatter{CommentMode: CommentsFollow} - result, err := f.Format([]byte(input)) + formatter := &Formatter{CommentMode: CommentsFollow} + formattedResult, err := formatter.Format([]byte(inputSource)) if err != nil { - t.Fatalf("Format error: %v", err) + testRunner.Fatalf("Format error: %v", err) } - if string(result) != expected { - t.Errorf("got:\n%s\nwant:\n%s", result, expected) + if string(formattedResult) != expectedOutput { + testRunner.Errorf("got:\n%s\nwant:\n%s", formattedResult, expectedOutput) } } -func TestFormat_ForLoop(t *testing.T) { - input := `package main +func TestFormat_ForLoop(testRunner *testing.T) { + inputSource := `package main func main() { x := 1 @@ -118,7 +118,7 @@ func main() { z := 2 } ` - expected := `package main + expectedOutput := `package main func main() { x := 1 @@ -130,20 +130,20 @@ func main() { z := 2 } ` - f := &Formatter{CommentMode: CommentsFollow} - result, err := f.Format([]byte(input)) + formatter := &Formatter{CommentMode: CommentsFollow} + formattedResult, err := formatter.Format([]byte(inputSource)) if err != nil { - t.Fatalf("Format error: %v", err) + testRunner.Fatalf("Format error: %v", err) } - if string(result) != expected { - t.Errorf("got:\n%s\nwant:\n%s", result, expected) + if string(formattedResult) != expectedOutput { + testRunner.Errorf("got:\n%s\nwant:\n%s", formattedResult, expectedOutput) } } -func TestFormat_Switch(t *testing.T) { - input := `package main +func TestFormat_Switch(testRunner *testing.T) { + inputSource := `package main func main() { x := 1 @@ -154,7 +154,7 @@ func main() { z := 3 } ` - expected := `package main + expectedOutput := `package main func main() { x := 1 @@ -167,20 +167,20 @@ func main() { z := 3 } ` - f := &Formatter{CommentMode: CommentsFollow} - result, err := f.Format([]byte(input)) + formatter := &Formatter{CommentMode: CommentsFollow} + formattedResult, err := formatter.Format([]byte(inputSource)) if err != nil { - t.Fatalf("Format error: %v", err) + testRunner.Fatalf("Format error: %v", err) } - if string(result) != expected { - t.Errorf("got:\n%s\nwant:\n%s", result, expected) + if string(formattedResult) != expectedOutput { + testRunner.Errorf("got:\n%s\nwant:\n%s", formattedResult, expectedOutput) } } -func TestFormat_MultipleFunctions(t *testing.T) { - input := `package main +func TestFormat_MultipleFunctions(testRunner *testing.T) { + inputSource := `package main func foo() { x := 1 @@ -191,7 +191,7 @@ func bar() { y := 2 } ` - expected := `package main + expectedOutput := `package main func foo() { x := 1 @@ -201,27 +201,27 @@ func bar() { y := 2 } ` - f := &Formatter{CommentMode: CommentsFollow} - result, err := f.Format([]byte(input)) + formatter := &Formatter{CommentMode: CommentsFollow} + formattedResult, err := formatter.Format([]byte(inputSource)) if err != nil { - t.Fatalf("Format error: %v", err) + testRunner.Fatalf("Format error: %v", err) } - if string(result) != expected { - t.Errorf("got:\n%s\nwant:\n%s", result, expected) + if string(formattedResult) != expectedOutput { + testRunner.Errorf("got:\n%s\nwant:\n%s", formattedResult, expectedOutput) } } -func TestFormat_TypeStruct(t *testing.T) { - input := `package main +func TestFormat_TypeStruct(testRunner *testing.T) { + inputSource := `package main type Foo struct { X int } var x = 1 ` - expected := `package main + expectedOutput := `package main type Foo struct { X int @@ -229,20 +229,20 @@ type Foo struct { var x = 1 ` - f := &Formatter{CommentMode: CommentsFollow} - result, err := f.Format([]byte(input)) + formatter := &Formatter{CommentMode: CommentsFollow} + formattedResult, err := formatter.Format([]byte(inputSource)) if err != nil { - t.Fatalf("Format error: %v", err) + testRunner.Fatalf("Format error: %v", err) } - if string(result) != expected { - t.Errorf("got:\n%s\nwant:\n%s", result, expected) + if string(formattedResult) != expectedOutput { + testRunner.Errorf("got:\n%s\nwant:\n%s", formattedResult, expectedOutput) } } -func TestFormat_DifferentStatementTypes(t *testing.T) { - input := `package main +func TestFormat_DifferentStatementTypes(testRunner *testing.T) { + inputSource := `package main func main() { x := 1 @@ -254,7 +254,7 @@ func main() { return } ` - expected := `package main + expectedOutput := `package main func main() { x := 1 @@ -270,20 +270,20 @@ func main() { return } ` - f := &Formatter{CommentMode: CommentsFollow} - result, err := f.Format([]byte(input)) + formatter := &Formatter{CommentMode: CommentsFollow} + formattedResult, err := formatter.Format([]byte(inputSource)) if err != nil { - t.Fatalf("Format error: %v", err) + testRunner.Fatalf("Format error: %v", err) } - if string(result) != expected { - t.Errorf("got:\n%s\nwant:\n%s", result, expected) + if string(formattedResult) != expectedOutput { + testRunner.Errorf("got:\n%s\nwant:\n%s", formattedResult, expectedOutput) } } -func TestFormat_ConsecutiveIfs(t *testing.T) { - input := `package main +func TestFormat_ConsecutiveIfs(testRunner *testing.T) { + inputSource := `package main func main() { if err != nil { @@ -294,7 +294,7 @@ func main() { } } ` - expected := `package main + expectedOutput := `package main func main() { if err != nil { @@ -306,20 +306,20 @@ func main() { } } ` - f := &Formatter{CommentMode: CommentsFollow} - result, err := f.Format([]byte(input)) + formatter := &Formatter{CommentMode: CommentsFollow} + formattedResult, err := formatter.Format([]byte(inputSource)) if err != nil { - t.Fatalf("Format error: %v", err) + testRunner.Fatalf("Format error: %v", err) } - if string(result) != expected { - t.Errorf("got:\n%s\nwant:\n%s", result, expected) + if string(formattedResult) != expectedOutput { + testRunner.Errorf("got:\n%s\nwant:\n%s", formattedResult, expectedOutput) } } -func TestFormat_CaseClauseStatements(t *testing.T) { - input := `package main +func TestFormat_CaseClauseStatements(testRunner *testing.T) { + inputSource := `package main func main() { switch x { @@ -331,7 +331,7 @@ func main() { } } ` - expected := `package main + expectedOutput := `package main func main() { switch x { @@ -344,27 +344,27 @@ func main() { } } ` - f := &Formatter{CommentMode: CommentsFollow} - result, err := f.Format([]byte(input)) + formatter := &Formatter{CommentMode: CommentsFollow} + formattedResult, err := formatter.Format([]byte(inputSource)) if err != nil { - t.Fatalf("Format error: %v", err) + testRunner.Fatalf("Format error: %v", err) } - if string(result) != expected { - t.Errorf("got:\n%s\nwant:\n%s", result, expected) + if string(formattedResult) != expectedOutput { + testRunner.Errorf("got:\n%s\nwant:\n%s", formattedResult, expectedOutput) } } -func TestFormat_DeferWithInlineFunc(t *testing.T) { - input := `package main +func TestFormat_DeferWithInlineFunc(testRunner *testing.T) { + inputSource := `package main func main() { defer func() { _ = file.Close() }() fileInfo, err := file.Stat() } ` - expected := `package main + expectedOutput := `package main func main() { defer func() { _ = file.Close() }() @@ -372,20 +372,20 @@ func main() { fileInfo, err := file.Stat() } ` - f := &Formatter{CommentMode: CommentsFollow} - result, err := f.Format([]byte(input)) + formatter := &Formatter{CommentMode: CommentsFollow} + formattedResult, err := formatter.Format([]byte(inputSource)) if err != nil { - t.Fatalf("Format error: %v", err) + testRunner.Fatalf("Format error: %v", err) } - if string(result) != expected { - t.Errorf("got:\n%s\nwant:\n%s", result, expected) + if string(formattedResult) != expectedOutput { + testRunner.Errorf("got:\n%s\nwant:\n%s", formattedResult, expectedOutput) } } -func TestFormat_CaseClauseConsecutiveAssignments(t *testing.T) { - input := `package main +func TestFormat_CaseClauseConsecutiveAssignments(testRunner *testing.T) { + inputSource := `package main func main() { switch x { @@ -398,7 +398,7 @@ func main() { } } ` - expected := `package main + expectedOutput := `package main func main() { switch x { @@ -411,14 +411,14 @@ func main() { } } ` - f := &Formatter{CommentMode: CommentsFollow} - result, err := f.Format([]byte(input)) + formatter := &Formatter{CommentMode: CommentsFollow} + formattedResult, err := formatter.Format([]byte(inputSource)) if err != nil { - t.Fatalf("Format error: %v", err) + testRunner.Fatalf("Format error: %v", err) } - if string(result) != expected { - t.Errorf("got:\n%s\nwant:\n%s", result, expected) + if string(formattedResult) != expectedOutput { + testRunner.Errorf("got:\n%s\nwant:\n%s", formattedResult, expectedOutput) } } @@ -59,20 +59,20 @@ func main() { exitCode := 0 - for _, path := range flag.Args() { - switch info, err := os.Stat(path); { + for _, argumentPath := range flag.Args() { + switch fileInfo, err := os.Stat(argumentPath); { case err != nil: fmt.Fprintf(os.Stderr, "iku: %v\n", err) exitCode = 1 - case info.IsDir(): - if err := processDir(formatter, path, &exitCode); err != nil { + case fileInfo.IsDir(): + if err := processDirectory(formatter, argumentPath, &exitCode); err != nil { fmt.Fprintf(os.Stderr, "iku: %v\n", err) exitCode = 1 } default: - if err := processFilePath(formatter, path, &exitCode); err != nil { + if err := processFilePath(formatter, argumentPath, &exitCode); err != nil { fmt.Fprintf(os.Stderr, "iku: %v\n", err) exitCode = 1 @@ -83,8 +83,8 @@ func main() { os.Exit(exitCode) } -func parseCommentMode(mode string) (CommentMode, error) { - switch strings.ToLower(mode) { +func parseCommentMode(commentModeString string) (CommentMode, error) { + switch strings.ToLower(commentModeString) { case "follow": return CommentsFollow, nil case "precede": @@ -92,20 +92,20 @@ func parseCommentMode(mode string) (CommentMode, error) { case "standalone": return CommentsStandalone, nil default: - return 0, fmt.Errorf("invalid comment mode: %q (use follow, precede, or standalone)", mode) + return 0, fmt.Errorf("invalid comment mode: %q (use follow, precede, or standalone)", commentModeString) } } -func processDir(formatter *Formatter, directory string, exitCode *int) error { - var files []string +func processDirectory(formatter *Formatter, directoryPath string, exitCode *int) error { + var goFilePaths []string - err := filepath.Walk(directory, func(path string, info os.FileInfo, err error) error { + err := filepath.Walk(directoryPath, func(currentPath string, fileInfo os.FileInfo, err error) error { if err != nil { return err } - if !info.IsDir() && strings.HasSuffix(path, ".go") { - files = append(files, path) + if !fileInfo.IsDir() && strings.HasSuffix(currentPath, ".go") { + goFilePaths = append(goFilePaths, currentPath) } return nil @@ -120,17 +120,17 @@ func processDir(formatter *Formatter, directory string, exitCode *int) error { semaphore := make(chan struct{}, runtime.NumCPU()) - for _, path := range files { + for _, filePath := range goFilePaths { waitGroup.Add(1) - go func(filePath string) { + go func(currentFilePath string) { defer waitGroup.Done() semaphore <- struct{}{} defer func() { <-semaphore }() - if err := processFilePath(formatter, filePath, exitCode); err != nil { + if err := processFilePath(formatter, currentFilePath, exitCode); err != nil { mutex.Lock() fmt.Fprintf(os.Stderr, "iku: %v\n", err) @@ -138,7 +138,7 @@ func processDir(formatter *Formatter, directory string, exitCode *int) error { mutex.Unlock() } - }(path) + }(filePath) } waitGroup.Wait() @@ -146,39 +146,39 @@ func processDir(formatter *Formatter, directory string, exitCode *int) error { return nil } -func processFilePath(formatter *Formatter, path string, _ *int) error { - file, err := os.Open(path) +func processFilePath(formatter *Formatter, filePath string, _ *int) error { + sourceFile, err := os.Open(filePath) if err != nil { return err } - defer func() { _ = file.Close() }() + defer func() { _ = sourceFile.Close() }() - var output io.Writer = os.Stdout + var outputDestination io.Writer = os.Stdout if *writeFlag { - output = nil + outputDestination = nil } - return processFile(formatter, path, file, output, true) + return processFile(formatter, filePath, sourceFile, outputDestination, true) } -func processFile(formatter *Formatter, filename string, input io.Reader, outputWriter io.Writer, isFile bool) error { - source, err := io.ReadAll(input) +func processFile(formatter *Formatter, filename string, inputReader io.Reader, outputWriter io.Writer, isFile bool) error { + sourceContent, err := io.ReadAll(inputReader) if err != nil { return fmt.Errorf("%s: %v", filename, err) } - result, err := formatter.Format(source) + formattedResult, err := formatter.Format(sourceContent) if err != nil { return fmt.Errorf("%s: %v", filename, err) } if *listFlag { - if !bytes.Equal(source, result) { + if !bytes.Equal(sourceContent, formattedResult) { fmt.Println(filename) } @@ -186,24 +186,24 @@ func processFile(formatter *Formatter, filename string, input io.Reader, outputW } if *diffFlag { - if !bytes.Equal(source, result) { - difference := unifiedDiff(filename, source, result) - _, _ = os.Stdout.Write(difference) + if !bytes.Equal(sourceContent, formattedResult) { + diffOutput := unifiedDiff(filename, sourceContent, formattedResult) + _, _ = os.Stdout.Write(diffOutput) } return nil } if *writeFlag && isFile { - if !bytes.Equal(source, result) { - return os.WriteFile(filename, result, 0644) + if !bytes.Equal(sourceContent, formattedResult) { + return os.WriteFile(filename, formattedResult, 0644) } return nil } if outputWriter != nil { - _, err = outputWriter.Write(result) + _, err = outputWriter.Write(formattedResult) return err } @@ -211,24 +211,24 @@ func processFile(formatter *Formatter, filename string, input io.Reader, outputW return nil } -func unifiedDiff(filename string, original, formatted []byte) []byte { - var buffer bytes.Buffer +func unifiedDiff(filename string, originalSource, formattedSource []byte) []byte { + var outputBuffer bytes.Buffer - fmt.Fprintf(&buffer, "--- %s\n", filename) - fmt.Fprintf(&buffer, "+++ %s\n", filename) + fmt.Fprintf(&outputBuffer, "--- %s\n", filename) + fmt.Fprintf(&outputBuffer, "+++ %s\n", filename) - originalLines := strings.Split(string(original), "\n") - formattedLines := strings.Split(string(formatted), "\n") + originalSourceLines := strings.Split(string(originalSource), "\n") + formattedSourceLines := strings.Split(string(formattedSource), "\n") - fmt.Fprintf(&buffer, "@@ -1,%d +1,%d @@\n", len(originalLines), len(formattedLines)) + fmt.Fprintf(&outputBuffer, "@@ -1,%d +1,%d @@\n", len(originalSourceLines), len(formattedSourceLines)) - for _, line := range originalLines { - fmt.Fprintf(&buffer, "-%s\n", line) + for _, currentLine := range originalSourceLines { + fmt.Fprintf(&outputBuffer, "-%s\n", currentLine) } - for _, line := range formattedLines { - fmt.Fprintf(&buffer, "+%s\n", line) + for _, currentLine := range formattedSourceLines { + fmt.Fprintf(&outputBuffer, "+%s\n", currentLine) } - return buffer.Bytes() + return outputBuffer.Bytes() } |