createMethodWrapper creates a ClassMethodFunc wrapper around a reflect.Method
(method reflect.Method)
| 340 | |
| 341 | // createMethodWrapper creates a ClassMethodFunc wrapper around a reflect.Method |
| 342 | func createMethodWrapper(method reflect.Method) ClassMethodFunc { |
| 343 | return func(ctx *Context, this *Value, args []*Value) *Value { |
| 344 | objValue, err := getValidObjectValue(ctx, this) |
| 345 | if err != nil { |
| 346 | return ctx.ThrowError(err) |
| 347 | } |
| 348 | |
| 349 | // Ensure we have a pointer receiver if the method requires it |
| 350 | if objValue.Kind() != reflect.Ptr && method.Type.In(0).Kind() == reflect.Ptr { |
| 351 | // In our implementation, objValue is always addressable because it comes |
| 352 | // from reflect.New().Elem(), so we can safely take its address |
| 353 | objValue = objValue.Addr() |
| 354 | } |
| 355 | |
| 356 | // Get the method value |
| 357 | methodValue := objValue.Method(method.Index) |
| 358 | |
| 359 | // Convert JavaScript arguments to Go method arguments |
| 360 | methodArgs, err := convertJSArgsToMethodArgs(&method, args, ctx) |
| 361 | if err != nil { |
| 362 | return ctx.ThrowError(fmt.Errorf("failed to prepare method arguments: %w", err)) |
| 363 | } |
| 364 | |
| 365 | // Call the method |
| 366 | results := methodValue.Call(methodArgs) |
| 367 | |
| 368 | // Convert results back to JavaScript values |
| 369 | return convertMethodResults(results, ctx) |
| 370 | } |
| 371 | } |
| 372 | |
| 373 | // createFieldGetter creates a getter function for a struct field |
| 374 | func createFieldGetter(field reflect.StructField, fieldIndex int) ClassGetterFunc { |
no test coverage detected