set method

  1. @override
void set(
  1. String name,
  2. Object? value, [
  3. InterpreterVisitor? visitor
])
override

Sets a property of this value.

Implementation

@override
void set(String name, Object? value, [InterpreterVisitor? visitor]) {
  Logger.debug(
      "[Instance.set] called for '${klass.name}.$name' with value: $value on instance $hashCode");
  // Look for a setter in the current class and superclasses
  InterpretedClass? currentClass = klass;
  while (currentClass != null) {
    final setter = currentClass.findInstanceSetter(name);
    if (setter != null) {
      // Found a setter, call it on the original instance ('this')
      setter.bind(this).call(visitor!, [value], {});
      return; // Setter called, assignment done
    }

    // Check bridged superclass at this level before moving up.
    // C19: Mirror the read-path pattern (line ~1319) and fall back to
    // `nativeProxy` when `bridgedSuperObject` is null. Interface-proxy
    // factories (e.g. _InterpretedRenderAligningShiftedBox) install
    // themselves on `nativeProxy` because the abstract bridged super
    // has no constructor adapter to populate `bridgedSuperObject`.
    // Without this fallback, `script.size = …` lands in `_fields`
    // instead of routing to the bridged setter, leaving the proxy's
    // real `_size` unset and tripping `hasSize`/`alignChild` asserts.
    if (currentClass.bridgedSuperclass != null) {
      final nativeTarget = bridgedSuperObject ?? nativeProxy;
      if (nativeTarget != null) {
        final bridgedSuper = currentClass.bridgedSuperclass!;
        final setterAdapter = bridgedSuper.findInstanceSetterAdapter(name);

        if (setterAdapter != null) {
          Logger.debug(
              "[Instance.set] Found setter '$name' in bridged superclass '${bridgedSuper.name}' at level '${currentClass.name}'. Calling adapter.");
          try {
            setterAdapter(visitor, nativeTarget, value);
            return; // Setter called, assignment done
          } catch (e, s) {
            Logger.error(
                "Native exception during bridged superclass setter '$name': $e\n$s");
            throw RuntimeD4rtException(
                "Native error in bridged superclass setter '$name': $e", originalException: e);
          }
        }
      }
    }

    // Move up to the superclass
    currentClass = currentClass.superclass;
  }

  // No setter found in the hierarchy or bridge, assign directly to the field
  Logger.debug(
      "[Instance.set] No setter found for '$name'. Setting field directly. Instance $hashCode");

  // Check if it's a late variable
  if (_fields.containsKey(name)) {
    final fieldValue = _fields[name];
    if (fieldValue is LateVariable) {
      // Assign to the late variable
      fieldValue.assign(value);
      Logger.debug(
          "[Instance.set] Assigned to late field '$name'. Fields now: ${_fields.keys}");
      return;
    }
  }

  // Perform generic type validation if this instance has type arguments
  _validateFieldAssignmentGeneric(name, value);

  _fields[name] = value;
  Logger.debug(
      "[Instance.set] Field '$name' set. Fields now: ${_fields.keys}");
}