mirror of https://github.com/apache/lucene.git
LUCENE-6965: Changed exception handling in JavascriptCompiler using "sneaky rethrow"
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1723642 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5bfbcfdfc9
commit
a46d5535cb
|
@ -227,8 +227,8 @@ Other
|
||||||
ctor inside InvocationTargetException. (Uwe Schindler)
|
ctor inside InvocationTargetException. (Uwe Schindler)
|
||||||
|
|
||||||
* LUCENE-6965: Expression's JavascriptCompiler now throw ParseException
|
* LUCENE-6965: Expression's JavascriptCompiler now throw ParseException
|
||||||
with bad function names or bad arity instead of IllegalArgumentException
|
with bad function names or bad arity instead of IllegalArgumentException.
|
||||||
(Tomás Fernández Löbbe)
|
(Tomás Fernández Löbbe, Uwe Schindler, Ryan Ernst)
|
||||||
|
|
||||||
* LUCENE-6964: String-based signatures in JavascriptCompiler replaced
|
* LUCENE-6964: String-based signatures in JavascriptCompiler replaced
|
||||||
with better compile-time-checked MethodType; generated class files
|
with better compile-time-checked MethodType; generated class files
|
||||||
|
|
|
@ -249,7 +249,7 @@ public final class JavascriptCompiler {
|
||||||
EVALUATE_METHOD, null, null, classWriter);
|
EVALUATE_METHOD, null, null, classWriter);
|
||||||
|
|
||||||
// to completely hide the ANTLR visitor we use an anonymous impl:
|
// to completely hide the ANTLR visitor we use an anonymous impl:
|
||||||
JavascriptBaseVisitor<Void> visitor = new JavascriptBaseVisitor<Void>() {
|
new JavascriptBaseVisitor<Void>() {
|
||||||
private final Deque<Type> typeStack = new ArrayDeque<>();
|
private final Deque<Type> typeStack = new ArrayDeque<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -295,9 +295,10 @@ public final class JavascriptCompiler {
|
||||||
int arity = method.getParameterTypes().length;
|
int arity = method.getParameterTypes().length;
|
||||||
|
|
||||||
if (arguments != arity) {
|
if (arguments != arity) {
|
||||||
throw new ParseRuntimeException(
|
throwChecked(new ParseException(
|
||||||
"Expected (" + arity + ") arguments for function call (" + text + "), but found (" + arguments + ").",
|
"Invalid expression '" + sourceText + "': Expected (" +
|
||||||
ctx.start.getStartIndex());
|
arity + ") arguments for function call (" + text + "), but found (" + arguments + ").",
|
||||||
|
ctx.start.getStartIndex()));
|
||||||
}
|
}
|
||||||
|
|
||||||
typeStack.push(Type.DOUBLE_TYPE);
|
typeStack.push(Type.DOUBLE_TYPE);
|
||||||
|
@ -331,7 +332,8 @@ public final class JavascriptCompiler {
|
||||||
gen.invokeVirtual(FUNCTION_VALUES_TYPE, DOUBLE_VAL_METHOD);
|
gen.invokeVirtual(FUNCTION_VALUES_TYPE, DOUBLE_VAL_METHOD);
|
||||||
gen.cast(Type.DOUBLE_TYPE, typeStack.peek());
|
gen.cast(Type.DOUBLE_TYPE, typeStack.peek());
|
||||||
} else {
|
} else {
|
||||||
throw new ParseRuntimeException("Unrecognized function call (" + text + ").", ctx.start.getStartIndex());
|
throwChecked(new ParseException("Invalid expression '" + sourceText + "': Unrecognized function call (" +
|
||||||
|
text + ").", ctx.start.getStartIndex()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -622,16 +624,18 @@ public final class JavascriptCompiler {
|
||||||
throw new IllegalStateException("Invalid expected type: " + typeStack.peek());
|
throw new IllegalStateException("Invalid expected type: " + typeStack.peek());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
/** Needed to throw checked ParseException in this visitor (that does not allow it). */
|
||||||
visitor.visit(parseTree);
|
private void throwChecked(Throwable t) {
|
||||||
} catch (final ParseRuntimeException e) {
|
this.<Error>throwChecked0(t);
|
||||||
ParseException exception = new ParseException("Invalid expression '" + sourceText + "': " + e.getMessage(), e.position);
|
|
||||||
exception.initCause(e);
|
|
||||||
throw exception;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T extends Throwable> void throwChecked0(Throwable t) throws T {
|
||||||
|
throw (T) t;
|
||||||
|
}
|
||||||
|
}.visit(parseTree);
|
||||||
|
|
||||||
gen.returnValue();
|
gen.returnValue();
|
||||||
gen.endMethod();
|
gen.endMethod();
|
||||||
|
|
||||||
|
@ -713,16 +717,6 @@ public final class JavascriptCompiler {
|
||||||
DEFAULT_FUNCTIONS = Collections.unmodifiableMap(map);
|
DEFAULT_FUNCTIONS = Collections.unmodifiableMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
private final static class ParseRuntimeException extends RuntimeException {
|
|
||||||
final int position;
|
|
||||||
public ParseRuntimeException(String msg, int position) {
|
|
||||||
super(msg);
|
|
||||||
this.position = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Check Method signature for compatibility. */
|
/** Check Method signature for compatibility. */
|
||||||
private static void checkFunction(Method method) {
|
private static void checkFunction(Method method) {
|
||||||
// check that the Method is public in some public reachable class:
|
// check that the Method is public in some public reachable class:
|
||||||
|
|
|
@ -105,7 +105,6 @@ public class TestCustomFunctions extends LuceneTestCase {
|
||||||
//expected
|
//expected
|
||||||
assertEquals("Invalid expression 'method()': Unrecognized function call (method).", expected.getMessage());
|
assertEquals("Invalid expression 'method()': Unrecognized function call (method).", expected.getMessage());
|
||||||
assertEquals(0, expected.getErrorOffset());
|
assertEquals(0, expected.getErrorOffset());
|
||||||
assertTrue(expected.getCause() != null && expected.getCause() != expected);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in New Issue