馃殌 Grammar-Aware Code Formatter: Structure through separation (supports Go, JavaScript, TypeScript, JSX, and TSX)
go formatter code-formatter javascript typescript jsx tsx
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 90 lines 2.2 kB view raw
1package main 2 3import ( 4 "bytes" 5 "github.com/Fuwn/iku/engine" 6 "go/format" 7 "go/parser" 8 "go/token" 9) 10 11type GoAdapter struct{} 12 13func (a *GoAdapter) Analyze(source []byte) ([]byte, []engine.LineEvent, error) { 14 formattedSource, err := format.Source(source) 15 16 if err != nil { 17 return nil, nil, err 18 } 19 20 tokenFileSet := token.NewFileSet() 21 parsedFile, err := parser.ParseFile(tokenFileSet, "", formattedSource, parser.ParseComments) 22 23 if err != nil { 24 return nil, nil, err 25 } 26 27 formatter := &Formatter{} 28 lineInformationMap := formatter.buildLineInfo(tokenFileSet, parsedFile) 29 sourceByteLines := bytes.Split(formattedSource, []byte("\n")) 30 events := make([]engine.LineEvent, len(sourceByteLines)) 31 insideRawString := false 32 33 for lineIndex, currentLineBytes := range sourceByteLines { 34 currentLine := string(currentLineBytes) 35 backtickCount := countRawStringDelimiters(currentLine) 36 wasInsideRawString := insideRawString 37 38 if backtickCount%2 == 1 { 39 insideRawString = !insideRawString 40 } 41 42 event := engine.NewLineEvent(currentLine) 43 44 if wasInsideRawString { 45 event.InRawString = true 46 events[lineIndex] = event 47 48 continue 49 } 50 51 if event.IsBlank { 52 events[lineIndex] = event 53 54 continue 55 } 56 57 lineNumber := lineIndex + 1 58 currentInformation := lineInformationMap[lineNumber] 59 60 if currentInformation != nil { 61 event.HasASTInfo = true 62 event.StatementType = currentInformation.statementType 63 event.IsTopLevel = currentInformation.isTopLevel 64 event.IsScoped = currentInformation.isScoped 65 event.IsStartLine = currentInformation.isStartLine 66 } 67 68 event.IsClosingBrace = isClosingBrace(currentLine) 69 event.IsOpeningBrace = isOpeningBrace(currentLine) 70 event.IsCaseLabel = isCaseLabel(currentLine) 71 event.IsCommentOnly = isCommentOnly(currentLine) 72 event.IsPackageDecl = isPackageLine(event.TrimmedContent) 73 events[lineIndex] = event 74 } 75 76 return formattedSource, events, nil 77} 78 79func MapCommentMode(mode CommentMode) engine.CommentMode { 80 switch mode { 81 case CommentsFollow: 82 return engine.CommentsFollow 83 case CommentsPrecede: 84 return engine.CommentsPrecede 85 case CommentsStandalone: 86 return engine.CommentsStandalone 87 default: 88 return engine.CommentsFollow 89 } 90}