computeCompoundValue method
Implementation
Object? computeCompoundValue(
Object? currentValue,
Object? rhsValue,
String operatorType,
) {
// Unwrap BridgedInstance if necessary
final bridgedInstance = toBridgedInstance(currentValue);
final left = bridgedInstance.$2
? bridgedInstance.$1!.nativeObject
: currentValue;
final right = rhsValue;
if (operatorType == '+=') {
// Use unwrapped left/right for calculation
if (left is num && right is num) {
return left + right;
} else if (left is String && right != null) {
return left + stringify(right);
} else if (left is List && right is List) {
// For List += List, create a new list with both elements
// This is how Dart's List + operator works
return [...left, ...right];
}
// Fall through to extension check if standard types don't match
} else if (operatorType == '-=') {
// Use unwrapped left/right for calculation
if (left is num && right is num) {
return left - right;
}
// Fall through
} else if (operatorType == '*=') {
// Use unwrapped left/right for calculation
if (left is num && right is num) {
return left * right;
}
// Fall through
} else if (operatorType == '/=') {
// Use unwrapped left/right for calculation
if (left is num && right is num) {
if (right == 0) throw RuntimeD4rtException("Division by zero in '/='.");
return left.toDouble() / right.toDouble();
}
// Fall through
} else if (operatorType == '~/=') {
// Use unwrapped left/right for calculation
if (left is num && right is num) {
if (rhsValue == 0) {
throw RuntimeD4rtException("Integer division by zero in '~/='.");
}
return left ~/ right;
}
// Fall through
} else if (operatorType == '%=') {
// Use unwrapped left/right for calculation
if (left is num && right is num) {
if (right == 0) throw RuntimeD4rtException("Modulo by zero in '%='.");
return left % right;
}
// Fall through
} else if (operatorType == '??=') {
// Note: Uses original currentValue, not unwrapped 'left'
if (currentValue == null) {
return rhsValue; // If left is null, assign right
} else {
return currentValue; // If left is not null, keep left
}
} else if (operatorType == '&=') {
// Bitwise AND assignment (&=)
if (left is int && right is int) {
return left & right;
} else if (left is BigInt && right is BigInt) {
return left & right;
}
// Fall through to extension search
} else if (operatorType == '|=') {
// Bitwise OR assignment (|=)
if (left is int && right is int) {
return left | right;
} else if (left is BigInt && right is BigInt) {
return left | right;
}
// Fall through to extension search
} else if (operatorType == '^=') {
// Bitwise XOR assignment (^=)
if (left is int && right is int) {
return left ^ right;
} else if (left is BigInt && right is BigInt) {
return left ^ right;
}
// Fall through to extension search
} else if (operatorType == '>>=') {
// Right shift assignment (>>=)
if (left is int && right is int) {
return left >> right;
} else if (left is BigInt && right is int) {
return left >> right;
}
// Fall through to extension search
} else if (operatorType == '<<=') {
// Left shift assignment (<<=)
if (left is int && right is int) {
return left << right;
} else if (left is BigInt && right is int) {
return left << right;
}
// Fall through to extension search
} else if (operatorType == '>>>=') {
// Unsigned right shift assignment (>>>=)
if (left is int && right is int) {
return left >>> right;
}
// Note: BigInt doesn't support >>> operator
// Fall through to extension search
}
Logger.debug(
"[CompoundAssign] Standard op failed for $operatorType. Trying extension operator.",
);
final String? operatorName = _mapCompoundToOperatorName(operatorType);
if (operatorName != null) {
try {
final extensionOperator = environment.findExtensionMember(
currentValue,
operatorName,
);
if (extensionOperator is ExtensionMemberCallable &&
extensionOperator.isOperator) {
Logger.debug(
"[CompoundAssign] Found extension operator '$operatorName' for type ${currentValue?.runtimeType}. Calling...",
);
// Call the extension operator method
// Args: receiver (currentValue), right-hand-side (rhsValue)
final extensionPositionalArgs = [currentValue, rhsValue];
try {
return extensionOperator.call(this, extensionPositionalArgs, {});
} on ReturnException catch (e) {
return e.value; // Should not happen for operators, but handle
} catch (e) {
throw RuntimeD4rtException(
"Error executing extension operator '$operatorName' for compound assignment: $e",
);
}
}
Logger.debug(
"[CompoundAssign] No suitable extension operator '$operatorName' found for type ${currentValue?.runtimeType}.",
);
} on RuntimeD4rtException catch (findError) {
Logger.debug(
"[CompoundAssign] No extension member '$operatorName' found for type ${currentValue?.runtimeType}. Error: ${findError.message}",
);
// Fall through to the final unimplemented error
}
}
throw UnimplementedD4rtException(
'Compound assignment operator $operatorType not handled for types ${currentValue?.runtimeType} and ${rhsValue?.runtimeType}',
);
}