Skip to content

Commit 5026bc0

Browse files
committed
Revert to alias handling which does not assume visit order
1 parent 1d469b8 commit 5026bc0

File tree

2 files changed

+66
-58
lines changed

2 files changed

+66
-58
lines changed

v2/parser/parse.go

Lines changed: 33 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"fmt"
2222
"go/ast"
2323
"go/constant"
24-
"go/parser"
2524
"go/token"
2625
gotypes "go/types"
2726
"maps"
@@ -38,8 +37,6 @@ import (
3837
"k8s.io/klog/v2"
3938
)
4039

41-
var typeAliasEnabled = goTypeAliasEnabled()
42-
4340
// Parser lets you add all the go files in all the packages that you care
4441
// about, then constructs the type source data.
4542
type Parser struct {
@@ -426,33 +423,31 @@ func (p *Parser) addCommentsToType(obj gotypes.Object, t *types.Type) {
426423
// no comments associated, or comments match exactly
427424
t.CommentLines = newLines
428425

429-
case typeAliasEnabled:
430-
if isTypeAlias(obj.Type()) {
431-
if !reflect.DeepEqual(minimize(oldLines), minimize(newLines)) {
432-
// ignore mismatched comments from obj because it's an alias
433-
klog.Warningf(
434-
"Mismatched comments on type %v.\n Using comments:\n%s\n Ignoring comments from type alias:\n%s\n",
435-
t.GoType,
436-
formatCommentBlock(oldLines),
437-
formatCommentBlock(newLines),
438-
)
439-
}
440-
} else {
441-
panic(fmt.Sprintf("type %v already has comments; somehow we processed it again, but it's not an alias\n old:\n%s\n new:\n%s",
426+
case isTypeAlias(obj.Type()):
427+
// Ignore mismatched comments from obj because it's an alias.
428+
// This can only be hit if gotypesalias is enabled.
429+
if !reflect.DeepEqual(minimize(oldLines), minimize(newLines)) {
430+
klog.Warningf(
431+
"Mismatched comments on type %v.\n Using comments:\n%s\n Ignoring comments from type alias:\n%s\n",
442432
t.GoType,
443433
formatCommentBlock(oldLines),
444434
formatCommentBlock(newLines),
445-
))
435+
)
446436
}
447437

448-
case !typeAliasEnabled:
449-
// ignore mismatched comments from obj because it's an PROBABLY alias
438+
case !isTypeAlias(obj.Type()):
439+
// Overwrite existing comments with ones from obj because obj is not an alias.
440+
// If gotypesalias is enabled, this should mean we found the "real"
441+
// type, not an alias. If gotypesalias is disabled, we can end up
442+
// overwriting the "real" comments with an alias's comments, but
443+
// it is not clear if we can assume which one is the "real" one.
444+
t.CommentLines = newLines
450445
if !reflect.DeepEqual(minimize(oldLines), minimize(newLines)) {
451446
klog.Warningf(
452-
"Mismatched comments on type %v.\n Using comments:\n%s\n Ignoring comments from presumed type alias:\n%s\n",
447+
"Mismatched comments on type %v.\n Using comments:\n%s\n Ignoring comments from possible type alias:\n%s\n",
453448
t.GoType,
454-
formatCommentBlock(oldLines),
455449
formatCommentBlock(newLines),
450+
formatCommentBlock(oldLines),
456451
)
457452
}
458453
}
@@ -467,33 +462,32 @@ func (p *Parser) addCommentsToType(obj gotypes.Object, t *types.Type) {
467462
// no comments associated, or comments match exactly
468463
t.SecondClosestCommentLines = newLines
469464

470-
case typeAliasEnabled:
471-
if isTypeAlias(obj.Type()) {
472-
if !reflect.DeepEqual(minimize(oldLines), minimize(newLines)) {
473-
// ignore mismatched comments from obj because it's an alias
474-
klog.Warningf(
475-
"Mismatched secondClosestCommentLines on type %v.\n Using comments:\n%s\n Ignoring comments from type alias:\n%s\n",
476-
t.GoType,
477-
formatCommentBlock(oldLines),
478-
formatCommentBlock(newLines),
479-
)
480-
}
481-
} else {
482-
panic(fmt.Sprintf("type %v already has comments; somehow we processed it again, but it's not an alias\n old:\n%s\n new:\n%s",
465+
case isTypeAlias(obj.Type()):
466+
// Ignore mismatched comments from obj because it's an alias.
467+
// This can only be hit if gotypesalias is enabled.
468+
if !reflect.DeepEqual(minimize(oldLines), minimize(newLines)) {
469+
// ignore mismatched comments from obj because it's an alias
470+
klog.Warningf(
471+
"Mismatched secondClosestCommentLines on type %v.\n Using comments:\n%s\n Ignoring comments from type alias:\n%s\n",
483472
t.GoType,
484473
formatCommentBlock(oldLines),
485474
formatCommentBlock(newLines),
486-
))
475+
)
487476
}
488477

489-
case !typeAliasEnabled:
490-
// ignore mismatched comments from obj because it's an PROBABLY alias
478+
case !isTypeAlias(obj.Type()):
479+
// Overwrite existing comments with ones from obj because obj is not an alias.
480+
// If gotypesalias is enabled, this should mean we found the "real"
481+
// type, not an alias. If gotypesalias is disabled, we can end up
482+
// overwriting the "real" comments with an alias's comments, but
483+
// it is not clear if we can assume which one is the "real" one.
484+
t.SecondClosestCommentLines = newLines
491485
if !reflect.DeepEqual(minimize(oldLines), minimize(newLines)) {
492486
klog.Warningf(
493-
"Mismatched secondClosestCommentLines on type %v.\n Using comments:\n%s\n Ignoring comments from presumed type alias:\n%s\n",
487+
"Mismatched secondClosestCommentLines on type %v.\n Using comments:\n%s\n Ignoring comments from possible type alias:\n%s\n",
494488
t.GoType,
495-
formatCommentBlock(oldLines),
496489
formatCommentBlock(newLines),
490+
formatCommentBlock(oldLines),
497491
)
498492
}
499493
}
@@ -1007,22 +1001,3 @@ func (p *Parser) addConstant(u types.Universe, useName *types.Name, in *gotypes.
10071001
out.ConstValue = &constval
10081002
return out
10091003
}
1010-
1011-
// Copied from https://github.com/golang/tools/blob/3e377036196f644e59e757af8a38ea6afa07677c/internal/aliases/aliases_go122.go#L64
1012-
func goTypeAliasEnabled() bool {
1013-
// The only reliable way to compute the answer is to invoke go/types.
1014-
// We don't parse the GODEBUG environment variable, because
1015-
// (a) it's tricky to do so in a manner that is consistent
1016-
// with the godebug package; in particular, a simple
1017-
// substring check is not good enough. The value is a
1018-
// rightmost-wins list of options. But more importantly:
1019-
// (b) it is impossible to detect changes to the effective
1020-
// setting caused by os.Setenv("GODEBUG"), as happens in
1021-
// many tests. Therefore any attempt to cache the result
1022-
// is just incorrect.
1023-
fset := token.NewFileSet()
1024-
f, _ := parser.ParseFile(fset, "a.go", "package p; type A = int", parser.SkipObjectResolution)
1025-
pkg, _ := new(gotypes.Config).Check("p", fset, []*ast.File{f}, nil)
1026-
_, enabled := pkg.Scope().Lookup("A").Type().(*gotypes.Alias)
1027-
return enabled
1028-
}

v2/parser/parse_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ package parser
1919
import (
2020
"encoding/json"
2121
"fmt"
22+
"go/ast"
23+
"go/parser"
24+
"go/token"
25+
gotypes "go/types"
2226
"path/filepath"
2327
"reflect"
2428
"sort"
@@ -30,6 +34,8 @@ import (
3034
"k8s.io/gengo/v2/types"
3135
)
3236

37+
var typeAliasEnabled = goTypeAliasEnabled()
38+
3339
func TestNew(t *testing.T) {
3440
parser := New()
3541
if parser.goPkgs == nil {
@@ -1115,6 +1121,10 @@ func TestStructParse(t *testing.T) {
11151121
},
11161122
expected: func() *types.Type {
11171123
expectedTypeComments := []string{"Blah is a test.", "A test, I tell you."}
1124+
if !typeAliasEnabled {
1125+
// Comments from the last processed package wins.
1126+
expectedTypeComments = []string{"This is an alias for v1.Blah."}
1127+
}
11181128

11191129
return &types.Type{
11201130
Name: types.Name{
@@ -1221,6 +1231,10 @@ func TestCommentsWithAliasedType(t *testing.T) {
12211231
}
12221232

12231233
expectedTypeComments := []string{"Blah is a test.", "A test, I tell you."}
1234+
if !typeAliasEnabled {
1235+
// Comments from the last processed package wins.
1236+
expectedTypeComments = []string{"This is an alias for v1.Blah."}
1237+
}
12241238
for _, typ := range pkg.Types {
12251239
if typ.Name.Name != "Blah" {
12261240
continue
@@ -1232,3 +1246,22 @@ func TestCommentsWithAliasedType(t *testing.T) {
12321246
}
12331247
}
12341248
}
1249+
1250+
// Copied from https://github.com/golang/tools/blob/3e377036196f644e59e757af8a38ea6afa07677c/internal/aliases/aliases_go122.go#L64
1251+
func goTypeAliasEnabled() bool {
1252+
// The only reliable way to compute the answer is to invoke go/types.
1253+
// We don't parse the GODEBUG environment variable, because
1254+
// (a) it's tricky to do so in a manner that is consistent
1255+
// with the godebug package; in particular, a simple
1256+
// substring check is not good enough. The value is a
1257+
// rightmost-wins list of options. But more importantly:
1258+
// (b) it is impossible to detect changes to the effective
1259+
// setting caused by os.Setenv("GODEBUG"), as happens in
1260+
// many tests. Therefore any attempt to cache the result
1261+
// is just incorrect.
1262+
fset := token.NewFileSet()
1263+
f, _ := parser.ParseFile(fset, "a.go", "package p; type A = int", parser.SkipObjectResolution)
1264+
pkg, _ := new(gotypes.Config).Check("p", fset, []*ast.File{f}, nil)
1265+
_, enabled := pkg.Scope().Lookup("A").Type().(*gotypes.Alias)
1266+
return enabled
1267+
}

0 commit comments

Comments
 (0)