cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.71.1

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

internal/parser/read.go

184lines · modecode

1package parser
2
3import (
4 "bufio"
5 "errors"
6 "io"
7 "strings"
8
9 "github.com/cloudflare/pint/internal/comments"
10 "github.com/cloudflare/pint/internal/diags"
11)
12
13type skipMode uint8
14
15const (
16 skipNone skipMode = iota
17 skipNextLine
18 skipBegin
19 skipEnd
20 skipCurrentLine
21 skipFile
22)
23
24func emptyLine(line string, comments []comments.Comment, stripComments bool) string {
25 offset := len(line)
26 for _, c := range comments {
27 offset = c.Offset
28 break
29 }
30
31 var buf strings.Builder
32 for i, r := range line {
33 switch {
34 case r == '\n':
35 buf.WriteRune(r)
36 case i < offset || stripComments:
37 buf.WriteRune(' ')
38 default:
39 buf.WriteRune(r)
40 }
41 }
42
43 return buf.String()
44}
45
46type Content struct {
47 Ignored *diags.Diagnostic
48 Body []byte
49 FileComments []comments.Comment
50 TotalLines int
51}
52
53func ReadContent(r io.Reader) (out Content, err error) {
54 reader := bufio.NewReader(r)
55 var (
56 lineno int
57 line string
58 lineComments []comments.Comment
59 found bool
60 skip skipMode
61
62 skipNext bool
63 autoReset bool
64 skipAll bool
65 inBegin bool
66 )
67
68 for {
69 lineno++
70 line, err = reader.ReadString('\n')
71 if err != nil && !errors.Is(err, io.EOF) {
72 break
73 }
74 if line != "" {
75 out.TotalLines++
76 }
77
78 lineComments = comments.Parse(lineno, line)
79
80 if skipAll {
81 out.Body = append(out.Body, []byte(emptyLine(line, lineComments, inBegin))...)
82 } else {
83 skip = skipNone
84 found = false
85 for _, comment := range lineComments {
86 // nolint:exhaustive
87 switch comment.Type {
88 case comments.IgnoreFileType:
89 skip = skipFile
90 found = true
91 out.Ignored = &diags.Diagnostic{
92 Message: "This file was excluded from pint checks.",
93 Pos: diags.PositionRanges{
94 {
95 Line: lineno,
96 FirstColumn: comment.Offset + 1,
97 LastColumn: len(line) - 1,
98 },
99 },
100 FirstColumn: comment.Offset + 1,
101 LastColumn: len(line) - 1,
102 }
103 case comments.IgnoreLineType:
104 skip = skipCurrentLine
105 found = true
106 case comments.IgnoreBeginType:
107 skip = skipBegin
108 found = true
109 case comments.IgnoreEndType:
110 skip = skipEnd
111 found = true
112 case comments.IgnoreNextLineType:
113 skip = skipNextLine
114 found = true
115 case comments.FileOwnerType:
116 out.FileComments = append(out.FileComments, comment)
117 case comments.RuleOwnerType:
118 // pass
119 case comments.FileDisableType:
120 out.FileComments = append(out.FileComments, comment)
121 case comments.DisableType:
122 // pass
123 case comments.FileSnoozeType:
124 out.FileComments = append(out.FileComments, comment)
125 case comments.SnoozeType:
126 // pass
127 case comments.RuleSetType:
128 // pass
129 case comments.InvalidComment:
130 out.FileComments = append(out.FileComments, comment)
131 }
132 }
133 switch {
134 case found:
135 switch skip {
136 case skipNone:
137 // no-op
138 case skipFile:
139 out.Body = append(out.Body, []byte(emptyLine(line, lineComments, inBegin))...)
140 skipNext = true
141 autoReset = false
142 skipAll = true
143 case skipCurrentLine:
144 out.Body = append(out.Body, []byte(emptyLine(line, lineComments, inBegin))...)
145 if !inBegin {
146 skipNext = false
147 autoReset = true
148 }
149 case skipNextLine:
150 out.Body = append(out.Body, []byte(line)...)
151 skipNext = true
152 autoReset = true
153 case skipBegin:
154 out.Body = append(out.Body, []byte(line)...)
155 skipNext = true
156 autoReset = false
157 inBegin = true
158 case skipEnd:
159 out.Body = append(out.Body, []byte(line)...)
160 skipNext = false
161 autoReset = true
162 inBegin = false
163 }
164 case skipNext:
165 out.Body = append(out.Body, []byte(emptyLine(line, lineComments, inBegin))...)
166 if autoReset {
167 skipNext = false
168 }
169 default:
170 out.Body = append(out.Body, []byte(line)...)
171 }
172 }
173
174 if err != nil {
175 break
176 }
177 }
178
179 if !errors.Is(err, io.EOF) {
180 return out, err
181 }
182
183 return out, nil
184}