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
: TYPE REF ( ID | NEW )
| ( ID | THIS ) REF ID
: classFuncref
| 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>
*/
@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
*/
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.CallinvokeContext;
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.ChainprecContext;
import org.elasticsearch.painless.antlr.PainlessParser.ClassFuncrefContext;
import org.elasticsearch.painless.antlr.PainlessParser.CompContext;
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.DeclContext;
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.LambdaContext;
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.NewobjectContext;
import org.elasticsearch.painless.antlr.PainlessParser.NullContext;
@ -950,20 +954,36 @@ public final class Walker extends PainlessParserBaseVisitor<Object> {
@Override
public Object visitFuncref(FuncrefContext ctx) {
if (ctx.TYPE() != null) {
// non-capturing Type::method or Type::new
final String methodText;
if (ctx.NEW() != null) {
methodText = ctx.NEW().getText();
if (ctx.classFuncref() != null) {
return visit(ctx.classFuncref());
} else if (ctx.constructorFuncref() != null) {
return visit(ctx.constructorFuncref());
} else if (ctx.capturingFuncref() != null) {
return visit(ctx.capturingFuncref());
} else if (ctx.localFuncref() != null) {
return visit(ctx.localFuncref());
} 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());
} else {
// capturing object::method
}
@Override
public Object visitClassFuncref(ClassFuncrefContext ctx) {
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());
}
@Override
public Object visitLocalFuncref(LocalFuncrefContext ctx) {
return new EFunctionRef(location(ctx), ctx.THIS().getText(), ctx.ID().getText());
}
}