Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lucene/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ Improvements

* GITHUB#12003: Minor cleanup/improvements to IndexSortSortedNumericDocValuesRangeQuery. (Greg Miller)

* GITHUB#12016: Upgrade lucene/expressions to use antlr 4.11.1 (Andriy Redko)

Bug Fixes
---------------------
* GITHUB#11726: Indexing term vectors on large documents could fail due to
Expand Down
6 changes: 3 additions & 3 deletions lucene/expressions/src/generated/checksums/generateAntlr.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"lucene/expressions/src/java/org/apache/lucene/expressions/js/Javascript.g4": "818e89aae0b6c7601051802013898c128fe7c1ba",
"lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptBaseVisitor.java": "45e3c7093f3e485a07be507efbdefc5e3d112576",
"lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptLexer.java": "354e2d7a982fec18a06e552438c2b2e2c13137cf",
"lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptParser.java": "6182b6a2e3ade663e6f7a8643ace313e66cbf12a",
"lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptBaseVisitor.java": "706c11702149d135fc7ebe13ec1fe01800338260",
"lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptLexer.java": "b8d6b259ebbfce09a5379a1a2aa4c1ddd4e378eb",
"lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptParser.java": "7a3a7b9de17f4a8d41ef342312eae5c55e483e08",
"lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptVisitor.java": "ebf033dc72e63203e5d4d85fd57114dd973482dc"
}
2 changes: 1 addition & 1 deletion lucene/expressions/src/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
module org.apache.lucene.expressions {
requires org.objectweb.asm;
requires org.objectweb.asm.commons;
requires antlr4.runtime;
requires org.antlr.antlr4.runtime;
requires org.apache.lucene.core;
requires org.apache.lucene.codecs;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* @param <T> The return type of the visit operation. Use {@link Void} for operations with no return
* type.
*/
@SuppressWarnings("CheckReturnValue")
class JavascriptBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements JavascriptVisitor<T> {
/**
* {@inheritDoc}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@
import java.util.Map;
import java.util.Properties;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.DiagnosticErrorListener;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.antlr.v4.runtime.atn.PredictionMode;
import org.antlr.v4.runtime.tree.ParseTree;
import org.apache.lucene.expressions.Expression;
import org.apache.lucene.expressions.js.JavascriptParser.ExpressionContext;
Expand Down Expand Up @@ -120,21 +125,22 @@ private static org.objectweb.asm.commons.Method getAsmMethod(

final String sourceText;
final Map<String, Method> functions;
final boolean picky;

/**
* Compiles the given expression.
* Compiles the given expression using default compiler settings.
*
* @param sourceText The expression to compile
* @return A new compiled expression
* @throws ParseException on failure to compile
*/
public static Expression compile(String sourceText) throws ParseException {
return new JavascriptCompiler(sourceText)
.compileExpression(JavascriptCompiler.class.getClassLoader());
return compile(sourceText, DEFAULT_FUNCTIONS, JavascriptCompiler.class.getClassLoader());
}

/**
* Compiles the given expression with the supplied custom functions.
* Compiles the given expression with the supplied custom functions using default compiler
* settings.
*
* <p>Functions must be {@code public static}, return {@code double} and can take from zero to 256
* {@code double} parameters.
Expand All @@ -148,14 +154,35 @@ public static Expression compile(String sourceText) throws ParseException {
*/
public static Expression compile(
String sourceText, Map<String, Method> functions, ClassLoader parent) throws ParseException {
return compile(sourceText, functions, parent, false);
}

/**
* Compiles the given expression with the supplied custom functions.
*
* <p>Functions must be {@code public static}, return {@code double} and can take from zero to 256
* {@code double} parameters.
*
* @param sourceText The expression to compile
* @param functions map of String names to functions
* @param parent a {@code ClassLoader} that should be used as the parent of the loaded class. It
* must contain all classes referred to by the given {@code functions}.
* @param picky whether to throw exception on ambiguity or other internal parsing issues (this
* option makes things slower too, it is only for debugging).
* @return A new compiled expression
* @throws ParseException on failure to compile
*/
static Expression compile(
String sourceText, Map<String, Method> functions, ClassLoader parent, boolean picky)
throws ParseException {
if (parent == null) {
throw new NullPointerException("A parent ClassLoader must be given.");
}
for (Method m : functions.values()) {
checkFunctionClassLoader(m, parent);
checkFunction(m);
}
return new JavascriptCompiler(sourceText, functions).compileExpression(parent);
return new JavascriptCompiler(sourceText, functions, picky).compileExpression(parent);
}

/**
Expand All @@ -169,26 +196,18 @@ private static void unusedTestCompile() throws IOException {
f.doubleValue();
}

/**
* Constructs a compiler for expressions.
*
* @param sourceText The expression to compile
*/
private JavascriptCompiler(String sourceText) {
this(sourceText, DEFAULT_FUNCTIONS);
}

/**
* Constructs a compiler for expressions with specific set of functions
*
* @param sourceText The expression to compile
*/
private JavascriptCompiler(String sourceText, Map<String, Method> functions) {
private JavascriptCompiler(String sourceText, Map<String, Method> functions, boolean picky) {
if (sourceText == null) {
throw new NullPointerException();
}
this.sourceText = sourceText;
this.functions = functions;
this.picky = picky;
}

/**
Expand Down Expand Up @@ -238,10 +257,47 @@ private ParseTree getAntlrParseTree() throws ParseException {
final JavascriptParser javascriptParser =
new JavascriptParser(new CommonTokenStream(javascriptLexer));
javascriptParser.removeErrorListeners();
if (picky) {
setupPicky(javascriptParser);
}
javascriptParser.setErrorHandler(new JavascriptParserErrorStrategy());
return javascriptParser.compile();
}

private void setupPicky(JavascriptParser parser) {
// Diagnostic listener invokes syntaxError on other listeners for ambiguity issues
parser.addErrorListener(new DiagnosticErrorListener(true));
// a second listener to fail the test when the above happens.
parser.addErrorListener(
new BaseErrorListener() {
@Override
public void syntaxError(
final Recognizer<?, ?> recognizer,
final Object offendingSymbol,
final int line,
final int charPositionInLine,
final String msg,
final RecognitionException e) {
throw new RuntimeException(
new ParseException(
"line ("
+ line
+ "), offset ("
+ charPositionInLine
+ "), symbol ("
+ offendingSymbol
+ ") "
+ msg,
charPositionInLine));
}
});

// Enable exact ambiguity detection (costly). we enable exact since its the default for
// DiagnosticErrorListener, life is too short to think about what 'inexact ambiguity' might
// mean.
parser.getInterpreter().setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);
}

/** Sends the bytecode of class file to {@link ClassWriter}. */
private void generateClass(
final ParseTree parseTree,
Expand Down
Loading