-
-
Notifications
You must be signed in to change notification settings - Fork 87
Description
Problem
The expression compiler generates Java source code (via javassist) that uses raw Java operators (+, -, *, /, ~, <<, >>) for arithmetic and bitwise operations. This works for primitives but fails for BigDecimal and BigInteger objects, since Java does not support operator overloading.
Additionally, there are minor type-handling gaps for Float widening, instanceof compilation, and method calls on auto-boxed primitives.
Documented by
PR #543 added 11 @Disabled dual-mode tests that document these divergences between interpreted and compiled paths:
| Category | Tests | Root cause |
|---|---|---|
BigDecimal arithmetic (-1b, +1b, 2*2.0b, etc.) |
8 | Operators can't apply to BigDecimal objects |
BigInteger arithmetic (-1h, +1H, 2h*2, etc.) |
7 | Operators can't apply to BigInteger objects |
BigInteger bitwise (~1h, 5h<<2, 5h>>2) |
3 | Same fundamental issue |
Float widening (5f-2F) |
1 | coerceToNumeric doesn't distinguish Float from Double |
instanceof (5 instanceof java.lang.Integer) |
2 | Generated source has syntax errors |
Method on auto-boxed primitive (index.toString()) |
1 | Missing boxing in generated source |
Suggested approach
BigDecimal/BigInteger (18 tests) — main effort
NumericExpression.toGetSourceString()should detect whengetterClassisBigDecimal/BigIntegerand generateognl.OgnlOps.add(a, b)instead ofa + bNumericExpression.coerceToNumeric()line 85 strips type info fromASTConstchildren viavalue.toString()— needs to preserve BigDecimal/BigInteger constructionASTNegate.toGetSourceString()should generateognl.OgnlOps.negate(a)instead of-aASTBitNegatesimilarly needsognl.OgnlOps.bitNegate(a)ASTConst.toGetSourceString()needs to emitnew java.math.BigDecimal("value")/new java.math.BigInteger("value")
The OgnlOps methods (add, subtract, multiply, divide, negate, bitNegate, remainder) already handle BigDecimal/BigInteger correctly — they're what the interpreted path uses.
Float widening (1 test)
OgnlRuntime.getNumericLiteral() likely returns the same suffix for Float and Double. Needs a Float-specific "f" literal path in coerceToNumeric.
instanceof (2 tests)
ASTInstanceof.toGetSourceString() generates source that javassist can't parse ("missing member name"). Investigate generated output and fix syntax, or delegate to a runtime helper.
Method on auto-boxed primitive (1 test)
ASTMethod compilation for index.toString() fails because index returns int (primitive) and the compiler calls .toString() without boxing. Needs Integer.valueOf(...) wrapping in generated source.
References
- Issue Unit tests don't work if expressions are not compiled #18 (original report)
- PR fix: dual-mode test coverage and Long/Float literal compilation #543 (dual-mode test coverage with
@Disabledtests)