diff options
| author | Fuwn <[email protected]> | 2026-02-05 07:14:33 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-05 07:14:33 +0000 |
| commit | 30fb266c13d32f838b1c5ee5be6036fc8eed4430 (patch) | |
| tree | c4228b7f2a0902e5d0ab88e31946b12f85b68255 /adapter_go.go | |
| parent | docs(README): Update "How It Works" source (diff) | |
| download | iku-30fb266c13d32f838b1c5ee5be6036fc8eed4430.tar.xz iku-30fb266c13d32f838b1c5ee5be6036fc8eed4430.zip | |
feat(engine): Add language-agnostic formatting engine with Go adapter
Diffstat (limited to 'adapter_go.go')
| -rw-r--r-- | adapter_go.go | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/adapter_go.go b/adapter_go.go new file mode 100644 index 0000000..59096bb --- /dev/null +++ b/adapter_go.go @@ -0,0 +1,89 @@ +package main + +import ( + "github.com/Fuwn/iku/engine" + "go/format" + "go/parser" + "go/token" + "strings" +) + +type GoAdapter struct{} + +func (a *GoAdapter) Analyze(source []byte) ([]byte, []engine.LineEvent, error) { + formattedSource, err := format.Source(source) + + if err != nil { + return nil, nil, err + } + + tokenFileSet := token.NewFileSet() + parsedFile, err := parser.ParseFile(tokenFileSet, "", formattedSource, parser.ParseComments) + + if err != nil { + return nil, nil, err + } + + formatter := &Formatter{} + lineInformationMap := formatter.buildLineInfo(tokenFileSet, parsedFile) + sourceLines := strings.Split(string(formattedSource), "\n") + events := make([]engine.LineEvent, len(sourceLines)) + insideRawString := false + + for lineIndex, currentLine := range sourceLines { + backtickCount := countRawStringDelimiters(currentLine) + wasInsideRawString := insideRawString + + if backtickCount%2 == 1 { + insideRawString = !insideRawString + } + + event := engine.NewLineEvent(currentLine) + + if wasInsideRawString { + event.InRawString = true + events[lineIndex] = event + + continue + } + + if event.IsBlank { + events[lineIndex] = event + + continue + } + + lineNumber := lineIndex + 1 + currentInformation := lineInformationMap[lineNumber] + + if currentInformation != nil { + event.HasASTInfo = true + event.StatementType = currentInformation.statementType + event.IsTopLevel = currentInformation.isTopLevel + event.IsScoped = currentInformation.isScoped + event.IsStartLine = currentInformation.isStartLine + } + + event.IsClosingBrace = isClosingBrace(currentLine) + event.IsOpeningBrace = isOpeningBrace(currentLine) + event.IsCaseLabel = isCaseLabel(currentLine) + event.IsCommentOnly = isCommentOnly(currentLine) + event.IsPackageDecl = isPackageLine(event.TrimmedContent) + events[lineIndex] = event + } + + return formattedSource, events, nil +} + +func MapCommentMode(mode CommentMode) engine.CommentMode { + switch mode { + case CommentsFollow: + return engine.CommentsFollow + case CommentsPrecede: + return engine.CommentsPrecede + case CommentsStandalone: + return engine.CommentsStandalone + default: + return engine.CommentsFollow + } +} |