@@ -194,18 +194,19 @@ func (c *Cache) Type(id dst.Ident, contextPkg string, testImport bool) (TypeInfo
194194 }, nil
195195}
196196
197- // IsComparable determines if an expression is comparable
198- func (c * Cache ) IsComparable (expr dst.Expr ) (bool , error ) {
199- return c .isDefaultComparable (expr , true )
197+ // IsComparable determines if an expression is comparable. The optional
198+ // parentType can be used to supply type parameters.
199+ func (c * Cache ) IsComparable (expr dst.Expr , parentType TypeInfo ) (bool , error ) {
200+ return c .isDefaultComparable (expr , & parentType , true )
200201}
201202
202203// IsDefaultComparable determines if an expression is comparable. Returns the
203204// same results as IsComparable but pointers and interfaces are not comparable
204205// by default (interface implementations that are not comparable and put into a
205206// map key will panic at runtime and by default pointers use a deep hash to be
206207// comparable).
207- func (c * Cache ) IsDefaultComparable (expr dst.Expr ) (bool , error ) {
208- return c .isDefaultComparable (expr , false )
208+ func (c * Cache ) IsDefaultComparable (expr dst.Expr , parentType TypeInfo ) (bool , error ) {
209+ return c .isDefaultComparable (expr , & parentType , false )
209210}
210211
211212// FindPackage finds the package for a given directory
@@ -363,17 +364,21 @@ func isExported(name, pkgPath string) bool {
363364 return false
364365}
365366
366- func (c * Cache ) isDefaultComparable (expr dst.Expr , interfacePointerDefault bool ) (bool , error ) {
367+ func (c * Cache ) isDefaultComparable (
368+ expr dst.Expr ,
369+ parentType * TypeInfo ,
370+ interfacePointerDefault bool ,
371+ ) (bool , error ) {
367372 switch e := expr .(type ) {
368373 case * dst.ArrayType :
369374 if e .Len == nil {
370375 return false , nil
371376 }
372- return c .isDefaultComparable (e .Elt , interfacePointerDefault )
373- case * dst.MapType , * dst.Ellipsis , * dst.FuncType :
377+ return c .isDefaultComparable (e .Elt , parentType , interfacePointerDefault )
378+ case * dst.Ellipsis :
379+ return false , nil
380+ case * dst.FuncType :
374381 return false , nil
375- case * dst.StarExpr :
376- return interfacePointerDefault , nil
377382 case * dst.InterfaceType :
378383 return interfacePointerDefault , nil
379384 case * dst.Ident :
@@ -387,11 +392,22 @@ func (c *Cache) isDefaultComparable(expr dst.Expr, interfacePointerDefault bool)
387392 return true , nil
388393 }
389394
390- return c .isDefaultComparable (typ .Type , interfacePointerDefault )
395+ return c .isDefaultComparable (typ .Type , parentType , interfacePointerDefault )
391396 }
397+ pkgPath := e .Path
392398 typ , ok := c .typesByIdent [e .String ()]
399+ if ! ok && e .Path == "" && parentType != nil {
400+ pkgPath = parentType .PkgPath
401+ typ , ok = c .typesByIdent [IdPath (e .Name , parentType .PkgPath ).String ()]
402+ }
393403 if ok {
394- return c .isDefaultComparable (typ .typ .Type , interfacePointerDefault )
404+ tInfo := & TypeInfo {
405+ Type : typ .typ ,
406+ PkgPath : pkgPath ,
407+ Exported : isExported (e .Name , pkgPath ),
408+ Fabricated : false ,
409+ }
410+ return c .isDefaultComparable (typ .typ .Type , tInfo , interfacePointerDefault )
395411 }
396412
397413 // Builtin type?
@@ -412,10 +428,18 @@ func (c *Cache) isDefaultComparable(expr dst.Expr, interfacePointerDefault bool)
412428
413429 typ , ok = c .typesByIdent [e .String ()]
414430 if ok {
415- return c .isDefaultComparable (typ .typ .Type , interfacePointerDefault )
431+ tInfo := & TypeInfo {
432+ Type : typ .typ ,
433+ PkgPath : e .Path ,
434+ Exported : isExported (e .Name , e .Path ),
435+ Fabricated : false ,
436+ }
437+ return c .isDefaultComparable (typ .typ .Type , tInfo , interfacePointerDefault )
416438 }
417439
418440 return true , nil
441+ case * dst.MapType :
442+ return false , nil
419443 case * dst.SelectorExpr :
420444 ex , ok := e .X .(* dst.Ident )
421445 if ! ok {
@@ -429,14 +453,16 @@ func (c *Cache) isDefaultComparable(expr dst.Expr, interfacePointerDefault bool)
429453
430454 typ , ok := c .typesByIdent [IdPath (e .Sel .Name , path ).String ()]
431455 if ok {
432- return c .isDefaultComparable (typ .typ .Type , interfacePointerDefault )
456+ return c .isDefaultComparable (typ .typ .Type , parentType , interfacePointerDefault )
433457 }
434458
435459 // Builtin type?
436460 return true , nil
461+ case * dst.StarExpr :
462+ return interfacePointerDefault , nil
437463 case * dst.StructType :
438464 for _ , f := range e .Fields .List {
439- comp , err := c .isDefaultComparable (f .Type , interfacePointerDefault )
465+ comp , err := c .isDefaultComparable (f .Type , parentType , interfacePointerDefault )
440466 if err != nil || ! comp {
441467 return false , err
442468 }
@@ -501,19 +527,6 @@ func (c *Cache) loadTypes(loadPkg string, testImport bool) (string, error) {
501527}
502528
503529func (c * Cache ) loadAST (loadPkg string , testImport bool ) ([]* pkgInfo , error ) {
504- if dp , ok := c .loadedPkgs [loadPkg ]; ok {
505- // If we already loaded the test types or if the test types aren't
506- // requested, we're done
507- if dp .loadTestPkgs || ! testImport {
508- // If we direct loaded, we're done
509- if dp .directLoaded {
510- c .metrics .ASTTypeCacheHitsInc ()
511- return []* pkgInfo {dp }, nil
512- }
513- }
514- }
515- c .metrics .ASTTypeCacheMissesInc ()
516-
517530 start := time .Now ()
518531 pkgs , err := c .load (& packages.Config {
519532 Mode : packages .NeedName |
@@ -597,7 +610,6 @@ func (c *Cache) convert(pkg *packages.Package, testImport, directLoaded bool) (*
597610
598611 start := time .Now ()
599612 p .pkg .Decorator = decorator .NewDecoratorFromPackage (pkg )
600- p .pkg .Decorator .ResolveLocalPath = true
601613 for _ , f := range pkg .Syntax {
602614 fpath := pkg .Fset .File (f .Pos ()).Name ()
603615 if ! goFiles [fpath ] {
0 commit comments