set method
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}");
}