diff --git a/internal/pkg/ir.go b/internal/pkg/ir.go index 72a2c90c..366d9ca0 100644 --- a/internal/pkg/ir.go +++ b/internal/pkg/ir.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "io" + "iter" "slices" "strconv" "sync" @@ -65,6 +66,18 @@ func NewIR() *IRCache { return &IRCache{zeroIRCache()} } +// Inputs returns an iterator over direct and transitive inputs of an [Artifact] +// in randomised order. +func Inputs(a Artifact) iter.Seq2[Artifact, unique.Handle[ID]] { + ic := NewIR() + ic.Ident(a) + return func(yield func(Artifact, unique.Handle[ID]) bool) { + ic.artifact.Range(func(key, value any) bool { + return yield(key.(Artifact), value.(unique.Handle[ID])) + }) + } +} + // IContext is passed to [Artifact.Params] and provides methods for writing // values to the IR writer. It does not expose the underlying [io.Writer]. // diff --git a/internal/rosa/llvm_test.go b/internal/rosa/llvm_test.go new file mode 100644 index 00000000..de63cb6b --- /dev/null +++ b/internal/rosa/llvm_test.go @@ -0,0 +1,21 @@ +package rosa_test + +import ( + "testing" + + "hakurei.app/internal/pkg" + "hakurei.app/internal/rosa" +) + +func TestLLVMInputs(t *testing.T) { + const wantInputCount = 688 + + _, llvm := rosa.Native().Std().MustLoad(rosa.H("llvm")) + var n int + for range pkg.Inputs(llvm) { + n++ + } + if n != wantInputCount { + t.Errorf("Inputs: %d, want %d", n, wantInputCount) + } +}