@@ -21,6 +21,7 @@ import (
2121 "fmt"
2222 "go/ast"
2323 "go/constant"
24+ "go/parser"
2425 "go/token"
2526 gotypes "go/types"
2627 "maps"
@@ -37,6 +38,8 @@ import (
3738 "k8s.io/klog/v2"
3839)
3940
41+ var typeAliasEnabled = goTypeAliasEnabled ()
42+
4043// Parser lets you add all the go files in all the packages that you care
4144// about, then constructs the type source data.
4245type Parser struct {
@@ -416,61 +419,81 @@ func minimize(lines []string) []string {
416419func (p * Parser ) addCommentsToType (obj gotypes.Object , t * types.Type ) {
417420 if newLines , oldLines := p .docComment (obj .Pos ()), t .CommentLines ; len (newLines ) > 0 {
418421 switch {
419- case len (oldLines ) == 0 , reflect .DeepEqual (oldLines , newLines ):
422+ case reflect .DeepEqual (oldLines , newLines ):
423+ // nothing needed
424+
425+ case len (oldLines ) == 0 :
420426 // no comments associated, or comments match exactly
421427 t .CommentLines = newLines
422428
423- case isTypeAlias (obj .Type ()):
424- // ignore mismatched comments from obj because it's an alias
425- if ! reflect .DeepEqual (minimize (oldLines ), minimize (newLines )) {
426- klog .Warningf (
427- "Mismatched comments seen for type %v. Using comments:\n %s\n Ignoring comments from type alias:\n %s\n " ,
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" ,
428442 t .GoType ,
429443 formatCommentBlock (oldLines ),
430444 formatCommentBlock (newLines ),
431- )
445+ ))
432446 }
433447
434- case ! isTypeAlias (obj .Type ()):
435- // overwrite existing comments with ones from obj because obj is not an alias
436- t .CommentLines = newLines
448+ case ! typeAliasEnabled :
449+ // ignore mismatched comments from obj because it's an PROBABLY alias
437450 if ! reflect .DeepEqual (minimize (oldLines ), minimize (newLines )) {
438451 klog .Warningf (
439- "Mismatched comments seen for type %v. Using comments:\n %s\n Ignoring comments from type alias:\n %s\n " ,
452+ "Mismatched comments on type %v.\n Using comments:\n %s\n Ignoring comments from presumed type alias:\n %s\n " ,
440453 t .GoType ,
441- formatCommentBlock (newLines ),
442454 formatCommentBlock (oldLines ),
455+ formatCommentBlock (newLines ),
443456 )
444457 }
445458 }
446459 }
447460
448461 if newLines , oldLines := p .priorDetachedComment (obj .Pos ()), t .SecondClosestCommentLines ; len (newLines ) > 0 {
449462 switch {
450- case len (oldLines ) == 0 , reflect .DeepEqual (oldLines , newLines ):
463+ case reflect .DeepEqual (oldLines , newLines ):
464+ // nothing needed
465+
466+ case len (oldLines ) == 0 :
451467 // no comments associated, or comments match exactly
452468 t .SecondClosestCommentLines = newLines
453469
454- case isTypeAlias (obj .Type ()):
455- // ignore mismatched comments from obj because it's an alias
456- if ! reflect .DeepEqual (minimize (oldLines ), minimize (newLines )) {
457- klog .Warningf (
458- "Mismatched secondClosestCommentLines seen for type %v. Using comments:\n %s\n Ignoring comments from type alias:\n %s\n " ,
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" ,
459483 t .GoType ,
460484 formatCommentBlock (oldLines ),
461485 formatCommentBlock (newLines ),
462- )
486+ ))
463487 }
464488
465- case ! isTypeAlias (obj .Type ()):
466- // overwrite existing comments with ones from obj because obj is not an alias
467- t .SecondClosestCommentLines = newLines
489+ case ! typeAliasEnabled :
490+ // ignore mismatched comments from obj because it's an PROBABLY alias
468491 if ! reflect .DeepEqual (minimize (oldLines ), minimize (newLines )) {
469492 klog .Warningf (
470- "Mismatched secondClosestCommentLines seen for type %v. Using comments:\n %s\n Ignoring comments from type alias:\n %s\n " ,
493+ "Mismatched secondClosestCommentLines on type %v.\n Using comments:\n %s\n Ignoring comments from presumed type alias:\n %s\n " ,
471494 t .GoType ,
472- formatCommentBlock (newLines ),
473495 formatCommentBlock (oldLines ),
496+ formatCommentBlock (newLines ),
474497 )
475498 }
476499 }
@@ -984,3 +1007,22 @@ func (p *Parser) addConstant(u types.Universe, useName *types.Name, in *gotypes.
9841007 out .ConstValue = & constval
9851008 return out
9861009}
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+ }
0 commit comments