Skip to content

Commit 2c925f5

Browse files
Fixing serialization of files for go1.20
1 parent d01b7cf commit 2c925f5

File tree

3 files changed

+55
-20
lines changed

3 files changed

+55
-20
lines changed

compiler/sources/serializer.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,15 @@ func (s *Sources) Read(decode func(any) error) error {
104104
if err := decode(&s.Files); err != nil {
105105
return err
106106
}
107-
for _, f := range s.Files {
108-
unpackFile(f)
109-
}
110107
if s.FileSet == nil {
111108
s.FileSet = token.NewFileSet()
112109
}
113110
if err := s.FileSet.Read(decode); err != nil {
114111
return err
115112
}
113+
for _, f := range s.Files {
114+
unpackFile(f, s.FileSet)
115+
}
116116
if err := decode(&s.JSFiles); err != nil {
117117
return err
118118
}
@@ -153,9 +153,14 @@ func prepareFile(file *ast.File) *ast.File {
153153
return file
154154
}
155155

156+
// finishUnpackingFile is an optional function that is run after unpacking
157+
// a file during deserialization to perform any additional processing needed
158+
// for specific Go versions.
159+
var finishUnpackingFile func(f *ast.File, fs *token.FileSet)
160+
156161
// unpackFile is run when deserializing a source to reconstruct the
157162
// Imports and Comments fields that were cleared when serializing the file.
158-
func unpackFile(file *ast.File) {
163+
func unpackFile(file *ast.File, fs *token.FileSet) {
159164
var imports []*ast.ImportSpec
160165
var comments []*ast.CommentGroup
161166
ast.Inspect(file, func(n ast.Node) bool {
@@ -169,6 +174,9 @@ func unpackFile(file *ast.File) {
169174
})
170175
file.Imports = imports
171176
file.Comments = comments
177+
if finishUnpackingFile != nil {
178+
finishUnpackingFile(file, fs)
179+
}
172180
}
173181

174182
// prepareGob registers the AST node types with the gob package
@@ -181,6 +189,13 @@ func unpackFile(file *ast.File) {
181189
// an interface field in the AST.
182190
var prepareGob = func() func() {
183191
registerTypes := func() {
192+
gob.Register(token.NoPos)
193+
gob.Register(&ast.File{})
194+
gob.Register(&ast.Comment{})
195+
gob.Register(&ast.CommentGroup{})
196+
gob.Register(&ast.Field{})
197+
gob.Register(&ast.FieldList{})
198+
184199
// Register expression nodes.
185200
gob.Register(&ast.BadExpr{})
186201
gob.Register(&ast.Ident{})

compiler/sources/serializer_120.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//go:build go1.20
2+
3+
package sources
4+
5+
import (
6+
"fmt"
7+
"go/ast"
8+
"go/token"
9+
)
10+
11+
func init() {
12+
finishUnpackingFile = finishUnpackingFile120
13+
}
14+
15+
// finishUnpackingFile120 performs additional processing needed
16+
// after unpacking a file during deserialization for Go 1.20+.
17+
//
18+
// Specifically, it sets the FileStart and FileEnd fields
19+
// that were added in Go 1.20 to ensure correct position calculations
20+
// used by the type checker (when checking file versions).
21+
// For some reason the gob encoding/decoding isn't automatically setting this.
22+
//
23+
// TODO(grantnelson-wf): Determine why the gob encoding/decoding isn't doing this automatically.
24+
func finishUnpackingFile120(f *ast.File, fs *token.FileSet) {
25+
fp := fs.File(f.Pos())
26+
if fp == nil {
27+
panic(fmt.Errorf(`failed to find token.File for ast.File (in %s at %d) during unpacking`, f.Name.Name, f.Pos()))
28+
}
29+
30+
if !f.FileStart.IsValid() {
31+
f.FileStart = token.Pos(fp.Base())
32+
}
33+
if !f.FileEnd.IsValid() {
34+
f.FileEnd = token.Pos(fp.Base() + fp.Size())
35+
}
36+
}

compiler/sources/sources.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package sources
22

33
import (
4-
"fmt"
54
"go/ast"
65
"go/token"
76
"go/types"
@@ -138,21 +137,6 @@ func (s *Sources) TypeCheck(importer Importer, sizes types.Sizes, tContext *type
138137
Sizes: sizes,
139138
Error: func(err error) { typeErrs = typeErrs.AppendDistinct(err) },
140139
}
141-
142-
if s.ImportPath == `internal/goarch` { // TODO(grantnelson-wf): Remove
143-
fmt.Println("Type checking package:", s.ImportPath)
144-
s.FileSet.Iterate(func(f *token.File) bool {
145-
fmt.Println(` File:`, f.Name(), `Base:`, f.Base(), `Size:`, f.Size())
146-
return true
147-
})
148-
for _, f := range s.Files {
149-
fmt.Println(` Pos:`, f.Pos(), `End:`, f.End())
150-
if s.FileSet.File(f.Pos()) == nil {
151-
fmt.Println(` Failed to find file`)
152-
}
153-
}
154-
}
155-
156140
typesPkg, err := config.Check(s.ImportPath, s.FileSet, s.Files, typesInfo)
157141
// If we encountered any import errors, it is likely that the other type errors
158142
// are not meaningful and would be resolved by fixing imports. Return them

0 commit comments

Comments
 (0)