At runtime, in my Java program, given a String, I 'd like to know the return type. For example:
1 + 1
returns int
1L + 1L
returns long
1L + 1
returns long
1 + 1.5
returns double
1 + 2 - 3 * 4 / 5
returns int
1 / 0
returns int
1 + Math.nextInt()
returns int
1.5 + Math.nextInt()
returns double
Color.RED
returns java.awt.Color
a
is an int: a + 1
returns int
a
is an int: a + 1.5
returns double
There is no need to actually evaluate the code: I just need the return type. How can I do this with the JDK runtime compiler, ECJ JDT or any other pure Java dependency?
Detailed code: Here's a simplified, pseudo-code unit test for this code:
public static void ExpressionTyper {
public String determineType(String expression, Map<String, String> variableTypes) {
... // How do I implement this?
}
}
public void ExpressionTyperTest {
@Test public void determineType() {
assertEquals("int", ExpressionTyper.determineType("1 + 1", emptyMap());
assertEquals("long", ExpressionTyper.determineType("1 + 1L", emptyMap());
assertEquals("double", ExpressionTyper.determineType("1 + 1.5", emptyMap());
assertEquals("int", ExpressionTyper.determineType("a + 1", mapOf({"a", "int"}));
assertEquals("int", ExpressionTyper.determineType("a + b", mapOf({"a", "int"}, {"b", "int"}));
assertEquals("double", ExpressionTyper.determineType("a + b", mapOf({"a", "double"}, {"b", "int"}));
}
}
I think this depends on the range of input you want to be able to process.
You see, in the end you are asking: how do I evaluate string expressions at runtime.
So, the short answer is: you need some kind of interpreter / REPL implementation; or at least "parts" of that.
Another approach could be to use the javax compiler to simply compile the thing, and then deduce the type, like here.
Other options would go along the lines of certain "compiler construction" topics, like constant folding.
I've not tried this ...
Wrap your expression in code like this:
public class Test {
private Test xxx = <<insert expression>>;
}
Compile code.
The problem is that an expression like Math.nextInt()
might require an import to be compilable, and I doubt that there is a bombproof way to infer what the import ought to be. Still, this should work for a useful subset of expressions.
This approach is also fragile and non-portable since it depends on the precise form of the compilation error message which is liable to be compiler / version dependent.
A better solution (but more work) would be to implement a parser and type-checker for your Java subset expression language.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With