Skip to content

Commit a23d144

Browse files
committed
todo
1 parent a0e2f5a commit a23d144

12 files changed

+399
-62
lines changed

errgoengine.go

-4
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ func (e *ErrgoEngine) Analyze(workingPath, msg string) (*CompiledErrorTemplate,
5757
contextData := NewContextData(e.SharedStore, workingPath)
5858
contextData.Analyzer = template.Language.AnalyzerFactory(contextData)
5959

60-
if template.Language.stubFs != nil {
61-
e.FS.AttachOrReplace(template.Language.stubFs, 1)
62-
}
63-
6460
groupNames := template.Pattern.SubexpNames()
6561
for _, submatches := range template.Pattern.FindAllStringSubmatch(msg, -1) {
6662
for idx, matchedContent := range submatches {

extern.go

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package errgoengine
2+
3+
import (
4+
"fmt"
5+
"io/fs"
6+
)
7+
8+
type ExternSymbol struct {
9+
Name string `json:"name"`
10+
Type string `json:"type"`
11+
ReturnType string `json:"returnType"`
12+
Paremeters []ExternSymbol `json:"parameters"`
13+
}
14+
15+
type ExternFile struct {
16+
Name string `json:"name"`
17+
Package string `json:"package"`
18+
Constructors []ExternSymbol `json:"constructors"`
19+
Methods []ExternSymbol `json:"methods"`
20+
}
21+
22+
func ImportExternSymbols(externFs fs.ReadFileFS) (map[string]*SymbolTree, error) {
23+
if externFs == nil {
24+
return nil, nil
25+
}
26+
27+
symbols := make(map[string]*SymbolTree)
28+
matches, err := fs.Glob(externFs, "**/*.json")
29+
if err != nil {
30+
return nil, err
31+
}
32+
33+
for _, match := range matches {
34+
if err := compileExternSymbol(externFs, match); err != nil {
35+
return symbols, err
36+
}
37+
}
38+
39+
return symbols, nil
40+
}
41+
42+
func compileExternSymbol(externFs fs.FS, path string) error {
43+
if externFs == nil {
44+
return fmt.Errorf("externFs must not be nil")
45+
}
46+
47+
return nil
48+
}

fs.go

+17-17
Original file line numberDiff line numberDiff line change
@@ -64,45 +64,45 @@ func (mfs *MultiReadFileFS) Open(name string) (fs.File, error) {
6464
return nil, os.ErrNotExist
6565
}
6666

67-
type stubFileInfo struct {
67+
type virtualFileInfo struct {
6868
name string
6969
}
7070

71-
func (*stubFileInfo) Name() string { return "" }
71+
func (f *virtualFileInfo) Name() string { return f.name }
7272

73-
func (*stubFileInfo) Size() int64 { return 0 }
73+
func (*virtualFileInfo) Size() int64 { return 0 }
7474

75-
func (*stubFileInfo) Mode() fs.FileMode { return 0400 }
75+
func (*virtualFileInfo) Mode() fs.FileMode { return 0400 }
7676

77-
func (*stubFileInfo) ModTime() time.Time { return time.Now() }
77+
func (*virtualFileInfo) ModTime() time.Time { return time.Now() }
7878

79-
func (*stubFileInfo) IsDir() bool { return false }
79+
func (*virtualFileInfo) IsDir() bool { return false }
8080

81-
func (*stubFileInfo) Sys() any { return nil }
81+
func (*virtualFileInfo) Sys() any { return nil }
8282

83-
type StubFile struct {
83+
type VirtualFile struct {
8484
Name string
8585
}
8686

87-
func (StubFile) Read(bt []byte) (int, error) { return 0, io.EOF }
87+
func (VirtualFile) Read(bt []byte) (int, error) { return 0, io.EOF }
8888

89-
func (vf StubFile) Stat() (fs.FileInfo, error) { return &stubFileInfo{vf.Name}, nil }
89+
func (vf VirtualFile) Stat() (fs.FileInfo, error) { return &virtualFileInfo{vf.Name}, nil }
9090

91-
func (StubFile) Close() error { return nil }
91+
func (VirtualFile) Close() error { return nil }
9292

93-
type StubFS struct {
94-
Files []StubFile
93+
type VirtualFS struct {
94+
Files []VirtualFile
9595
}
9696

97-
func (vfs *StubFS) StubFile(name string) StubFile {
98-
file := StubFile{
97+
func (vfs *VirtualFS) StubFile(name string) VirtualFile {
98+
file := VirtualFile{
9999
Name: name,
100100
}
101101
vfs.Files = append(vfs.Files, file)
102102
return file
103103
}
104104

105-
func (vfs *StubFS) Open(name string) (fs.File, error) {
105+
func (vfs *VirtualFS) Open(name string) (fs.File, error) {
106106
for _, file := range vfs.Files {
107107
if file.Name == name {
108108
return file, nil
@@ -111,7 +111,7 @@ func (vfs *StubFS) Open(name string) (fs.File, error) {
111111
return nil, os.ErrNotExist
112112
}
113113

114-
func (vfs *StubFS) ReadFile(name string) ([]byte, error) {
114+
func (vfs *VirtualFS) ReadFile(name string) ([]byte, error) {
115115
for _, file := range vfs.Files {
116116
if file.Name == name {
117117
return make([]byte, 0), nil

language.go

+46-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package errgoengine
22

33
import (
44
"context"
5+
"encoding/json"
56
"fmt"
7+
"io/fs"
68
"regexp"
79
"strings"
810

@@ -24,7 +26,7 @@ type LanguageAnalyzer interface {
2426
type Language struct {
2527
isCompiled bool
2628
stackTraceRegex *regexp.Regexp
27-
stubFs *StubFS
29+
externSymbols map[string]*SymbolTree
2830
Name string
2931
FilePatterns []string
3032
SitterLanguage *sitter.Language
@@ -33,7 +35,7 @@ type Language struct {
3335
SymbolsToCapture string
3436
LocationConverter func(path, pos string) Location
3537
AnalyzerFactory func(cd *ContextData) LanguageAnalyzer
36-
OnGenStubFS func(fs *StubFS)
38+
ExternFS fs.ReadFileFS
3739
}
3840

3941
func (lang *Language) MatchPath(path string) bool {
@@ -62,14 +64,53 @@ func (lang *Language) Compile() {
6264
panic(fmt.Sprintf("[Language -> %s] AnalyzerFactory must not be nil", lang.Name))
6365
}
6466

65-
if lang.stubFs == nil && lang.OnGenStubFS != nil {
66-
lang.stubFs = &StubFS{}
67-
lang.OnGenStubFS(lang.stubFs)
67+
if err := lang.compileExternSymbols(); err != nil {
68+
panic(err)
6869
}
6970

7071
lang.isCompiled = true
7172
}
7273

74+
func (lang *Language) compileExternSymbols() error {
75+
if lang.isCompiled || lang.ExternFS == nil {
76+
return nil
77+
}
78+
79+
lang.externSymbols = make(map[string]*SymbolTree)
80+
81+
matches, err := fs.Glob(lang.ExternFS, "**/*.json")
82+
if err != nil {
83+
return err
84+
}
85+
86+
for _, match := range matches {
87+
if err := lang.compileExternSymbol(match); err != nil {
88+
return err
89+
}
90+
}
91+
}
92+
93+
func (lang *Language) compileExternSymbol(path string) error {
94+
if lang.isCompiled || lang.ExternFS == nil {
95+
return nil
96+
}
97+
98+
file, err := lang.ExternFS.Open(path)
99+
if err != nil {
100+
return err
101+
}
102+
103+
defer file.Close()
104+
105+
var symTree SymbolTree
106+
if err := json.NewDecoder(file).Decode(&symTree); err != nil {
107+
return err
108+
}
109+
110+
lang.externSymbols[path] = &symTree
111+
return nil
112+
}
113+
73114
// SetTemplateStackTraceRegex sets the language's regex pattern directly. for testing purposes only
74115
func SetTemplateStackTraceRegex(lang *Language, pattern *regexp.Regexp) {
75116
lang.stackTraceRegex = pattern
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "Object",
3+
"package": "java.lang",
4+
"description": "The root class of the Java class hierarchy.",
5+
"constructors": [
6+
{
7+
"name": "Object",
8+
"parameters": [],
9+
"description": "Creates a new instance of the Object class."
10+
}
11+
],
12+
"methods": [
13+
{
14+
"name": "equals",
15+
"returnType": "boolean",
16+
"parameters": [
17+
{
18+
"name": "obj",
19+
"type": "Object",
20+
"description": "The object to compare to."
21+
}
22+
],
23+
"description": "Indicates whether some other object is \"equal to\" this one."
24+
},
25+
{
26+
"name": "hashCode",
27+
"returnType": "int",
28+
"parameters": [],
29+
"description": "Returns a hash code value for this object."
30+
},
31+
{
32+
"name": "toString",
33+
"returnType": "String",
34+
"parameters": [],
35+
"description": "Returns a string representation of this object."
36+
}
37+
]
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
{
2+
"name": "String",
3+
"package": "java.lang",
4+
"description": "Represents a sequence of characters.",
5+
"constructors": [
6+
{
7+
"name": "String",
8+
"parameters": [
9+
{
10+
"name": "value",
11+
"type": "char[]",
12+
"description": "The character array that is the initial value of the string."
13+
}
14+
]
15+
},
16+
{
17+
"name": "String",
18+
"parameters": [
19+
{
20+
"name": "value",
21+
"type": "String",
22+
"description": "The string that is the initial value of the string."
23+
}
24+
]
25+
}
26+
],
27+
"methods": [
28+
{
29+
"name": "length",
30+
"returnType": "int",
31+
"description": "Returns the length of the string."
32+
},
33+
{
34+
"name": "charAt",
35+
"returnType": "char",
36+
"parameters": [
37+
{
38+
"name": "index",
39+
"type": "int",
40+
"description": "The index of the character to return."
41+
}
42+
],
43+
"description": "Returns the character at the specified index."
44+
},
45+
{
46+
"name": "substring",
47+
"returnType": "String",
48+
"parameters": [
49+
{
50+
"name": "start",
51+
"type": "int",
52+
"description": "The starting index of the substring."
53+
},
54+
{
55+
"name": "end",
56+
"type": "int",
57+
"description": "The ending index of the substring."
58+
}
59+
],
60+
"description": "Returns a substring of the string."
61+
},
62+
{
63+
"name": "concat",
64+
"returnType": "String",
65+
"parameters": [
66+
{
67+
"name": "str",
68+
"type": "String",
69+
"description": "The string to concatenate."
70+
}
71+
],
72+
"description": "Concatenates the specified string to the end of this string."
73+
},
74+
{
75+
"name": "equals",
76+
"returnType": "boolean",
77+
"parameters": [
78+
{
79+
"name": "obj",
80+
"type": "Object",
81+
"description": "The object to compare to."
82+
}
83+
],
84+
"description": "Compares this string to the specified object."
85+
},
86+
{
87+
"name": "hashCode",
88+
"returnType": "int",
89+
"description": "Returns the hash code of this string."
90+
},
91+
{
92+
"name": "toString",
93+
"returnType": "String",
94+
"description": "Returns a string representation of this string."
95+
}
96+
]
97+
}

0 commit comments

Comments
 (0)