@@ -539,6 +539,9 @@ type analysisNode struct {
539
539
typesOnce sync.Once // guards lazy population of types and typesErr fields
540
540
types * types.Package // type information lazily imported from summary
541
541
typesErr error // an error producing type information
542
+
543
+ depHashOnce sync.Once
544
+ _depHash file.Hash // memoized hash of data affecting dependents
542
545
}
543
546
544
547
func (an * analysisNode ) String () string { return string (an .mp .ID ) }
@@ -597,6 +600,40 @@ func (an *analysisNode) _import() (*types.Package, error) {
597
600
return an .types , an .typesErr
598
601
}
599
602
603
+ // depHash computes the hash of node information that may affect other nodes
604
+ // depending on this node: the package path, export hash, and action results.
605
+ //
606
+ // The result is memoized to avoid redundant work when analysing multiple
607
+ // dependents.
608
+ func (an * analysisNode ) depHash () file.Hash {
609
+ an .depHashOnce .Do (func () {
610
+ hasher := sha256 .New ()
611
+ fmt .Fprintf (hasher , "dep: %s\n " , an .mp .PkgPath )
612
+ fmt .Fprintf (hasher , "export: %s\n " , an .summary .DeepExportHash )
613
+
614
+ // action results: errors and facts
615
+ actions := an .summary .Actions
616
+ names := make ([]string , 0 , len (actions ))
617
+ for name := range actions {
618
+ names = append (names , name )
619
+ }
620
+ sort .Strings (names )
621
+ for _ , name := range names {
622
+ summary := actions [name ]
623
+ fmt .Fprintf (hasher , "action %s\n " , name )
624
+ if summary .Err != "" {
625
+ fmt .Fprintf (hasher , "error %s\n " , summary .Err )
626
+ } else {
627
+ fmt .Fprintf (hasher , "facts %s\n " , summary .FactsHash )
628
+ // We can safely omit summary.diagnostics
629
+ // from the key since they have no downstream effect.
630
+ }
631
+ }
632
+ hasher .Sum (an ._depHash [:0 ])
633
+ })
634
+ return an ._depHash
635
+ }
636
+
600
637
// analyzeSummary is a gob-serializable summary of successfully
601
638
// applying a list of analyzers to a package.
602
639
type analyzeSummary struct {
@@ -770,27 +807,8 @@ func (an *analysisNode) cacheKey() [sha256.Size]byte {
770
807
771
808
// vdeps, in PackageID order
772
809
for _ , vdep := range moremaps .Sorted (an .succs ) {
773
- fmt .Fprintf (hasher , "dep: %s\n " , vdep .mp .PkgPath )
774
- fmt .Fprintf (hasher , "export: %s\n " , vdep .summary .DeepExportHash )
775
-
776
- // action results: errors and facts
777
- actions := vdep .summary .Actions
778
- names := make ([]string , 0 , len (actions ))
779
- for name := range actions {
780
- names = append (names , name )
781
- }
782
- sort .Strings (names )
783
- for _ , name := range names {
784
- summary := actions [name ]
785
- fmt .Fprintf (hasher , "action %s\n " , name )
786
- if summary .Err != "" {
787
- fmt .Fprintf (hasher , "error %s\n " , summary .Err )
788
- } else {
789
- fmt .Fprintf (hasher , "facts %s\n " , summary .FactsHash )
790
- // We can safely omit summary.diagnostics
791
- // from the key since they have no downstream effect.
792
- }
793
- }
810
+ hash := vdep .depHash ()
811
+ hasher .Write (hash [:])
794
812
}
795
813
796
814
var hash [sha256 .Size ]byte
0 commit comments