1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
package main
import (
"bytes"
"github.com/Fuwn/iku/engine"
"go/format"
"go/parser"
"go/token"
)
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)
sourceByteLines := bytes.Split(formattedSource, []byte("\n"))
events := make([]engine.LineEvent, len(sourceByteLines))
insideRawString := false
for lineIndex, currentLineBytes := range sourceByteLines {
currentLine := string(currentLineBytes)
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
}
}
|