bind method

Callable bind(
  1. RuntimeValue instance
)

Binds 'this' to a specific instance, returning a new callable where the closure has 'this' defined.

Implementation

Callable bind(RuntimeValue instance) {
  if (ownerType == null) {
    // Check ownerType instead of definingClass
    throw RuntimeD4rtException(
        "Cannot bind 'this' to a non-method function.");
  }
  // Create a new environment that encloses the original function closure,
  // but defines 'this' locally.
  final boundEnvironment = Environment(enclosing: closure);
  boundEnvironment.define('this', instance);

  // Define class type parameters in bound environment
  if (instance is InterpretedInstance && ownerType is InterpretedClass) {
    final klass = ownerType as InterpretedClass;
    final instTypeArgs = instance.typeArguments ?? [];
    for (int i = 0; i < klass.typeParameterNames.length; i++) {
      final paramName = klass.typeParameterNames[i];
      final typeArg = i < instTypeArgs.length
          ? instTypeArgs[i]
          : TypeParameter(paramName);
      boundEnvironment.define(paramName, typeArg);
    }
  }

  // G-DOV3-1 FIX: Handle extension type instances - define the representation field
  // so that `value` (or whatever the field is named) is accessible in the getter/method body
  if (instance is InterpretedExtensionTypeInstance &&
      ownerType is InterpretedExtensionType) {
    final extType = ownerType as InterpretedExtensionType;
    // Define the representation field name (e.g., 'value') to point to the wrapped value
    boundEnvironment.define(
        extType.representationFieldName, instance.representationValue);
  }

  // Create a new function *instance* that uses the bound environment
  // Need to ensure all relevant properties (isGetter, isSetter, etc.) are copied.
  final boundFunction = InterpretedFunction._internal(
    _parameters,
    _body,
    boundEnvironment,
    _name,
    isInitializer: isInitializer,
    constructorInitializers: _constructorInitializers,
    isGetter: isGetter,
    isSetter: isSetter,
    ownerType: ownerType, // Pass ownerType
    isAbstract: isAbstract,
    isAsync: isAsync,
    isGenerator: isGenerator,
    isAsyncGenerator: isAsyncGenerator,
    isFactory: isFactory, // Copy the factory flag
    redirectedFactoryTarget: redirectedFactoryTarget, // Copy redirect target
    declaredReturnType: declaredReturnType,
    typeParameterNames: typeParameterNames, // Copy type parameter names
    typeParameterBounds: typeParameterBounds, // Copy type parameter bounds
  );
  return boundFunction;
}