computeCompoundValue method
Object?
computeCompoundValue(
- Object? currentValue,
- Object? rhsValue,
- TokenType operatorType
)
Implementation
Object? computeCompoundValue(
Object? currentValue, Object? rhsValue, TokenType operatorType) {
// Unwrap BridgedInstance if necessary
final bridgedInstance = toBridgedInstance(currentValue);
final left =
bridgedInstance.$2 ? bridgedInstance.$1!.nativeObject : currentValue;
final right = rhsValue;
if (operatorType == TokenType.PLUS_EQ) {
// 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 == TokenType.MINUS_EQ) {
// Use unwrapped left/right for calculation
if (left is num && right is num) {
return left - right;
}
// Fall through
} else if (operatorType == TokenType.STAR_EQ) {
// Use unwrapped left/right for calculation
if (left is num && right is num) {
return left * right;
}
// Fall through
} else if (operatorType == TokenType.SLASH_EQ) {
// 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 == TokenType.TILDE_SLASH_EQ) {
// 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 == TokenType.PERCENT_EQ) {
// 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 == TokenType.QUESTION_QUESTION_EQ) {
// 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 == TokenType.AMPERSAND_EQ) {
// 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 == TokenType.BAR_EQ) {
// 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 == TokenType.CARET_EQ) {
// 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 == TokenType.GT_GT_EQ) {
// 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 == TokenType.LT_LT_EQ) {
// 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 == TokenType.GT_GT_GT_EQ) {
// 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}');
}