Skip to content

Commit fae85c0

Browse files
authored
Move checker to checker package (#227)
1 parent 887237c commit fae85c0

17 files changed

+542
-520
lines changed

internal/ast/diagnostic.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package ast
22

33
import (
4+
"maps"
5+
"slices"
6+
"strings"
7+
48
"github.com/microsoft/typescript-go/internal/compiler/diagnostics"
59
"github.com/microsoft/typescript-go/internal/core"
610
"github.com/microsoft/typescript-go/internal/stringutil"
@@ -81,3 +85,149 @@ func NewDiagnosticChain(chain *Diagnostic, message *diagnostics.Message, args ..
8185
func NewCompilerDiagnostic(message *diagnostics.Message, args ...any) *Diagnostic {
8286
return NewDiagnostic(nil, core.UndefinedTextRange(), message, args...)
8387
}
88+
89+
type DiagnosticsCollection struct {
90+
fileDiagnostics map[string][]*Diagnostic
91+
nonFileDiagnostics []*Diagnostic
92+
}
93+
94+
func (c *DiagnosticsCollection) Add(diagnostic *Diagnostic) {
95+
if diagnostic.File() != nil {
96+
fileName := diagnostic.File().FileName()
97+
if c.fileDiagnostics == nil {
98+
c.fileDiagnostics = make(map[string][]*Diagnostic)
99+
}
100+
c.fileDiagnostics[fileName] = core.InsertSorted(c.fileDiagnostics[fileName], diagnostic, CompareDiagnostics)
101+
} else {
102+
c.nonFileDiagnostics = core.InsertSorted(c.nonFileDiagnostics, diagnostic, CompareDiagnostics)
103+
}
104+
}
105+
106+
func (c *DiagnosticsCollection) Lookup(diagnostic *Diagnostic) *Diagnostic {
107+
var diagnostics []*Diagnostic
108+
if diagnostic.File() != nil {
109+
diagnostics = c.fileDiagnostics[diagnostic.File().FileName()]
110+
} else {
111+
diagnostics = c.nonFileDiagnostics
112+
}
113+
if i, ok := slices.BinarySearchFunc(diagnostics, diagnostic, CompareDiagnostics); ok {
114+
return diagnostics[i]
115+
}
116+
return nil
117+
}
118+
119+
func (c *DiagnosticsCollection) GetGlobalDiagnostics() []*Diagnostic {
120+
return c.nonFileDiagnostics
121+
}
122+
123+
func (c *DiagnosticsCollection) GetDiagnosticsForFile(fileName string) []*Diagnostic {
124+
return c.fileDiagnostics[fileName]
125+
}
126+
127+
func (c *DiagnosticsCollection) GetDiagnostics() []*Diagnostic {
128+
fileNames := slices.Collect(maps.Keys(c.fileDiagnostics))
129+
slices.Sort(fileNames)
130+
diagnostics := c.nonFileDiagnostics
131+
for _, fileName := range fileNames {
132+
diagnostics = append(diagnostics, c.fileDiagnostics[fileName]...)
133+
}
134+
return diagnostics
135+
}
136+
137+
func getDiagnosticPath(d *Diagnostic) string {
138+
if d.File() != nil {
139+
return d.File().FileName()
140+
}
141+
return ""
142+
}
143+
144+
func EqualDiagnostics(d1, d2 *Diagnostic) bool {
145+
return getDiagnosticPath(d1) == getDiagnosticPath(d2) &&
146+
d1.Loc() == d2.Loc() &&
147+
d1.Code() == d2.Code() &&
148+
d1.Message() == d2.Message() &&
149+
slices.EqualFunc(d1.MessageChain(), d2.MessageChain(), equalMessageChain) &&
150+
slices.EqualFunc(d1.RelatedInformation(), d2.RelatedInformation(), EqualDiagnostics)
151+
}
152+
153+
func equalMessageChain(c1, c2 *Diagnostic) bool {
154+
return c1.Code() == c2.Code() &&
155+
c1.Message() == c2.Message() &&
156+
slices.EqualFunc(c1.MessageChain(), c2.MessageChain(), equalMessageChain)
157+
}
158+
159+
func compareMessageChainSize(c1, c2 []*Diagnostic) int {
160+
c := len(c2) - len(c1)
161+
if c != 0 {
162+
return c
163+
}
164+
for i := range c1 {
165+
c = compareMessageChainSize(c1[i].MessageChain(), c2[i].MessageChain())
166+
if c != 0 {
167+
return c
168+
}
169+
}
170+
return 0
171+
}
172+
173+
func compareMessageChainContent(c1, c2 []*Diagnostic) int {
174+
for i := range c1 {
175+
c := strings.Compare(c1[i].Message(), c2[i].Message())
176+
if c != 0 {
177+
return c
178+
}
179+
if c1[i].MessageChain() != nil {
180+
c = compareMessageChainContent(c1[i].MessageChain(), c2[i].MessageChain())
181+
if c != 0 {
182+
return c
183+
}
184+
}
185+
}
186+
return 0
187+
}
188+
189+
func compareRelatedInfo(r1, r2 []*Diagnostic) int {
190+
c := len(r2) - len(r1)
191+
if c != 0 {
192+
return c
193+
}
194+
for i := range r1 {
195+
c = CompareDiagnostics(r1[i], r2[i])
196+
if c != 0 {
197+
return c
198+
}
199+
}
200+
return 0
201+
}
202+
203+
func CompareDiagnostics(d1, d2 *Diagnostic) int {
204+
c := strings.Compare(getDiagnosticPath(d1), getDiagnosticPath(d2))
205+
if c != 0 {
206+
return c
207+
}
208+
c = d1.Loc().Pos() - d2.Loc().Pos()
209+
if c != 0 {
210+
return c
211+
}
212+
c = d1.Loc().End() - d2.Loc().End()
213+
if c != 0 {
214+
return c
215+
}
216+
c = int(d1.Code()) - int(d2.Code())
217+
if c != 0 {
218+
return c
219+
}
220+
c = strings.Compare(d1.Message(), d2.Message())
221+
if c != 0 {
222+
return c
223+
}
224+
c = compareMessageChainSize(d1.MessageChain(), d2.MessageChain())
225+
if c != 0 {
226+
return c
227+
}
228+
c = compareMessageChainContent(d1.MessageChain(), d2.MessageChain())
229+
if c != 0 {
230+
return c
231+
}
232+
return compareRelatedInfo(d1.RelatedInformation(), d2.RelatedInformation())
233+
}

0 commit comments

Comments
 (0)