@@ -196,19 +196,41 @@ func (c *Context[T]) Render(a, e, changes Task[T]) error {
196196
197197 targetType := reflect .ValueOf (c .Target ).Type ()
198198
199- var renderer * reflect.Method
199+ // Probe renderers with literal method names only: enumerating the method set or passing a
200+ // variable name to MethodByName would disable linker pruning of every unused exported method.
201+ candidates := []struct {
202+ name string
203+ method reflect.Value
204+ }{
205+ {"Render" , v .MethodByName ("Render" )},
206+ {"RenderAWS" , v .MethodByName ("RenderAWS" )},
207+ {"RenderAzure" , v .MethodByName ("RenderAzure" )},
208+ {"RenderDO" , v .MethodByName ("RenderDO" )},
209+ {"RenderGCE" , v .MethodByName ("RenderGCE" )},
210+ {"RenderHetzner" , v .MethodByName ("RenderHetzner" )},
211+ {"RenderInstall" , v .MethodByName ("RenderInstall" )},
212+ {"RenderLinode" , v .MethodByName ("RenderLinode" )},
213+ {"RenderLocal" , v .MethodByName ("RenderLocal" )},
214+ {"RenderOpenstack" , v .MethodByName ("RenderOpenstack" )},
215+ {"RenderScw" , v .MethodByName ("RenderScw" )},
216+ {"RenderSubnet" , v .MethodByName ("RenderSubnet" )},
217+ {"RenderTerraform" , v .MethodByName ("RenderTerraform" )},
218+ }
219+
220+ var rendererName string
221+ var renderer reflect.Value
200222 var rendererArgs []reflect.Value
201223
202- for i := 0 ; i < vType .NumMethod (); i ++ {
203- method := vType .Method (i )
204- if ! strings .HasPrefix (method .Name , "Render" ) {
224+ for _ , candidate := range candidates {
225+ if ! candidate .method .IsValid () {
205226 continue
206227 }
228+ mType := candidate .method .Type ()
207229 match := true
208230
209231 var args []reflect.Value
210- for j := 0 ; j < method . Type .NumIn (); j ++ {
211- arg := method . Type .In (j )
232+ for j := 0 ; j < mType .NumIn (); j ++ {
233+ arg := mType .In (j )
212234 if vType .ConvertibleTo (arg ) {
213235 continue
214236 }
@@ -224,28 +246,28 @@ func (c *Context[T]) Render(a, e, changes Task[T]) error {
224246 break
225247 }
226248 if match {
227- if renderer != nil {
228- if method . Name == "Render" {
249+ if renderer . IsValid () {
250+ if candidate . name == "Render" {
229251 continue
230252 }
231- if renderer . Name != "Render" {
253+ if rendererName != "Render" {
232254 return fmt .Errorf ("found multiple Render methods that could be involved on %T" , e )
233255 }
234256 }
235- renderer = & method
257+ rendererName = candidate .name
258+ renderer = candidate .method
236259 rendererArgs = args
237260 }
238261
239262 }
240- if renderer == nil {
263+ if ! renderer . IsValid () {
241264 return fmt .Errorf ("could not find Render method on type %T (target %T)" , e , c .Target )
242265 }
243266 rendererArgs = append (rendererArgs , reflect .ValueOf (a ))
244267 rendererArgs = append (rendererArgs , reflect .ValueOf (e ))
245268 rendererArgs = append (rendererArgs , reflect .ValueOf (changes ))
246- klog .V (11 ).Infof ("Calling method %s on %T" , renderer .Name , e )
247- m := v .MethodByName (renderer .Name )
248- rv := m .Call (rendererArgs )
269+ klog .V (11 ).Infof ("Calling method %s on %T" , rendererName , e )
270+ rv := renderer .Call (rendererArgs )
249271 var rvErr error
250272 if ! rv [0 ].IsNil () {
251273 rvErr = rv [0 ].Interface ().(error )
0 commit comments