-
Notifications
You must be signed in to change notification settings - Fork 1
/
process.go
82 lines (71 loc) · 2.01 KB
/
process.go
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
package main
import (
"bytes"
"fmt"
"github.com/tshprecher/gospell/check"
"strings"
"text/scanner"
)
type misspelling struct {
line int
word string
suggestions []string
}
type fileResult struct {
filename string
misspellings []misspelling
}
func (r fileResult) String() string {
var buffer bytes.Buffer
for _, misp := range r.misspellings {
buffer.WriteString(fmt.Sprintf("%s:%d\t'%s'\t%v\n", r.filename, misp.line, misp.word, misp.suggestions))
}
return buffer.String()
}
type processor interface {
run(filename string, src []byte, dict check.Dict) (*fileResult, error)
}
// TODO: benchmark object allocations
func sanitizeWord(word string, alphabet check.Alphabet) string {
if len(word) == 0 {
return word
}
letters := []rune(strings.ToLower(word))
startIdx, endIdx := 0, len(letters)-1
for startIdx < endIdx && !alphabet.Contains(letters[startIdx]) {
startIdx++
}
for startIdx < endIdx && !alphabet.Contains(letters[endIdx]) {
endIdx--
}
return string(letters[startIdx : endIdx+1])
}
type cStyleCommentProcessor struct {
checker check.Checker
}
func handleComments(curLineNo int, comment string, dict check.Dict, res *fileResult) {
var lines []string = strings.Split(comment, "\n")
if len(lines) == 0 {
lines = append(lines, comment)
}
for l := 0; l < len(lines); l++ {
for _, word := range strings.Split(lines[l], " ") {
sanitized := sanitizeWord(word, dict.Alphabet())
if mis, sug := checker.IsMisspelled(sanitized, dict); mis {
m := misspelling{curLineNo - len(lines) + 1 + l, sanitized, sug}
res.misspellings = append(res.misspellings, m)
}
}
}
}
func (p cStyleCommentProcessor) run(filename string, src []byte, dict check.Dict) (*fileResult, error) {
scan := new(scanner.Scanner).Init(bytes.NewReader(src))
scan.Mode = scanner.ScanComments
res := &fileResult{filename, nil}
for tok := scan.Scan(); tok != scanner.EOF; tok = scan.Scan() {
if tok == scanner.Comment {
handleComments(scan.Pos().Line, scan.TokenText(), dict, res)
}
}
return res, nil
}