Skip to content

Commit f98fa22

Browse files
committed
fix: also apply moduledata cache to types parse
1 parent 8bafe0a commit f98fa22

File tree

4 files changed

+85
-83
lines changed

4 files changed

+85
-83
lines changed

file.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,13 @@ func (f *GoFile) GetTypes() ([]*GoType, error) {
386386
if err != nil {
387387
return nil, err
388388
}
389-
t, err := getTypes(f.FileInfo, f.fh)
389+
err = f.initModuleData()
390+
if err != nil {
391+
return nil, err
392+
}
393+
md := f.moduledata
394+
395+
t, err := getTypes(f.FileInfo, f.fh, md)
390396
if err != nil {
391397
return nil, err
392398
}

moduledata.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ type Moduledata interface {
5151
// ITabLinks returns the itablinks section.
5252
ITabLinks() ModuleDataSection
5353
// TypeLink returns the typelink section.
54-
TypeLink() ([]int32, error)
54+
TypeLink() ModuleDataSection
55+
// TypeLinkData returns the typelink section data.
56+
TypeLinkData() ([]int32, error)
5557
// GoFuncValue returns the value of the 'go:func.*' symbol.
5658
GoFuncValue() uint64
5759
}
@@ -156,7 +158,16 @@ func (m moduledata) ITabLinks() ModuleDataSection {
156158
}
157159

158160
// TypeLink returns the typelink section.
159-
func (m moduledata) TypeLink() ([]int32, error) {
161+
func (m moduledata) TypeLink() ModuleDataSection {
162+
return ModuleDataSection{
163+
Address: m.TypelinkAddr,
164+
Length: m.TypelinkLen,
165+
fh: m.fh,
166+
}
167+
}
168+
169+
// TypeLinkData returns the typelink section.
170+
func (m moduledata) TypeLinkData() ([]int32, error) {
160171
base, data, err := m.fh.getSectionDataFromOffset(m.TypelinkAddr)
161172
if err != nil {
162173
return nil, fmt.Errorf("failed to get the typelink data section: %w", err)
@@ -212,7 +223,7 @@ func (m ModuleDataSection) Data() ([]byte, error) {
212223
}
213224

214225
func buildPclnTabAddrBinary(order binary.ByteOrder, addr uint64) ([]byte, error) {
215-
buf := make([]byte, intSize64)
226+
buf := make([]byte, intSize32)
216227
order.PutUint32(buf, uint32(addr))
217228
return buf, nil
218229
}

type.go

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,17 @@ const (
5555
ChanBoth = ChanRecv | ChanSend
5656
)
5757

58-
func getTypes(fileInfo *FileInfo, f fileHandler) (map[uint64]*GoType, error) {
58+
func getTypes(fileInfo *FileInfo, f fileHandler, md moduledata) (map[uint64]*GoType, error) {
5959
if GoVersionCompare(fileInfo.goversion.Name, "go1.7beta1") < 0 {
60-
return getLegacyTypes(fileInfo, f)
61-
}
62-
63-
md, err := extractModuledata(fileInfo, f)
64-
if err != nil {
65-
return nil, fmt.Errorf("failed to parse the module data: %w", err)
60+
return getLegacyTypes(fileInfo, f, md)
6661
}
6762

6863
types, err := md.Types().Data()
6964
if err != nil {
7065
return nil, fmt.Errorf("failed to get types data section: %w", err)
7166
}
7267

73-
typeLink, err := md.TypeLink()
68+
typeLink, err := md.TypeLinkData()
7469
if err != nil {
7570
return nil, fmt.Errorf("failed to get type link data: %w", err)
7671
}
@@ -86,11 +81,7 @@ func getTypes(fileInfo *FileInfo, f fileHandler) (map[uint64]*GoType, error) {
8681
return parser.parsedTypes(), nil
8782
}
8883

89-
func getLegacyTypes(fileInfo *FileInfo, f fileHandler) (map[uint64]*GoType, error) {
90-
md, err := extractModuledata(fileInfo, f)
91-
if err != nil {
92-
return nil, err
93-
}
84+
func getLegacyTypes(fileInfo *FileInfo, f fileHandler, md moduledata) (map[uint64]*GoType, error) {
9485
typelinkAddr, typelinkData, err := f.getSectionDataFromOffset(md.TypelinkAddr)
9586
if err != nil {
9687
return nil, fmt.Errorf("no typelink section found: %w", err)

type_test.go

Lines changed: 60 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"fmt"
2222
"os"
2323
"reflect"
24-
"strings"
2524
"testing"
2625

2726
"github.com/stretchr/testify/assert"
@@ -36,126 +35,121 @@ func TestGetTypes(t *testing.T) {
3635
}
3736
for _, test := range goldFiles {
3837
t.Run("get_types_"+test, func(t *testing.T) {
39-
require := require.New(t)
40-
assert := assert.New(t)
41-
42-
// TODO: Remove this check when arm support has been added.
43-
if strings.Contains(test, "arm64") {
44-
t.Skip("ARM currently not supported")
45-
}
38+
r := require.New(t)
39+
a := assert.New(t)
4640

4741
fp, err := getTestResourcePath("gold/" + test)
48-
require.NoError(err, "Failed to get path to resource")
42+
r.NoError(err, "Failed to get path to resource")
4943
if _, err = os.Stat(fp); os.IsNotExist(err) {
5044
// Skip this file because it doesn't exist
5145
// t.Skip will cause the parent test to be skipped.
5246
fmt.Printf("[SKIPPING TEST] golden fille %s does not exist\n", test)
5347
return
5448
}
5549
f, err := Open(fp)
56-
require.NoError(err, "Failed to get path to the file")
50+
r.NoError(err, "Failed to get path to the file")
5751
defer f.Close()
5852

5953
typs, err := f.GetTypes()
60-
require.NoError(err, "Should parse with no error")
54+
r.NoError(err, "Should parse with no error")
6155

6256
var simpleStructTested bool
6357
var complexStructTested bool
6458
var stringerInterfaceTested bool
6559
for _, typ := range typs {
6660
if typ.Name == "fmt.Stringer" && typ.PackagePath == "fmt" &&
6761
GoVersionCompare(f.FileInfo.goversion.Name, "go1.7beta1") >= 0 {
68-
assert.Equal(reflect.Interface, typ.Kind, "Stringer should be an interface")
69-
assert.Len(typ.Methods, 1, "Stringer should have 1 function defined")
70-
assert.Equal("String", typ.Methods[0].Name, "Stringer's function should have the name of String")
62+
a.Equal(reflect.Interface, typ.Kind, "Stringer should be an interface")
63+
a.Len(typ.Methods, 1, "Stringer should have 1 function defined")
64+
a.Equal("String", typ.Methods[0].Name, "Stringer's function should have the name of String")
7165

7266
stringerInterfaceTested = true
7367
}
7468
if typ.Name == "main.simpleStruct" && typ.PackagePath == "main" {
75-
assert.Equal(reflect.Struct, typ.Kind, "simpleStruct parsed as wrong type")
76-
assert.Len(typ.Fields, 2, "simpleStruct should have 2 fields")
69+
a.Equal(reflect.Struct, typ.Kind, "simpleStruct parsed as wrong type")
70+
a.Len(typ.Fields, 2, "simpleStruct should have 2 fields")
7771

7872
// Checking fields first should be a string and second an int
79-
assert.Equal(reflect.String, typ.Fields[0].Kind, "First field is the wrong kind.")
80-
assert.Equal("name", typ.Fields[0].FieldName, "First field has the wrong name.")
73+
a.Equal(reflect.String, typ.Fields[0].Kind, "First field is the wrong kind.")
74+
a.Equal("name", typ.Fields[0].FieldName, "First field has the wrong name.")
8175

82-
assert.Equal(reflect.Int, typ.Fields[1].Kind, "Second field is the wrong kind.")
83-
assert.Equal("age", typ.Fields[1].FieldName, "Second field has the wrong name.")
76+
a.Equal(reflect.Int, typ.Fields[1].Kind, "Second field is the wrong kind.")
77+
a.Equal("age", typ.Fields[1].FieldName, "Second field has the wrong name.")
8478

8579
simpleStructTested = true
8680
}
8781

8882
if typ.Name == "main.myComplexStruct" && typ.PackagePath == "main" &&
8983
GoVersionCompare(f.FileInfo.goversion.Name, "go1.7beta1") >= 0 {
90-
assert.Equal(reflect.Struct, typ.Kind, "myComplexStruct parsed as wrong type")
91-
assert.Len(typ.Fields, 8, "myComplexStruct should have 7 fields")
84+
a.Equal(reflect.Struct, typ.Kind, "myComplexStruct parsed as wrong type")
85+
a.Len(typ.Fields, 8, "myComplexStruct should have 7 fields")
9286

9387
// Checking fields first should be a string and second an int
94-
assert.Equal(reflect.String, typ.Fields[0].Kind, "First field is the wrong kind.")
95-
assert.Equal("MyString", typ.Fields[0].FieldName, "First field has the wrong name.")
96-
assert.Equal(`json:"String"`, typ.Fields[0].FieldTag, "Field tag incorrectly parsed")
88+
a.Equal(reflect.String, typ.Fields[0].Kind, "First field is the wrong kind.")
89+
a.Equal("MyString", typ.Fields[0].FieldName, "First field has the wrong name.")
90+
a.Equal(`json:"String"`, typ.Fields[0].FieldTag, "Field tag incorrectly parsed")
9791

98-
assert.Equal(reflect.Ptr, typ.Fields[1].Kind, "Second field is the wrong kind.")
99-
assert.Equal("person", typ.Fields[1].FieldName, "Second field has the wrong name.")
100-
assert.Equal(reflect.Struct, typ.Fields[1].Element.Kind, "Second field resolves to the wrong kind.")
92+
a.Equal(reflect.Ptr, typ.Fields[1].Kind, "Second field is the wrong kind.")
93+
a.Equal("person", typ.Fields[1].FieldName, "Second field has the wrong name.")
94+
a.Equal(reflect.Struct, typ.Fields[1].Element.Kind, "Second field resolves to the wrong kind.")
10195

102-
assert.Len(typ.Fields[1].Element.Fields, 2, "simpleStruct should have 2 fields")
103-
assert.Equal(reflect.String, typ.Fields[1].Element.Fields[0].Kind, "First resolved field is the wrong kind.")
104-
assert.Equal("name", typ.Fields[1].Element.Fields[0].FieldName, "First resolved field has the wrong name.")
96+
a.Len(typ.Fields[1].Element.Fields, 2, "simpleStruct should have 2 fields")
97+
a.Equal(reflect.String, typ.Fields[1].Element.Fields[0].Kind, "First resolved field is the wrong kind.")
98+
a.Equal("name", typ.Fields[1].Element.Fields[0].FieldName, "First resolved field has the wrong name.")
10599

106-
assert.Equal(reflect.Int, typ.Fields[1].Element.Fields[1].Kind, "Second resolved field is the wrong kind.")
107-
assert.Equal("age", typ.Fields[1].Element.Fields[1].FieldName, "Second resolved field has the wrong name.")
100+
a.Equal(reflect.Int, typ.Fields[1].Element.Fields[1].Kind, "Second resolved field is the wrong kind.")
101+
a.Equal("age", typ.Fields[1].Element.Fields[1].FieldName, "Second resolved field has the wrong name.")
108102

109103
// Methods on simpleStruct
110-
assert.Len(typ.Fields[1].Methods, 1, "simpleStruct should have 1 method")
111-
assert.Equal("String", typ.Fields[1].Methods[0].Name, "Wrong method name")
104+
a.Len(typ.Fields[1].Methods, 1, "simpleStruct should have 1 method")
105+
a.Equal("String", typ.Fields[1].Methods[0].Name, "Wrong method name")
112106

113107
// Checking other types
114-
assert.Equal(reflect.Array, typ.Fields[2].Kind, "Third field is the wrong kind.")
115-
assert.Equal("myArray", typ.Fields[2].FieldName, "Third field has the wrong name.")
116-
assert.Equal(2, typ.Fields[2].Length, "Array length is wrong")
117-
assert.Equal(reflect.Int, typ.Fields[2].Element.Kind, "Array element is wrong")
118-
119-
assert.Equal(reflect.Slice, typ.Fields[3].Kind, "4th field is the wrong kind.")
120-
assert.Equal("mySlice", typ.Fields[3].FieldName, "4th field has the wrong name.")
121-
assert.Equal(reflect.Uint, typ.Fields[3].Element.Kind, "Slice element is wrong")
122-
123-
assert.Equal(reflect.Chan, typ.Fields[4].Kind, "5th field is the wrong kind.")
124-
assert.Equal("myChan", typ.Fields[4].FieldName, "5th field has the wrong name.")
125-
assert.Equal(reflect.Struct, typ.Fields[4].Element.Kind, "Chan element is wrong")
126-
assert.Equal(ChanBoth, typ.Fields[4].ChanDir, "Chan direction is wrong")
127-
128-
assert.Equal(reflect.Map, typ.Fields[5].Kind, "6th field is the wrong kind.")
129-
assert.Equal("myMap", typ.Fields[5].FieldName, "6th field has the wrong name.")
130-
assert.Equal(reflect.String, typ.Fields[5].Key.Kind, "Map key is wrong")
131-
assert.Equal(reflect.Int, typ.Fields[5].Element.Kind, "Map element is wrong")
132-
133-
assert.Equal(reflect.Func, typ.Fields[6].Kind, "7th field is the wrong kind.")
134-
assert.Equal("myFunc", typ.Fields[6].FieldName, "7th field has the wrong name.")
135-
assert.Equal(reflect.String, typ.Fields[6].FuncArgs[0].Kind, "Function argument kind is wrong.")
136-
assert.Equal(reflect.Int, typ.Fields[6].FuncArgs[1].Kind, "Function argument kind is wrong.")
137-
assert.Equal(reflect.Uint, typ.Fields[6].FuncReturnVals[0].Kind, "Function return kind is wrong.")
108+
a.Equal(reflect.Array, typ.Fields[2].Kind, "Third field is the wrong kind.")
109+
a.Equal("myArray", typ.Fields[2].FieldName, "Third field has the wrong name.")
110+
a.Equal(2, typ.Fields[2].Length, "Array length is wrong")
111+
a.Equal(reflect.Int, typ.Fields[2].Element.Kind, "Array element is wrong")
112+
113+
a.Equal(reflect.Slice, typ.Fields[3].Kind, "4th field is the wrong kind.")
114+
a.Equal("mySlice", typ.Fields[3].FieldName, "4th field has the wrong name.")
115+
a.Equal(reflect.Uint, typ.Fields[3].Element.Kind, "Slice element is wrong")
116+
117+
a.Equal(reflect.Chan, typ.Fields[4].Kind, "5th field is the wrong kind.")
118+
a.Equal("myChan", typ.Fields[4].FieldName, "5th field has the wrong name.")
119+
a.Equal(reflect.Struct, typ.Fields[4].Element.Kind, "Chan element is wrong")
120+
a.Equal(ChanBoth, typ.Fields[4].ChanDir, "Chan direction is wrong")
121+
122+
a.Equal(reflect.Map, typ.Fields[5].Kind, "6th field is the wrong kind.")
123+
a.Equal("myMap", typ.Fields[5].FieldName, "6th field has the wrong name.")
124+
a.Equal(reflect.String, typ.Fields[5].Key.Kind, "Map key is wrong")
125+
a.Equal(reflect.Int, typ.Fields[5].Element.Kind, "Map element is wrong")
126+
127+
a.Equal(reflect.Func, typ.Fields[6].Kind, "7th field is the wrong kind.")
128+
a.Equal("myFunc", typ.Fields[6].FieldName, "7th field has the wrong name.")
129+
a.Equal(reflect.String, typ.Fields[6].FuncArgs[0].Kind, "Function argument kind is wrong.")
130+
a.Equal(reflect.Int, typ.Fields[6].FuncArgs[1].Kind, "Function argument kind is wrong.")
131+
a.Equal(reflect.Uint, typ.Fields[6].FuncReturnVals[0].Kind, "Function return kind is wrong.")
138132

139133
// Embedded struct
140-
assert.True(typ.Fields[7].FieldAnon, "Last field should be an anonymous struct")
141-
assert.Equal(reflect.Struct, typ.Fields[7].Kind, "Last field should be an anonymous struct")
142-
assert.Equal("val", typ.Fields[7].Fields[0].FieldName, "Last field's field should be called val")
134+
a.True(typ.Fields[7].FieldAnon, "Last field should be an anonymous struct")
135+
a.Equal(reflect.Struct, typ.Fields[7].Kind, "Last field should be an anonymous struct")
136+
a.Equal("val", typ.Fields[7].Fields[0].FieldName, "Last field's field should be called val")
143137

144138
complexStructTested = true
145139
}
146140

147141
if typ.Name == "cpu.option" && typ.PackagePath == "" &&
148142
GoVersionCompare(f.FileInfo.goversion.Name, "go1.7beta1") >= 0 {
149143
for _, field := range typ.Fields {
150-
assert.Equal("", field.FieldTag, "Field Tag should be empty")
144+
a.Equal("", field.FieldTag, "Field Tag should be empty")
151145
}
152146
}
153147
}
154148
if GoVersionCompare(f.FileInfo.goversion.Name, "go1.7beta1") >= 0 {
155-
assert.True(complexStructTested, "myComplexStruct was not found")
156-
assert.True(stringerInterfaceTested, "fmt.Stringer was not found")
149+
a.True(complexStructTested, "myComplexStruct was not found")
150+
a.True(stringerInterfaceTested, "fmt.Stringer was not found")
157151
}
158-
assert.True(simpleStructTested, "simpleStruct was not found")
152+
a.True(simpleStructTested, "simpleStruct was not found")
159153
})
160154
}
161155
}

0 commit comments

Comments
 (0)