cleanup grammar

This commit is contained in:
Robert Muir 2016-06-12 11:25:52 -04:00
parent 7c8eb184ee
commit 5be9211761
5 changed files with 756 additions and 492 deletions

View File

@ -195,6 +195,30 @@ lamtype
; ;
funcref funcref
: TYPE REF ( ID | NEW ) : classFuncref
| ( ID | THIS ) REF ID | constructorFuncref
| capturingFuncref
| localFuncref
;
// reference to a static or instance method, e.g. ArrayList::size or Integer::compare
classFuncref
: TYPE REF ID
;
// reference to a constructor, e.g. ArrayList::new
// currently limited to simple non-array types
constructorFuncref
: TYPE REF NEW
;
// reference to an instance method, e.g. object::toString
// currently limited to capture of a simple variable (id).
capturingFuncref
: ID REF ID
;
// reference to a local function, e.g. this::myfunc
localFuncref
: THIS REF ID
; ;

View File

@ -417,4 +417,32 @@ class PainlessParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> implement
* {@link #visitChildren} on {@code ctx}.</p> * {@link #visitChildren} on {@code ctx}.</p>
*/ */
@Override public T visitFuncref(PainlessParser.FuncrefContext ctx) { return visitChildren(ctx); } @Override public T visitFuncref(PainlessParser.FuncrefContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitClassFuncref(PainlessParser.ClassFuncrefContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitConstructorFuncref(PainlessParser.ConstructorFuncrefContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitCapturingFuncref(PainlessParser.CapturingFuncrefContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitLocalFuncref(PainlessParser.LocalFuncrefContext ctx) { return visitChildren(ctx); }
} }

View File

@ -397,4 +397,28 @@ interface PainlessParserVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result * @return the visitor result
*/ */
T visitFuncref(PainlessParser.FuncrefContext ctx); T visitFuncref(PainlessParser.FuncrefContext ctx);
/**
* Visit a parse tree produced by {@link PainlessParser#classFuncref}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitClassFuncref(PainlessParser.ClassFuncrefContext ctx);
/**
* Visit a parse tree produced by {@link PainlessParser#constructorFuncref}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitConstructorFuncref(PainlessParser.ConstructorFuncrefContext ctx);
/**
* Visit a parse tree produced by {@link PainlessParser#capturingFuncref}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitCapturingFuncref(PainlessParser.CapturingFuncrefContext ctx);
/**
* Visit a parse tree produced by {@link PainlessParser#localFuncref}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitLocalFuncref(PainlessParser.LocalFuncrefContext ctx);
} }

View File

@ -45,10 +45,13 @@ import org.elasticsearch.painless.antlr.PainlessParser.BraceaccessContext;
import org.elasticsearch.painless.antlr.PainlessParser.BreakContext; import org.elasticsearch.painless.antlr.PainlessParser.BreakContext;
import org.elasticsearch.painless.antlr.PainlessParser.CallinvokeContext; import org.elasticsearch.painless.antlr.PainlessParser.CallinvokeContext;
import org.elasticsearch.painless.antlr.PainlessParser.CalllocalContext; import org.elasticsearch.painless.antlr.PainlessParser.CalllocalContext;
import org.elasticsearch.painless.antlr.PainlessParser.CapturingFuncrefContext;
import org.elasticsearch.painless.antlr.PainlessParser.CastContext; import org.elasticsearch.painless.antlr.PainlessParser.CastContext;
import org.elasticsearch.painless.antlr.PainlessParser.ChainprecContext; import org.elasticsearch.painless.antlr.PainlessParser.ChainprecContext;
import org.elasticsearch.painless.antlr.PainlessParser.ClassFuncrefContext;
import org.elasticsearch.painless.antlr.PainlessParser.CompContext; import org.elasticsearch.painless.antlr.PainlessParser.CompContext;
import org.elasticsearch.painless.antlr.PainlessParser.ConditionalContext; import org.elasticsearch.painless.antlr.PainlessParser.ConditionalContext;
import org.elasticsearch.painless.antlr.PainlessParser.ConstructorFuncrefContext;
import org.elasticsearch.painless.antlr.PainlessParser.ContinueContext; import org.elasticsearch.painless.antlr.PainlessParser.ContinueContext;
import org.elasticsearch.painless.antlr.PainlessParser.DeclContext; import org.elasticsearch.painless.antlr.PainlessParser.DeclContext;
import org.elasticsearch.painless.antlr.PainlessParser.DeclarationContext; import org.elasticsearch.painless.antlr.PainlessParser.DeclarationContext;
@ -71,6 +74,7 @@ import org.elasticsearch.painless.antlr.PainlessParser.IfContext;
import org.elasticsearch.painless.antlr.PainlessParser.InitializerContext; import org.elasticsearch.painless.antlr.PainlessParser.InitializerContext;
import org.elasticsearch.painless.antlr.PainlessParser.LambdaContext; import org.elasticsearch.painless.antlr.PainlessParser.LambdaContext;
import org.elasticsearch.painless.antlr.PainlessParser.LamtypeContext; import org.elasticsearch.painless.antlr.PainlessParser.LamtypeContext;
import org.elasticsearch.painless.antlr.PainlessParser.LocalFuncrefContext;
import org.elasticsearch.painless.antlr.PainlessParser.NewarrayContext; import org.elasticsearch.painless.antlr.PainlessParser.NewarrayContext;
import org.elasticsearch.painless.antlr.PainlessParser.NewobjectContext; import org.elasticsearch.painless.antlr.PainlessParser.NewobjectContext;
import org.elasticsearch.painless.antlr.PainlessParser.NullContext; import org.elasticsearch.painless.antlr.PainlessParser.NullContext;
@ -950,20 +954,36 @@ public final class Walker extends PainlessParserBaseVisitor<Object> {
@Override @Override
public Object visitFuncref(FuncrefContext ctx) { public Object visitFuncref(FuncrefContext ctx) {
if (ctx.TYPE() != null) { if (ctx.classFuncref() != null) {
// non-capturing Type::method or Type::new return visit(ctx.classFuncref());
final String methodText; } else if (ctx.constructorFuncref() != null) {
if (ctx.NEW() != null) { return visit(ctx.constructorFuncref());
methodText = ctx.NEW().getText(); } else if (ctx.capturingFuncref() != null) {
return visit(ctx.capturingFuncref());
} else if (ctx.localFuncref() != null) {
return visit(ctx.localFuncref());
} else { } else {
methodText = ctx.ID(0).getText(); throw location(ctx).createError(new IllegalStateException("Illegal tree structure."));
} }
return new EFunctionRef(location(ctx), ctx.TYPE().getText(), methodText); }
} else if (ctx.THIS() != null) {
return new EFunctionRef(location(ctx), ctx.THIS().getText(), ctx.ID(0).getText()); @Override
} else { public Object visitClassFuncref(ClassFuncrefContext ctx) {
// capturing object::method return new EFunctionRef(location(ctx), ctx.TYPE().getText(), ctx.ID().getText());
}
@Override
public Object visitConstructorFuncref(ConstructorFuncrefContext ctx) {
return new EFunctionRef(location(ctx), ctx.TYPE().getText(), ctx.NEW().getText());
}
@Override
public Object visitCapturingFuncref(CapturingFuncrefContext ctx) {
return new ECapturingFunctionRef(location(ctx), ctx.ID(0).getText(), ctx.ID(1).getText()); return new ECapturingFunctionRef(location(ctx), ctx.ID(0).getText(), ctx.ID(1).getText());
} }
@Override
public Object visitLocalFuncref(LocalFuncrefContext ctx) {
return new EFunctionRef(location(ctx), ctx.THIS().getText(), ctx.ID().getText());
} }
} }