diff --git a/modules/lang-painless/src/main/antlr/PainlessLexer.g4 b/modules/lang-painless/src/main/antlr/PainlessLexer.g4
index 6ab6a86113595..fe58984fa8712 100644
--- a/modules/lang-painless/src/main/antlr/PainlessLexer.g4
+++ b/modules/lang-painless/src/main/antlr/PainlessLexer.g4
@@ -19,14 +19,14 @@
lexer grammar PainlessLexer;
-@members{
+@members {
/**
* Check against the current whitelist to determine whether a token is a type
* or not. Called by the {@code TYPE} token defined in {@code PainlessLexer.g4}.
* See also
* The lexer hack.
*/
-protected abstract boolean isSimpleType(String name);
+protected abstract boolean isType(String name);
/**
* Is the preceding {@code /} a the beginning of a regex (true) or a division
@@ -133,7 +133,7 @@ NULL: 'null';
// or not. Note this works by processing one character at a time
// and the rule is added or removed as this happens. This is also known
// as "the lexer hack." See (https://en.wikipedia.org/wiki/The_lexer_hack).
-TYPE: ID ( DOT ID )* { isSimpleType(getText()) }?;
+TYPE: ID ( DOT ID )* { isType(getText()) }?;
ID: [_a-zA-Z] [_a-zA-Z0-9]*;
mode AFTER_DOT;
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java
index 988a31a24ee27..8694ff7903859 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java
@@ -185,7 +185,7 @@ static Method lookupMethodInternal(Definition definition, Class> receiverClass
Definition.MethodKey key = new Definition.MethodKey(name, arity);
// check whitelist for matching method
for (Class> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
- Struct struct = definition.RuntimeClassToStruct(clazz);
+ Struct struct = definition.getPainlessStructFromJavaClass(clazz);
if (struct != null) {
Method method = struct.methods.get(key);
@@ -195,7 +195,7 @@ static Method lookupMethodInternal(Definition definition, Class> receiverClass
}
for (Class> iface : clazz.getInterfaces()) {
- struct = definition.RuntimeClassToStruct(iface);
+ struct = definition.getPainlessStructFromJavaClass(iface);
if (struct != null) {
Method method = struct.methods.get(key);
@@ -279,7 +279,7 @@ static MethodHandle lookupMethod(Definition definition, Lookup lookup, MethodTyp
captures[capture] = callSiteType.parameterType(i + 1 + capture);
}
MethodHandle filter;
- Definition.Type interfaceType = definition.ClassToType(method.arguments.get(i - 1 - replaced));
+ Class> interfaceType = method.arguments.get(i - 1 - replaced);
if (signature.charAt(0) == 'S') {
// the implementation is strongly typed, now that we know the interface type,
// we have everything.
@@ -293,14 +293,14 @@ static MethodHandle lookupMethod(Definition definition, Lookup lookup, MethodTyp
// the interface type is now known, but we need to get the implementation.
// this is dynamically based on the receiver type (and cached separately, underneath
// this cache). It won't blow up since we never nest here (just references)
- MethodType nestedType = MethodType.methodType(interfaceType.clazz, captures);
+ MethodType nestedType = MethodType.methodType(interfaceType, captures);
CallSite nested = DefBootstrap.bootstrap(definition,
lookup,
call,
nestedType,
0,
DefBootstrap.REFERENCE,
- interfaceType.name);
+ Definition.ClassToName(interfaceType));
filter = nested.dynamicInvoker();
} else {
throw new AssertionError();
@@ -324,8 +324,8 @@ static MethodHandle lookupMethod(Definition definition, Lookup lookup, MethodTyp
*/
static MethodHandle lookupReference(Definition definition, Lookup lookup, String interfaceClass,
Class> receiverClass, String name) throws Throwable {
- Definition.Type interfaceType = definition.getType(interfaceClass);
- Method interfaceMethod = interfaceType.struct.functionalMethod;
+ Class> interfaceType = definition.getJavaClassFromPainlessType(interfaceClass);
+ Method interfaceMethod = definition.getPainlessStructFromJavaClass(interfaceType).functionalMethod;
if (interfaceMethod == null) {
throw new IllegalArgumentException("Class [" + interfaceClass + "] is not a functional interface");
}
@@ -337,15 +337,15 @@ static MethodHandle lookupReference(Definition definition, Lookup lookup, String
/** Returns a method handle to an implementation of clazz, given method reference signature. */
private static MethodHandle lookupReferenceInternal(Definition definition, Lookup lookup,
- Definition.Type clazz, String type, String call, Class>... captures)
+ Class> clazz, String type, String call, Class>... captures)
throws Throwable {
final FunctionRef ref;
if ("this".equals(type)) {
// user written method
- Method interfaceMethod = clazz.struct.functionalMethod;
+ Method interfaceMethod = definition.getPainlessStructFromJavaClass(clazz).functionalMethod;
if (interfaceMethod == null) {
throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " +
- "to [" + clazz.name + "], not a functional interface");
+ "to [" + Definition.ClassToName(clazz) + "], not a functional interface");
}
int arity = interfaceMethod.arguments.size() + captures.length;
final MethodHandle handle;
@@ -359,14 +359,14 @@ private static MethodHandle lookupReferenceInternal(Definition definition, Looku
// because the arity does not match the expected interface type.
if (call.contains("$")) {
throw new IllegalArgumentException("Incorrect number of parameters for [" + interfaceMethod.name +
- "] in [" + clazz.clazz + "]");
+ "] in [" + clazz + "]");
}
throw new IllegalArgumentException("Unknown call [" + call + "] with [" + arity + "] arguments.");
}
- ref = new FunctionRef(clazz.clazz, interfaceMethod, call, handle.type(), captures.length);
+ ref = new FunctionRef(clazz, interfaceMethod, call, handle.type(), captures.length);
} else {
// whitelist lookup
- ref = new FunctionRef(definition, clazz.clazz, type, call, captures.length);
+ ref = new FunctionRef(definition, clazz, type, call, captures.length);
}
final CallSite callSite = LambdaBootstrap.lambdaBootstrap(
lookup,
@@ -379,7 +379,7 @@ private static MethodHandle lookupReferenceInternal(Definition definition, Looku
ref.delegateMethodType,
ref.isDelegateInterface ? 1 : 0
);
- return callSite.dynamicInvoker().asType(MethodType.methodType(clazz.clazz, captures));
+ return callSite.dynamicInvoker().asType(MethodType.methodType(clazz, captures));
}
/** gets the field name used to lookup up the MethodHandle for a function. */
@@ -416,7 +416,7 @@ public static String getUserFunctionHandleFieldName(String name, int arity) {
static MethodHandle lookupGetter(Definition definition, Class> receiverClass, String name) {
// first try whitelist
for (Class> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
- Struct struct = definition.RuntimeClassToStruct(clazz);
+ Struct struct = definition.getPainlessStructFromJavaClass(clazz);
if (struct != null) {
MethodHandle handle = struct.getters.get(name);
@@ -426,7 +426,7 @@ static MethodHandle lookupGetter(Definition definition, Class> receiverClass,
}
for (final Class> iface : clazz.getInterfaces()) {
- struct = definition.RuntimeClassToStruct(iface);
+ struct = definition.getPainlessStructFromJavaClass(iface);
if (struct != null) {
MethodHandle handle = struct.getters.get(name);
@@ -487,7 +487,7 @@ static MethodHandle lookupGetter(Definition definition, Class> receiverClass,
static MethodHandle lookupSetter(Definition definition, Class> receiverClass, String name) {
// first try whitelist
for (Class> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
- Struct struct = definition.RuntimeClassToStruct(clazz);
+ Struct struct = definition.getPainlessStructFromJavaClass(clazz);
if (struct != null) {
MethodHandle handle = struct.setters.get(name);
@@ -497,7 +497,7 @@ static MethodHandle lookupSetter(Definition definition, Class> receiverClass,
}
for (final Class> iface : clazz.getInterfaces()) {
- struct = definition.RuntimeClassToStruct(iface);
+ struct = definition.getPainlessStructFromJavaClass(iface);
if (struct != null) {
MethodHandle handle = struct.setters.get(name);
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefBootstrap.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefBootstrap.java
index 31fba8f757954..9c7c7f631b68d 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefBootstrap.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefBootstrap.java
@@ -1,7 +1,3 @@
-package org.elasticsearch.painless;
-
-import org.elasticsearch.common.SuppressForbidden;
-
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
@@ -21,6 +17,10 @@
* under the License.
*/
+package org.elasticsearch.painless;
+
+import org.elasticsearch.common.SuppressForbidden;
+
import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
@@ -72,16 +72,16 @@ private DefBootstrap() {} // no instance!
public static final int SHIFT_OPERATOR = 9;
/** static bootstrap parameter indicating a request to normalize an index for array-like-access */
public static final int INDEX_NORMALIZE = 10;
-
+
// constants for the flags parameter of operators
- /**
- * static bootstrap parameter indicating the binary operator allows nulls (e.g. == and +)
+ /**
+ * static bootstrap parameter indicating the binary operator allows nulls (e.g. == and +)
*
* requires additional {@link MethodHandles#catchException} guard, which will invoke
* the fallback if a null is encountered.
*/
public static final int OPERATOR_ALLOWS_NULL = 1 << 0;
-
+
/**
* static bootstrap parameter indicating the binary operator is part of compound assignment (e.g. +=).
*
@@ -89,7 +89,7 @@ private DefBootstrap() {} // no instance!
* to cast back to the receiver's type, depending on types seen.
*/
public static final int OPERATOR_COMPOUND_ASSIGNMENT = 1 << 1;
-
+
/**
* static bootstrap parameter indicating an explicit cast to the return type.
*
@@ -129,7 +129,7 @@ static final class PIC extends MutableCallSite {
setTarget(fallback);
}
-
+
/**
* guard method for inline caching: checks the receiver's class is the same
* as the cached class
@@ -162,7 +162,7 @@ private MethodHandle lookup(int flavor, String name, Class> receiver) throws T
default: throw new AssertionError();
}
}
-
+
/**
* Creates the {@link MethodHandle} for the megamorphic call site
* using {@link ClassValue} and {@link MethodHandles#exactInvoker(MethodType)}:
@@ -182,7 +182,7 @@ protected MethodHandle computeValue(Class> receiverType) {
}
};
return MethodHandles.foldArguments(MethodHandles.exactInvoker(type),
- MEGAMORPHIC_LOOKUP.bindTo(megamorphicCache));
+ MEGAMORPHIC_LOOKUP.bindTo(megamorphicCache));
}
/**
@@ -195,18 +195,18 @@ Object fallback(final Object[] callArgs) throws Throwable {
if (depth >= MAX_DEPTH) {
// we revert the whole cache and build a new megamorphic one
final MethodHandle target = this.createMegamorphicHandle();
-
+
setTarget(target);
- return target.invokeWithArguments(callArgs);
+ return target.invokeWithArguments(callArgs);
} else {
final Class> receiver = callArgs[0].getClass();
final MethodHandle target = lookup(flavor, name, receiver).asType(type());
-
+
MethodHandle test = CHECK_CLASS.bindTo(receiver);
MethodHandle guard = MethodHandles.guardWithTest(test, target, getTarget());
-
+
depth++;
-
+
setTarget(guard);
return target.invokeWithArguments(callArgs);
}
@@ -225,7 +225,7 @@ Object fallback(final Object[] callArgs) throws Throwable {
MethodType.methodType(Object.class, Object[].class));
MethodHandle mh = publicLookup.findVirtual(ClassValue.class, "get",
MethodType.methodType(Object.class, Class.class));
- mh = MethodHandles.filterArguments(mh, 1,
+ mh = MethodHandles.filterArguments(mh, 1,
publicLookup.findVirtual(Object.class, "getClass", MethodType.methodType(Class.class)));
MEGAMORPHIC_LOOKUP = mh.asType(mh.type().changeReturnType(MethodHandle.class));
} catch (ReflectiveOperationException e) {
@@ -233,7 +233,7 @@ Object fallback(final Object[] callArgs) throws Throwable {
}
}
}
-
+
/**
* CallSite that implements the monomorphic inlining cache (for operators).
*/
@@ -252,14 +252,14 @@ static final class MIC extends MutableCallSite {
if (initialDepth > 0) {
initialized = true;
}
-
+
MethodHandle fallback = FALLBACK.bindTo(this)
.asCollector(Object[].class, type.parameterCount())
.asType(type);
setTarget(fallback);
}
-
+
/**
* Does a slow lookup for the operator
*/
@@ -290,7 +290,7 @@ private MethodHandle lookup(Object[] args) throws Throwable {
default: throw new AssertionError();
}
}
-
+
private MethodHandle lookupGeneric() {
MethodHandle target = DefMath.lookupGeneric(name);
if ((flags & OPERATOR_EXPLICIT_CAST) != 0) {
@@ -302,7 +302,7 @@ private MethodHandle lookupGeneric() {
}
return target;
}
-
+
/**
* Called when a new type is encountered or if cached type does not match.
* In that case we revert to a generic, but slower operator handling.
@@ -315,7 +315,7 @@ Object fallback(Object[] args) throws Throwable {
setTarget(generic.asType(type()));
return generic.invokeWithArguments(args);
}
-
+
final MethodType type = type();
MethodHandle target = lookup(args);
// for math operators: WrongMethodType can be confusing. convert into a ClassCastException if they screw up.
@@ -361,18 +361,18 @@ Object fallback(Object[] args) throws Throwable {
// very special cases, where even the receiver can be null (see JLS rules for string concat)
// we wrap + with an NPE catcher, and use our generic method in that case.
if (flavor == BINARY_OPERATOR && (flags & OPERATOR_ALLOWS_NULL) != 0) {
- MethodHandle handler = MethodHandles.dropArguments(lookupGeneric().asType(type()),
- 0,
+ MethodHandle handler = MethodHandles.dropArguments(lookupGeneric().asType(type()),
+ 0,
NullPointerException.class);
guard = MethodHandles.catchException(guard, NullPointerException.class, handler);
}
-
+
initialized = true;
setTarget(guard);
return target.invokeWithArguments(args);
}
-
+
/**
* guard method for inline caching: checks the receiver's class is the same
* as the cached class
@@ -388,7 +388,7 @@ static boolean checkLHS(Class> clazz, Object leftObject) {
static boolean checkRHS(Class> left, Class> right, Object leftObject, Object rightObject) {
return rightObject.getClass() == right;
}
-
+
/**
* guard method for inline caching: checks the receiver's class and the first argument
* are the same as the cached receiver and first argument.
@@ -396,7 +396,7 @@ static boolean checkRHS(Class> left, Class> right, Object leftObject, Object
static boolean checkBoth(Class> left, Class> right, Object leftObject, Object rightObject) {
return leftObject.getClass() == left && rightObject.getClass() == right;
}
-
+
private static final MethodHandle CHECK_LHS;
private static final MethodHandle CHECK_RHS;
private static final MethodHandle CHECK_BOTH;
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java
index 6628484660699..f903c0571b2bd 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java
@@ -21,8 +21,8 @@
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -31,38 +31,38 @@
import java.util.stream.Stream;
/**
- * Dynamic operators for painless.
+ * Dynamic operators for painless.
*
* Each operator must "support" the following types:
- * {@code int,long,float,double,boolean,Object}. Operators can throw exceptions if
+ * {@code int,long,float,double,boolean,Object}. Operators can throw exceptions if
* the type is illegal. The {@code Object} type must be a "generic" handler that
* handles all legal types: it must be convertible to every possible legal signature.
*/
@SuppressWarnings("unused")
public class DefMath {
-
+
// Unary not: only applicable to integral types
private static int not(int v) {
return ~v;
}
-
+
private static long not(long v) {
return ~v;
}
-
+
private static float not(float v) {
throw new ClassCastException("Cannot apply not [~] to type [float]");
}
-
+
private static double not(double v) {
throw new ClassCastException("Cannot apply not [~] to type [double]");
}
-
+
private static boolean not(boolean v) {
throw new ClassCastException("Cannot apply not [~] to type [boolean]");
}
-
+
private static Object not(Object unary) {
if (unary instanceof Long) {
return ~(Long)unary;
@@ -79,29 +79,29 @@ private static Object not(Object unary) {
throw new ClassCastException("Cannot apply [~] operation to type " +
"[" + unary.getClass().getCanonicalName() + "].");
}
-
+
// unary negation and plus: applicable to all numeric types
private static int neg(int v) {
return -v;
}
-
+
private static long neg(long v) {
return -v;
}
-
+
private static float neg(float v) {
return -v;
}
-
+
private static double neg(double v) {
return -v;
}
-
+
private static boolean neg(boolean v) {
throw new ClassCastException("Cannot apply [-] operation to type [boolean]");
}
-
+
private static Object neg(final Object unary) {
if (unary instanceof Double) {
return -(double)unary;
@@ -122,27 +122,27 @@ private static Object neg(final Object unary) {
throw new ClassCastException("Cannot apply [-] operation to type " +
"[" + unary.getClass().getCanonicalName() + "].");
}
-
+
private static int plus(int v) {
return +v;
}
-
+
private static long plus(long v) {
return +v;
}
-
+
private static float plus(float v) {
return +v;
}
-
+
private static double plus(double v) {
return +v;
}
-
+
private static boolean plus(boolean v) {
throw new ClassCastException("Cannot apply [+] operation to type [boolean]");
}
-
+
private static Object plus(final Object unary) {
if (unary instanceof Double) {
return +(double)unary;
@@ -163,29 +163,29 @@ private static Object plus(final Object unary) {
throw new ClassCastException("Cannot apply [+] operation to type " +
"[" + unary.getClass().getCanonicalName() + "].");
}
-
+
// multiplication/division/remainder/subtraction: applicable to all integer types
-
+
private static int mul(int a, int b) {
return a * b;
}
-
+
private static long mul(long a, long b) {
return a * b;
}
-
+
private static float mul(float a, float b) {
return a * b;
}
-
+
private static double mul(double a, double b) {
return a * b;
}
-
+
private static boolean mul(boolean a, boolean b) {
throw new ClassCastException("Cannot apply [*] operation to type [boolean]");
}
-
+
private static Object mul(Object left, Object right) {
if (left instanceof Number) {
if (right instanceof Number) {
@@ -228,27 +228,27 @@ private static Object mul(Object left, Object right) {
throw new ClassCastException("Cannot apply [*] operation to types " +
"[" + left.getClass().getCanonicalName() + "] and [" + right.getClass().getCanonicalName() + "].");
}
-
+
private static int div(int a, int b) {
return a / b;
}
-
+
private static long div(long a, long b) {
return a / b;
}
-
+
private static float div(float a, float b) {
return a / b;
}
-
+
private static double div(double a, double b) {
return a / b;
}
-
+
private static boolean div(boolean a, boolean b) {
throw new ClassCastException("Cannot apply [/] operation to type [boolean]");
}
-
+
private static Object div(Object left, Object right) {
if (left instanceof Number) {
if (right instanceof Number) {
@@ -291,27 +291,27 @@ private static Object div(Object left, Object right) {
throw new ClassCastException("Cannot apply [/] operation to types " +
"[" + left.getClass().getCanonicalName() + "] and [" + right.getClass().getCanonicalName() + "].");
}
-
+
private static int rem(int a, int b) {
return a % b;
}
-
+
private static long rem(long a, long b) {
return a % b;
}
-
+
private static float rem(float a, float b) {
return a % b;
}
-
+
private static double rem(double a, double b) {
return a % b;
}
-
+
private static boolean rem(boolean a, boolean b) {
throw new ClassCastException("Cannot apply [%] operation to type [boolean]");
}
-
+
private static Object rem(Object left, Object right) {
if (left instanceof Number) {
if (right instanceof Number) {
@@ -354,30 +354,30 @@ private static Object rem(Object left, Object right) {
throw new ClassCastException("Cannot apply [%] operation to types " +
"[" + left.getClass().getCanonicalName() + "] and [" + right.getClass().getCanonicalName() + "].");
}
-
+
// addition: applicable to all numeric types.
// additionally, if either type is a string, the other type can be any arbitrary type (including null)
-
+
private static int add(int a, int b) {
return a + b;
}
-
+
private static long add(long a, long b) {
return a + b;
}
-
+
private static float add(float a, float b) {
return a + b;
}
-
+
private static double add(double a, double b) {
return a + b;
}
-
+
private static boolean add(boolean a, boolean b) {
throw new ClassCastException("Cannot apply [+] operation to type [boolean]");
}
-
+
private static Object add(Object left, Object right) {
if (left instanceof String) {
return (String) left + right;
@@ -424,27 +424,27 @@ private static Object add(Object left, Object right) {
throw new ClassCastException("Cannot apply [+] operation to types " +
"[" + left.getClass().getCanonicalName() + "] and [" + right.getClass().getCanonicalName() + "].");
}
-
+
private static int sub(int a, int b) {
return a - b;
}
-
+
private static long sub(long a, long b) {
return a - b;
}
-
+
private static float sub(float a, float b) {
return a - b;
}
-
+
private static double sub(double a, double b) {
return a - b;
}
-
+
private static boolean sub(boolean a, boolean b) {
throw new ClassCastException("Cannot apply [-] operation to type [boolean]");
}
-
+
private static Object sub(Object left, Object right) {
if (left instanceof Number) {
if (right instanceof Number) {
@@ -487,29 +487,29 @@ private static Object sub(Object left, Object right) {
throw new ClassCastException("Cannot apply [-] operation to types " +
"[" + left.getClass().getCanonicalName() + "] and [" + right.getClass().getCanonicalName() + "].");
}
-
+
// eq: applicable to any arbitrary type, including nulls for both arguments!!!
private static boolean eq(int a, int b) {
return a == b;
}
-
+
private static boolean eq(long a, long b) {
return a == b;
}
-
+
private static boolean eq(float a, float b) {
return a == b;
}
-
+
private static boolean eq(double a, double b) {
return a == b;
}
-
+
private static boolean eq(boolean a, boolean b) {
return a == b;
}
-
+
private static boolean eq(Object left, Object right) {
if (left != null && right != null) {
if (left instanceof Double) {
@@ -565,29 +565,29 @@ private static boolean eq(Object left, Object right) {
return left == null && right == null;
}
-
+
// comparison operators: applicable for any numeric type
private static boolean lt(int a, int b) {
return a < b;
}
-
+
private static boolean lt(long a, long b) {
return a < b;
}
-
+
private static boolean lt(float a, float b) {
return a < b;
}
-
+
private static boolean lt(double a, double b) {
return a < b;
}
-
+
private static boolean lt(boolean a, boolean b) {
- throw new ClassCastException("Cannot apply [<] operation to type [boolean]");
+ throw new ClassCastException("Cannot apply [<] operation to type [boolean]");
}
-
+
private static boolean lt(Object left, Object right) {
if (left instanceof Number) {
if (right instanceof Number) {
@@ -634,23 +634,23 @@ private static boolean lt(Object left, Object right) {
private static boolean lte(int a, int b) {
return a <= b;
}
-
+
private static boolean lte(long a, long b) {
return a <= b;
}
-
+
private static boolean lte(float a, float b) {
return a <= b;
}
-
+
private static boolean lte(double a, double b) {
return a <= b;
}
-
+
private static boolean lte(boolean a, boolean b) {
- throw new ClassCastException("Cannot apply [<=] operation to type [boolean]");
+ throw new ClassCastException("Cannot apply [<=] operation to type [boolean]");
}
-
+
private static boolean lte(Object left, Object right) {
if (left instanceof Number) {
if (right instanceof Number) {
@@ -697,23 +697,23 @@ private static boolean lte(Object left, Object right) {
private static boolean gt(int a, int b) {
return a > b;
}
-
+
private static boolean gt(long a, long b) {
return a > b;
}
-
+
private static boolean gt(float a, float b) {
return a > b;
}
-
+
private static boolean gt(double a, double b) {
return a > b;
}
-
+
private static boolean gt(boolean a, boolean b) {
- throw new ClassCastException("Cannot apply [>] operation to type [boolean]");
+ throw new ClassCastException("Cannot apply [>] operation to type [boolean]");
}
-
+
private static boolean gt(Object left, Object right) {
if (left instanceof Number) {
if (right instanceof Number) {
@@ -756,25 +756,25 @@ private static boolean gt(Object left, Object right) {
throw new ClassCastException("Cannot apply [>] operation to types " +
"[" + left.getClass().getCanonicalName() + "] and [" + right.getClass().getCanonicalName() + "].");
}
-
+
private static boolean gte(int a, int b) {
return a >= b;
}
-
+
private static boolean gte(long a, long b) {
return a >= b;
}
-
+
private static boolean gte(float a, float b) {
return a >= b;
}
-
+
private static boolean gte(double a, double b) {
return a >= b;
}
-
+
private static boolean gte(boolean a, boolean b) {
- throw new ClassCastException("Cannot apply [>=] operation to type [boolean]");
+ throw new ClassCastException("Cannot apply [>=] operation to type [boolean]");
}
private static boolean gte(Object left, Object right) {
@@ -819,10 +819,10 @@ private static boolean gte(Object left, Object right) {
throw new ClassCastException("Cannot apply [>] operation to types " +
"[" + left.getClass().getCanonicalName() + "] and [" + right.getClass().getCanonicalName() + "].");
}
-
+
// helper methods to convert an integral according to numeric promotion
// this is used by the generic code for bitwise and shift operators
-
+
private static long longIntegralValue(Object o) {
if (o instanceof Long) {
return (long)o;
@@ -834,7 +834,7 @@ private static long longIntegralValue(Object o) {
throw new ClassCastException("Cannot convert [" + o.getClass().getCanonicalName() + "] to an integral value.");
}
}
-
+
private static int intIntegralValue(Object o) {
if (o instanceof Integer || o instanceof Short || o instanceof Byte) {
return ((Number)o).intValue();
@@ -844,29 +844,29 @@ private static int intIntegralValue(Object o) {
throw new ClassCastException("Cannot convert [" + o.getClass().getCanonicalName() + "] to an integral value.");
}
}
-
+
// bitwise operators: valid only for integral types
private static int and(int a, int b) {
return a & b;
}
-
+
private static long and(long a, long b) {
return a & b;
}
-
+
private static float and(float a, float b) {
- throw new ClassCastException("Cannot apply [&] operation to type [float]");
+ throw new ClassCastException("Cannot apply [&] operation to type [float]");
}
-
+
private static double and(double a, double b) {
- throw new ClassCastException("Cannot apply [&] operation to type [float]");
+ throw new ClassCastException("Cannot apply [&] operation to type [float]");
}
-
+
private static boolean and(boolean a, boolean b) {
return a & b;
}
-
+
private static Object and(Object left, Object right) {
if (left instanceof Boolean && right instanceof Boolean) {
return (boolean)left & (boolean)right;
@@ -876,23 +876,23 @@ private static Object and(Object left, Object right) {
return intIntegralValue(left) & intIntegralValue(right);
}
}
-
+
private static int xor(int a, int b) {
return a ^ b;
}
-
+
private static long xor(long a, long b) {
return a ^ b;
}
-
+
private static float xor(float a, float b) {
- throw new ClassCastException("Cannot apply [^] operation to type [float]");
+ throw new ClassCastException("Cannot apply [^] operation to type [float]");
}
-
+
private static double xor(double a, double b) {
- throw new ClassCastException("Cannot apply [^] operation to type [float]");
+ throw new ClassCastException("Cannot apply [^] operation to type [float]");
}
-
+
private static boolean xor(boolean a, boolean b) {
return a ^ b;
}
@@ -910,23 +910,23 @@ private static Object xor(Object left, Object right) {
private static int or(int a, int b) {
return a | b;
}
-
+
private static long or(long a, long b) {
return a | b;
}
-
+
private static float or(float a, float b) {
- throw new ClassCastException("Cannot apply [|] operation to type [float]");
+ throw new ClassCastException("Cannot apply [|] operation to type [float]");
}
-
+
private static double or(double a, double b) {
- throw new ClassCastException("Cannot apply [|] operation to type [float]");
+ throw new ClassCastException("Cannot apply [|] operation to type [float]");
}
-
+
private static boolean or(boolean a, boolean b) {
return a | b;
}
-
+
private static Object or(Object left, Object right) {
if (left instanceof Boolean && right instanceof Boolean) {
return (boolean)left | (boolean)right;
@@ -936,30 +936,30 @@ private static Object or(Object left, Object right) {
return intIntegralValue(left) | intIntegralValue(right);
}
}
-
+
// shift operators, valid for any integral types, but does not promote.
// we implement all shifts as long shifts, because the extra bits are ignored anyway.
-
+
private static int lsh(int a, long b) {
return a << b;
}
-
+
private static long lsh(long a, long b) {
return a << b;
}
-
+
private static float lsh(float a, long b) {
- throw new ClassCastException("Cannot apply [<<] operation to type [float]");
+ throw new ClassCastException("Cannot apply [<<] operation to type [float]");
}
-
+
private static double lsh(double a, long b) {
- throw new ClassCastException("Cannot apply [<<] operation to type [double]");
+ throw new ClassCastException("Cannot apply [<<] operation to type [double]");
}
-
+
private static boolean lsh(boolean a, long b) {
- throw new ClassCastException("Cannot apply [<<] operation to type [boolean]");
+ throw new ClassCastException("Cannot apply [<<] operation to type [boolean]");
}
-
+
public static Object lsh(Object left, long right) {
if (left instanceof Long) {
return (long)(left) << right;
@@ -967,25 +967,25 @@ public static Object lsh(Object left, long right) {
return intIntegralValue(left) << right;
}
}
-
+
private static int rsh(int a, long b) {
return a >> b;
}
-
+
private static long rsh(long a, long b) {
return a >> b;
}
-
+
private static float rsh(float a, long b) {
- throw new ClassCastException("Cannot apply [>>] operation to type [float]");
+ throw new ClassCastException("Cannot apply [>>] operation to type [float]");
}
-
+
private static double rsh(double a, long b) {
- throw new ClassCastException("Cannot apply [>>] operation to type [double]");
+ throw new ClassCastException("Cannot apply [>>] operation to type [double]");
}
-
+
private static boolean rsh(boolean a, long b) {
- throw new ClassCastException("Cannot apply [>>] operation to type [boolean]");
+ throw new ClassCastException("Cannot apply [>>] operation to type [boolean]");
}
public static Object rsh(Object left, long right) {
@@ -995,25 +995,25 @@ public static Object rsh(Object left, long right) {
return intIntegralValue(left) >> right;
}
}
-
+
private static int ush(int a, long b) {
return a >>> b;
}
-
+
private static long ush(long a, long b) {
return a >>> b;
}
-
+
private static float ush(float a, long b) {
- throw new ClassCastException("Cannot apply [>>>] operation to type [float]");
+ throw new ClassCastException("Cannot apply [>>>] operation to type [float]");
}
-
+
private static double ush(double a, long b) {
- throw new ClassCastException("Cannot apply [>>>] operation to type [double]");
+ throw new ClassCastException("Cannot apply [>>>] operation to type [double]");
}
-
+
private static boolean ush(boolean a, long b) {
- throw new ClassCastException("Cannot apply [>>>] operation to type [boolean]");
+ throw new ClassCastException("Cannot apply [>>>] operation to type [boolean]");
}
public static Object ush(Object left, long right) {
@@ -1023,15 +1023,15 @@ public static Object ush(Object left, long right) {
return intIntegralValue(left) >>> right;
}
}
-
- /**
- * unboxes a class to its primitive type, or returns the original
+
+ /**
+ * unboxes a class to its primitive type, or returns the original
* class if its not a boxed type.
*/
private static Class> unbox(Class> clazz) {
return MethodType.methodType(clazz).unwrap().returnType();
}
-
+
/** Unary promotion. All Objects are promoted to Object. */
private static Class> promote(Class> clazz) {
// if either is a non-primitive type -> Object.
@@ -1039,25 +1039,25 @@ private static Class> promote(Class> clazz) {
return Object.class;
}
// always promoted to integer
- if (clazz == byte.class || clazz == short.class || clazz == char.class || clazz == int.class) {
- return int.class;
- } else {
- return clazz;
- }
+ if (clazz == byte.class || clazz == short.class || clazz == char.class || clazz == int.class) {
+ return int.class;
+ } else {
+ return clazz;
+ }
}
-
+
/** Binary promotion. */
private static Class> promote(Class> a, Class> b) {
// if either is a non-primitive type -> Object.
if (a.isPrimitive() == false || b.isPrimitive() == false) {
return Object.class;
}
-
+
// boolean -> boolean
if (a == boolean.class && b == boolean.class) {
return boolean.class;
}
-
+
// ordinary numeric promotion
if (a == double.class || b == double.class) {
return double.class;
@@ -1069,7 +1069,7 @@ private static Class> promote(Class> a, Class> b) {
return int.class;
}
}
-
+
private static final Lookup PRIV_LOOKUP = MethodHandles.lookup();
private static final Map,Map> TYPE_OP_MAPPING = Collections.unmodifiableMap(
@@ -1107,7 +1107,7 @@ private static Class> promote(Class> a, Class> b) {
}
}))
);
-
+
/** Returns an appropriate method handle for a unary or shift operator, based only on the receiver (LHS) */
public static MethodHandle lookupUnary(Class> receiverClass, String name) {
MethodHandle handle = TYPE_OP_MAPPING.get(promote(unbox(receiverClass))).get(name);
@@ -1116,7 +1116,7 @@ public static MethodHandle lookupUnary(Class> receiverClass, String name) {
}
return handle;
}
-
+
/** Returns an appropriate method handle for a binary operator, based on promotion of the LHS and RHS arguments */
public static MethodHandle lookupBinary(Class> classA, Class> classB, String name) {
MethodHandle handle = TYPE_OP_MAPPING.get(promote(promote(unbox(classA)), promote(unbox(classB)))).get(name);
@@ -1125,7 +1125,7 @@ public static MethodHandle lookupBinary(Class> classA, Class> classB, String
}
return handle;
}
-
+
/** Returns a generic method handle for any operator, that can handle all valid signatures, nulls, corner cases */
public static MethodHandle lookupGeneric(String name) {
return TYPE_OP_MAPPING.get(Object.class).get(name);
@@ -1143,7 +1143,7 @@ static Object dynamicReceiverCast(Object returnValue, Object lhs) {
return returnValue;
}
}
-
+
/**
* Slow dynamic cast: casts {@code value} to an instance of {@code clazz}
* based upon inspection. If {@code lhs} is null, no cast takes place.
@@ -1173,7 +1173,7 @@ static Object dynamicCast(Class> clazz, Object value) {
return value;
}
}
-
+
/** Slowly returns a Number for o. Just for supporting dynamicCast */
static Number getNumber(Object o) {
if (o instanceof Number) {
@@ -1184,17 +1184,17 @@ static Number getNumber(Object o) {
throw new ClassCastException("Cannot convert [" + o.getClass() + "] to a Number");
}
}
-
+
private static final MethodHandle DYNAMIC_CAST;
private static final MethodHandle DYNAMIC_RECEIVER_CAST;
static {
final Lookup lookup = MethodHandles.lookup();
try {
- DYNAMIC_CAST = lookup.findStatic(lookup.lookupClass(),
- "dynamicCast",
+ DYNAMIC_CAST = lookup.findStatic(lookup.lookupClass(),
+ "dynamicCast",
MethodType.methodType(Object.class, Class.class, Object.class));
- DYNAMIC_RECEIVER_CAST = lookup.findStatic(lookup.lookupClass(),
- "dynamicReceiverCast",
+ DYNAMIC_RECEIVER_CAST = lookup.findStatic(lookup.lookupClass(),
+ "dynamicReceiverCast",
MethodType.methodType(Object.class, Object.class, Object.class));
} catch (ReflectiveOperationException e) {
throw new AssertionError(e);
@@ -1204,7 +1204,7 @@ static Number getNumber(Object o) {
/** Looks up generic method, with a dynamic cast to the receiver's type. (compound assignment) */
public static MethodHandle dynamicCast(MethodHandle target) {
// adapt dynamic receiver cast to the generic method
- MethodHandle cast = DYNAMIC_RECEIVER_CAST.asType(MethodType.methodType(target.type().returnType(),
+ MethodHandle cast = DYNAMIC_RECEIVER_CAST.asType(MethodType.methodType(target.type().returnType(),
target.type().returnType(),
target.type().parameterType(0)));
// drop the RHS parameter
@@ -1212,7 +1212,7 @@ public static MethodHandle dynamicCast(MethodHandle target) {
// combine: f(x,y) -> g(f(x,y), x, y);
return MethodHandles.foldArguments(cast, target);
}
-
+
/** Looks up generic method, with a dynamic cast to the specified type. (explicit assignment) */
public static MethodHandle dynamicCast(MethodHandle target, Class> desired) {
// adapt dynamic cast to the generic method
@@ -1221,23 +1221,23 @@ public static MethodHandle dynamicCast(MethodHandle target, Class> desired) {
MethodHandle cast = DYNAMIC_CAST.bindTo(desired);
return MethodHandles.filterReturnValue(target, cast);
}
-
+
/** Forces a cast to class A for target (only if types differ) */
public static MethodHandle cast(Class> classA, MethodHandle target) {
MethodType newType = MethodType.methodType(classA).unwrap();
MethodType targetType = MethodType.methodType(target.type().returnType()).unwrap();
-
+
// don't do a conversion if types are the same. explicitCastArguments has this opto,
// but we do it explicitly, to make the boolean check simpler
if (newType.returnType() == targetType.returnType()) {
return target;
}
-
+
// we don't allow the to/from boolean conversions of explicitCastArguments
if (newType.returnType() == boolean.class || targetType.returnType() == boolean.class) {
throw new ClassCastException("Cannot cast " + targetType.returnType() + " to " + newType.returnType());
}
-
+
// null return values are not possible for our arguments.
return MethodHandles.explicitCastArguments(target, target.type().changeReturnType(newType.returnType()));
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java
index 75575d6f12568..25145a44b5853 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java
@@ -21,6 +21,7 @@
import org.elasticsearch.painless.spi.Whitelist;
import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
@@ -48,35 +49,6 @@ public final class Definition {
private static final Pattern TYPE_NAME_PATTERN = Pattern.compile("^[_a-zA-Z][._a-zA-Z0-9]*$");
- /** Some native types as constants: */
- public final Type voidType;
- public final Type booleanType;
- public final Type BooleanType;
- public final Type byteType;
- public final Type ByteType;
- public final Type shortType;
- public final Type ShortType;
- public final Type intType;
- public final Type IntegerType;
- public final Type longType;
- public final Type LongType;
- public final Type floatType;
- public final Type FloatType;
- public final Type doubleType;
- public final Type DoubleType;
- public final Type charType;
- public final Type CharacterType;
- public final Type ObjectType;
- public final Type DefType;
- public final Type NumberType;
- public final Type StringType;
- public final Type ExceptionType;
- public final Type PatternType;
- public final Type MatcherType;
- public final Type IteratorType;
- public final Type ArrayListType;
- public final Type HashMapType;
-
/** Marker class for def type to be used during type analysis. */
public static final class def {
private def() {
@@ -84,53 +56,6 @@ private def() {
}
}
- public static final class Type {
- public final String name;
- public final int dimensions;
- public final boolean dynamic;
- public final Struct struct;
- public final Class> clazz;
- public final org.objectweb.asm.Type type;
-
- private Type(final String name, final int dimensions, final boolean dynamic,
- final Struct struct, final Class> clazz, final org.objectweb.asm.Type type) {
- this.name = name;
- this.dimensions = dimensions;
- this.dynamic = dynamic;
- this.struct = struct;
- this.clazz = clazz;
- this.type = type;
- }
-
- @Override
- public boolean equals(final Object object) {
- if (this == object) {
- return true;
- }
-
- if (object == null || getClass() != object.getClass()) {
- return false;
- }
-
- final Type type = (Type)object;
-
- return this.type.equals(type.type) && struct.equals(type.struct);
- }
-
- @Override
- public int hashCode() {
- int result = struct.hashCode();
- result = 31 * result + type.hashCode();
-
- return result;
- }
-
- @Override
- public String toString() {
- return name;
- }
- }
-
public static class Method {
public final String name;
public final Struct owner;
@@ -431,21 +356,6 @@ private Cast(Class> from, Class> to, boolean explicit, Class> unboxFrom, C
}
}
- /** Returns whether or not a non-array type exists. */
- public boolean isSimpleType(final String name) {
- return structsMap.containsKey(name);
- }
-
- /** Gets the type given by its name */
- public Type getType(final String name) {
- return getTypeInternal(name);
- }
-
- /** Creates an array type from the given Struct. */
- public Type getType(final Struct struct, final int dimensions) {
- return getTypeInternal(struct, dimensions);
- }
-
public static Class> getBoxedType(Class> clazz) {
if (clazz == boolean.class) {
return Boolean.class;
@@ -502,6 +412,10 @@ public static boolean isConstantType(Class> clazz) {
clazz == String.class;
}
+ public Class> getClassFromBinaryName(String painlessType) {
+ return painlessTypesToJavaClasses.get(painlessType.replace('$', '.'));
+ }
+
public static Class> ObjectClassTodefClass(Class> clazz) {
if (clazz.isArray()) {
Class> component = clazz.getComponentType();
@@ -590,53 +504,6 @@ public static String ClassToName(Class> clazz) {
return clazz.getCanonicalName().replace('$', '.');
}
- public Type ClassToType(Class> clazz) {
- if (clazz == null) {
- return null;
- } else if (clazz.isArray()) {
- Class> component = clazz.getComponentType();
- int dimensions = 1;
-
- while (component.isArray()) {
- component = component.getComponentType();
- ++dimensions;
- }
-
- if (component == def.class) {
- return getType(structsMap.get(def.class.getSimpleName()), dimensions);
- } else {
- return getType(structsMap.get(ClassToName(component)), dimensions);
- }
- } else if (clazz == def.class) {
- return getType(structsMap.get(def.class.getSimpleName()), 0);
- }
-
- return getType(structsMap.get(ClassToName(clazz)), 0);
- }
-
- public Struct RuntimeClassToStruct(Class> clazz) {
- return structsMap.get(ClassToName(clazz));
- }
-
- public static Class> TypeToClass(Type type) {
- if (def.class.getSimpleName().equals(type.struct.name)) {
- return ObjectClassTodefClass(type.clazz);
- }
-
- return type.clazz;
- }
-
- public Class> getClassFromBinaryName(String name) {
- Struct struct = structsMap.get(name.replace('$', '.'));
-
- return struct == null ? null : struct.clazz;
- }
-
- /** Collection of all simple types. Used by {@code PainlessDocGenerator} to generate an API reference. */
- Collection allSimpleTypes() {
- return simpleTypesMap.values();
- }
-
private static String buildMethodCacheKey(String structName, String methodName, List> arguments) {
StringBuilder key = new StringBuilder();
key.append(structName);
@@ -653,21 +520,21 @@ private static String buildFieldCacheKey(String structName, String fieldName, St
return structName + fieldName + typeName;
}
- // INTERNAL IMPLEMENTATION:
+ public Collection getStructs() {
+ return javaClassesToPainlessStructs.values();
+ }
- private final Map structsMap;
- private final Map simpleTypesMap;
+ private final Map> painlessTypesToJavaClasses;
+ private final Map, Struct> javaClassesToPainlessStructs;
public Definition(List whitelists) {
- structsMap = new HashMap<>();
- simpleTypesMap = new HashMap<>();
+ painlessTypesToJavaClasses = new HashMap<>();
+ javaClassesToPainlessStructs = new HashMap<>();
- Map, Struct> javaClassesToPainlessStructs = new HashMap<>();
String origin = null;
- // add the universal def type
- structsMap.put(def.class.getSimpleName(),
- new Struct(def.class.getSimpleName(), Object.class, org.objectweb.asm.Type.getType(Object.class)));
+ painlessTypesToJavaClasses.put("def", def.class);
+ javaClassesToPainlessStructs.put(def.class, new Struct("def", Object.class, Type.getType(Object.class)));
try {
// first iteration collects all the Painless type names that
@@ -675,7 +542,7 @@ public Definition(List whitelists) {
for (Whitelist whitelist : whitelists) {
for (Whitelist.Struct whitelistStruct : whitelist.whitelistStructs) {
String painlessTypeName = whitelistStruct.javaClassName.replace('$', '.');
- Struct painlessStruct = structsMap.get(painlessTypeName);
+ Struct painlessStruct = javaClassesToPainlessStructs.get(painlessTypesToJavaClasses.get(painlessTypeName));
if (painlessStruct != null && painlessStruct.clazz.getName().equals(whitelistStruct.javaClassName) == false) {
throw new IllegalArgumentException("struct [" + painlessStruct.name + "] cannot represent multiple classes " +
@@ -685,7 +552,7 @@ public Definition(List whitelists) {
origin = whitelistStruct.origin;
addStruct(whitelist.javaClassLoader, whitelistStruct);
- painlessStruct = structsMap.get(painlessTypeName);
+ painlessStruct = javaClassesToPainlessStructs.get(painlessTypesToJavaClasses.get(painlessTypeName));
javaClassesToPainlessStructs.put(painlessStruct.clazz, painlessStruct);
}
}
@@ -719,13 +586,8 @@ public Definition(List whitelists) {
// goes through each Painless struct and determines the inheritance list,
// and then adds all inherited types to the Painless struct's whitelist
- for (Map.Entry painlessNameStructEntry : structsMap.entrySet()) {
- String painlessStructName = painlessNameStructEntry.getKey();
- Struct painlessStruct = painlessNameStructEntry.getValue();
-
- if (painlessStruct.name.equals(painlessStructName) == false) {
- continue;
- }
+ for (Class> javaClass : javaClassesToPainlessStructs.keySet()) {
+ Struct painlessStruct = javaClassesToPainlessStructs.get(javaClass);
List painlessSuperStructs = new ArrayList<>();
Class> javaSuperClass = painlessStruct.clazz.getSuperclass();
@@ -782,52 +644,14 @@ public Definition(List whitelists) {
}
// precompute runtime classes
- for (String painlessStructName : structsMap.keySet()) {
- Struct painlessStruct = structsMap.get(painlessStructName);
-
- if (painlessStruct.name.equals(painlessStructName) == false) {
- continue;
- }
-
+ for (Struct painlessStruct : javaClassesToPainlessStructs.values()) {
addRuntimeClass(painlessStruct);
}
// copy all structs to make them unmodifiable for outside users:
- for (Map.Entry entry : structsMap.entrySet()) {
- if (entry.getKey().equals(entry.getValue().name) == false) {
- continue;
- }
-
+ for (Map.Entry,Struct> entry : javaClassesToPainlessStructs.entrySet()) {
entry.setValue(entry.getValue().freeze(computeFunctionalInterfaceMethod(entry.getValue())));
}
-
- voidType = getType("void");
- booleanType = getType("boolean");
- BooleanType = getType("Boolean");
- byteType = getType("byte");
- ByteType = getType("Byte");
- shortType = getType("short");
- ShortType = getType("Short");
- intType = getType("int");
- IntegerType = getType("Integer");
- longType = getType("long");
- LongType = getType("Long");
- floatType = getType("float");
- FloatType = getType("Float");
- doubleType = getType("double");
- DoubleType = getType("Double");
- charType = getType("char");
- CharacterType = getType("Character");
- ObjectType = getType("Object");
- DefType = getType(def.class.getSimpleName());
- NumberType = getType("Number");
- StringType = getType("String");
- ExceptionType = getType("Exception");
- PatternType = getType("Pattern");
- MatcherType = getType("Matcher");
- IteratorType = getType("Iterator");
- ArrayListType = getType("ArrayList");
- HashMapType = getType("HashMap");
}
private void addStruct(ClassLoader whitelistClassLoader, Whitelist.Struct whitelistStruct) {
@@ -864,35 +688,45 @@ private void addStruct(ClassLoader whitelistClassLoader, Whitelist.Struct whitel
}
}
- Struct existingStruct = structsMap.get(painlessTypeName);
+ Struct existingStruct = javaClassesToPainlessStructs.get(javaClass);
if (existingStruct == null) {
Struct struct = new Struct(painlessTypeName, javaClass, org.objectweb.asm.Type.getType(javaClass));
- structsMap.put(painlessTypeName, struct);
-
- if (whitelistStruct.onlyFQNJavaClassName) {
- simpleTypesMap.put(painlessTypeName, getType(painlessTypeName));
- } else if (simpleTypesMap.containsKey(importedPainlessTypeName) == false) {
- simpleTypesMap.put(importedPainlessTypeName, getType(painlessTypeName));
- structsMap.put(importedPainlessTypeName, struct);
- } else {
- throw new IllegalArgumentException("duplicate short name [" + importedPainlessTypeName + "] " +
- "found for struct [" + painlessTypeName + "]");
- }
+ painlessTypesToJavaClasses.put(painlessTypeName, javaClass);
+ javaClassesToPainlessStructs.put(javaClass, struct);
} else if (existingStruct.clazz.equals(javaClass) == false) {
throw new IllegalArgumentException("struct [" + painlessTypeName + "] is used to " +
"illegally represent multiple java classes [" + whitelistStruct.javaClassName + "] and " +
"[" + existingStruct.clazz.getName() + "]");
- } else if (whitelistStruct.onlyFQNJavaClassName && simpleTypesMap.containsKey(importedPainlessTypeName) &&
- simpleTypesMap.get(importedPainlessTypeName).clazz == javaClass ||
- whitelistStruct.onlyFQNJavaClassName == false && (simpleTypesMap.containsKey(importedPainlessTypeName) == false ||
- simpleTypesMap.get(importedPainlessTypeName).clazz != javaClass)) {
- throw new IllegalArgumentException("inconsistent only_fqn parameters found for type [" + painlessTypeName + "]");
+ }
+
+ if (painlessTypeName.equals(importedPainlessTypeName)) {
+ if (whitelistStruct.onlyFQNJavaClassName == false) {
+ throw new IllegalArgumentException("must use only_fqn parameter on type [" + painlessTypeName + "] with no package");
+ }
+ } else {
+ Class> importedJavaClass = painlessTypesToJavaClasses.get(importedPainlessTypeName);
+
+ if (importedJavaClass == null) {
+ if (whitelistStruct.onlyFQNJavaClassName == false) {
+ if (existingStruct != null) {
+ throw new IllegalArgumentException("inconsistent only_fqn parameters found for type [" + painlessTypeName + "]");
+ }
+
+ painlessTypesToJavaClasses.put(importedPainlessTypeName, javaClass);
+ }
+ } else if (importedJavaClass.equals(javaClass) == false) {
+ throw new IllegalArgumentException("imported name [" + painlessTypeName + "] is used to " +
+ "illegally represent multiple java classes [" + whitelistStruct.javaClassName + "] " +
+ "and [" + importedJavaClass.getName() + "]");
+ } else if (whitelistStruct.onlyFQNJavaClassName) {
+ throw new IllegalArgumentException("inconsistent only_fqn parameters found for type [" + painlessTypeName + "]");
+ }
}
}
private void addConstructor(String ownerStructName, Whitelist.Constructor whitelistConstructor) {
- Struct ownerStruct = structsMap.get(ownerStructName);
+ Struct ownerStruct = javaClassesToPainlessStructs.get(painlessTypesToJavaClasses.get(ownerStructName));
if (ownerStruct == null) {
throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for constructor with " +
@@ -906,7 +740,7 @@ private void addConstructor(String ownerStructName, Whitelist.Constructor whitel
String painlessParameterTypeName = whitelistConstructor.painlessParameterTypeNames.get(parameterCount);
try {
- Class> painlessParameterClass = TypeToClass(getTypeInternal(painlessParameterTypeName));
+ Class> painlessParameterClass = getJavaClassFromPainlessType(painlessParameterTypeName);
painlessParametersTypes.add(painlessParameterClass);
javaClassParameters[parameterCount] = defClassToObjectClass(painlessParameterClass);
@@ -952,7 +786,7 @@ private void addConstructor(String ownerStructName, Whitelist.Constructor whitel
}
private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName, Whitelist.Method whitelistMethod) {
- Struct ownerStruct = structsMap.get(ownerStructName);
+ Struct ownerStruct = javaClassesToPainlessStructs.get(painlessTypesToJavaClasses.get(ownerStructName));
if (ownerStruct == null) {
throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for method with " +
@@ -991,7 +825,7 @@ private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName,
String painlessParameterTypeName = whitelistMethod.painlessParameterTypeNames.get(parameterCount);
try {
- Class> painlessParameterClass = TypeToClass(getTypeInternal(painlessParameterTypeName));
+ Class> painlessParameterClass = getJavaClassFromPainlessType(painlessParameterTypeName);
painlessParametersTypes.add(painlessParameterClass);
javaClassParameters[parameterCount + augmentedOffset] = defClassToObjectClass(painlessParameterClass);
@@ -1016,7 +850,7 @@ private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName,
Class> painlessReturnClass;
try {
- painlessReturnClass = TypeToClass(getTypeInternal(whitelistMethod.painlessReturnTypeName));
+ painlessReturnClass = getJavaClassFromPainlessType(whitelistMethod.painlessReturnTypeName);
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("struct not defined for return type [" + whitelistMethod.painlessReturnTypeName + "] " +
"with owner struct [" + ownerStructName + "] and method with name [" + whitelistMethod.javaMethodName + "] " +
@@ -1088,7 +922,7 @@ private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName,
}
private void addField(String ownerStructName, Whitelist.Field whitelistField) {
- Struct ownerStruct = structsMap.get(ownerStructName);
+ Struct ownerStruct = javaClassesToPainlessStructs.get(painlessTypesToJavaClasses.get(ownerStructName));
if (ownerStruct == null) {
throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for method with " +
@@ -1112,7 +946,7 @@ private void addField(String ownerStructName, Whitelist.Field whitelistField) {
Class> painlessFieldClass;
try {
- painlessFieldClass = TypeToClass(getTypeInternal(whitelistField.painlessFieldTypeName));
+ painlessFieldClass = getJavaClassFromPainlessType(whitelistField.painlessFieldTypeName);
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("struct not defined for return type [" + whitelistField.painlessFieldTypeName + "] " +
"with owner struct [" + ownerStructName + "] and field with name [" + whitelistField.javaFieldName + "]", iae);
@@ -1169,14 +1003,14 @@ private void addField(String ownerStructName, Whitelist.Field whitelistField) {
}
private void copyStruct(String struct, List children) {
- final Struct owner = structsMap.get(struct);
+ final Struct owner = javaClassesToPainlessStructs.get(painlessTypesToJavaClasses.get(struct));
if (owner == null) {
throw new IllegalArgumentException("Owner struct [" + struct + "] not defined for copy.");
}
for (int count = 0; count < children.size(); ++count) {
- final Struct child = structsMap.get(children.get(count));
+ final Struct child = javaClassesToPainlessStructs.get(painlessTypesToJavaClasses.get(children.get(count)));
if (child == null) {
throw new IllegalArgumentException("Child struct [" + children.get(count) + "]" +
@@ -1340,71 +1174,68 @@ private Method computeFunctionalInterfaceMethod(Struct clazz) {
return painless;
}
- private Type getTypeInternal(String name) {
- // simple types (e.g. 0 array dimensions) are a simple hash lookup for speed
- Type simple = simpleTypesMap.get(name);
+ public boolean isSimplePainlessType(String painlessType) {
+ return painlessTypesToJavaClasses.containsKey(painlessType);
+ }
- if (simple != null) {
- return simple;
- }
+ public Struct getPainlessStructFromJavaClass(Class> clazz) {
+ return javaClassesToPainlessStructs.get(clazz);
+ }
- int dimensions = getDimensions(name);
- String structstr = dimensions == 0 ? name : name.substring(0, name.indexOf('['));
- Struct struct = structsMap.get(structstr);
+ public Class> getJavaClassFromPainlessType(String painlessType) {
+ Class> javaClass = painlessTypesToJavaClasses.get(painlessType);
- if (struct == null) {
- throw new IllegalArgumentException("The struct with name [" + name + "] has not been defined.");
+ if (javaClass != null) {
+ return javaClass;
}
+ int arrayDimensions = 0;
+ int arrayIndex = painlessType.indexOf('[');
- return getTypeInternal(struct, dimensions);
- }
-
- private Type getTypeInternal(Struct struct, int dimensions) {
- String name = struct.name;
- org.objectweb.asm.Type type = struct.type;
- Class> clazz = struct.clazz;
+ if (arrayIndex != -1) {
+ int length = painlessType.length();
- if (dimensions > 0) {
- StringBuilder builder = new StringBuilder(name);
- char[] brackets = new char[dimensions];
-
- for (int count = 0; count < dimensions; ++count) {
- builder.append("[]");
- brackets[count] = '[';
+ while (arrayIndex < length) {
+ if (painlessType.charAt(arrayIndex) == '[' && ++arrayIndex < length && painlessType.charAt(arrayIndex++) == ']') {
+ ++arrayDimensions;
+ } else {
+ throw new IllegalArgumentException("invalid painless type [" + painlessType + "].");
+ }
}
- String descriptor = new String(brackets) + struct.type.getDescriptor();
-
- name = builder.toString();
- type = org.objectweb.asm.Type.getType(descriptor);
-
- try {
- clazz = Class.forName(type.getInternalName().replace('/', '.'));
- } catch (ClassNotFoundException exception) {
- throw new IllegalArgumentException("The class [" + type.getInternalName() + "]" +
- " could not be found to create type [" + name + "].");
+ painlessType = painlessType.substring(0, painlessType.indexOf('['));
+ javaClass = painlessTypesToJavaClasses.get(painlessType);
+
+ char braces[] = new char[arrayDimensions];
+ Arrays.fill(braces, '[');
+ String descriptor = new String(braces);
+
+ if (javaClass == boolean.class) {
+ descriptor += "Z";
+ } else if (javaClass == byte.class) {
+ descriptor += "B";
+ } else if (javaClass == short.class) {
+ descriptor += "S";
+ } else if (javaClass == char.class) {
+ descriptor += "C";
+ } else if (javaClass == int.class) {
+ descriptor += "I";
+ } else if (javaClass == long.class) {
+ descriptor += "J";
+ } else if (javaClass == float.class) {
+ descriptor += "F";
+ } else if (javaClass == double.class) {
+ descriptor += "D";
+ } else {
+ descriptor += "L" + javaClass.getName() + ";";
}
- }
-
- return new Type(name, dimensions, def.class.getSimpleName().equals(name), struct, clazz, type);
- }
- private int getDimensions(String name) {
- int dimensions = 0;
- int index = name.indexOf('[');
-
- if (index != -1) {
- int length = name.length();
-
- while (index < length) {
- if (name.charAt(index) == '[' && ++index < length && name.charAt(index++) == ']') {
- ++dimensions;
- } else {
- throw new IllegalArgumentException("Invalid array braces in canonical name [" + name + "].");
- }
+ try {
+ return Class.forName(descriptor);
+ } catch (ClassNotFoundException cnfe) {
+ throw new IllegalStateException("invalid painless type [" + painlessType + "]", cnfe);
}
}
- return dimensions;
+ throw new IllegalArgumentException("invalid painless type [" + painlessType + "]");
}
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/FunctionRef.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/FunctionRef.java
index 0b698dd244192..1b438965538ce 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/FunctionRef.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/FunctionRef.java
@@ -78,7 +78,7 @@ public class FunctionRef {
* @param numCaptures number of captured arguments
*/
public FunctionRef(Definition definition, Class> expected, String type, String call, int numCaptures) {
- this(expected, definition.ClassToType(expected).struct.functionalMethod,
+ this(expected, definition.getPainlessStructFromJavaClass(expected).functionalMethod,
lookup(definition, expected, type, call, numCaptures > 0), numCaptures);
}
@@ -162,14 +162,14 @@ private static Definition.Method lookup(Definition definition, Class> expected
String type, String call, boolean receiverCaptured) {
// check its really a functional interface
// for e.g. Comparable
- Method method = definition.ClassToType(expected).struct.functionalMethod;
+ Method method = definition.getPainlessStructFromJavaClass(expected).functionalMethod;
if (method == null) {
throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " +
"to [" + Definition.ClassToName(expected) + "], not a functional interface");
}
// lookup requested method
- Definition.Struct struct = definition.getType(type).struct;
+ Definition.Struct struct = definition.getPainlessStructFromJavaClass(definition.getJavaClassFromPainlessType(type));
final Definition.Method impl;
// ctor ref
if ("new".equals(call)) {
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessExplainError.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessExplainError.java
index 0b2fdf35890a0..7ae93eba22632 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessExplainError.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessExplainError.java
@@ -54,7 +54,7 @@ public Map> getHeaders(Definition definition) {
if (objectToExplain != null) {
toString = objectToExplain.toString();
javaClassName = objectToExplain.getClass().getName();
- Definition.Struct struct = definition.ClassToType(objectToExplain.getClass()).struct;
+ Definition.Struct struct = definition.getPainlessStructFromJavaClass(objectToExplain.getClass());
if (struct != null) {
painlessClassName = struct.name;
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java
index 4ebcf8bfb82d2..833ff0eac4134 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java
@@ -31,8 +31,8 @@
import org.elasticsearch.common.settings.SettingsFilter;
import org.elasticsearch.painless.spi.PainlessExtension;
import org.elasticsearch.painless.spi.Whitelist;
-import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.painless.spi.WhitelistLoader;
+import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.plugins.ExtensiblePlugin;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.plugins.ScriptPlugin;
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java
index 60ce1d033532a..0ec806282db2f 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java
@@ -179,22 +179,18 @@ private MethodArgument methodArgument(Definition definition, Class> clazz, Str
private static Class> definitionTypeForClass(Definition definition, Class> type,
Function, String> unknownErrorMessageSource) {
- int dimensions = 0;
+ type = Definition.ObjectClassTodefClass(type);
Class> componentType = type;
+
while (componentType.isArray()) {
- dimensions++;
componentType = componentType.getComponentType();
}
- Definition.Struct struct;
- if (componentType == Object.class) {
- struct = definition.getType("def").struct;
- } else {
- if (definition.RuntimeClassToStruct(componentType) == null) {
- throw new IllegalArgumentException(unknownErrorMessageSource.apply(componentType));
- }
- struct = definition.RuntimeClassToStruct(componentType);
+
+ if (definition.getPainlessStructFromJavaClass(componentType) == null) {
+ throw new IllegalArgumentException(unknownErrorMessageSource.apply(componentType));
}
- return Definition.TypeToClass(definition.getType(struct, dimensions));
+
+ return type;
}
private static String[] readArgumentNamesConstant(Class> iface) {
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/EnhancedPainlessLexer.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/EnhancedPainlessLexer.java
index cf24a47386603..add3aaabe51e0 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/EnhancedPainlessLexer.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/EnhancedPainlessLexer.java
@@ -74,8 +74,8 @@ public void recover(final LexerNoViableAltException lnvae) {
}
@Override
- protected boolean isSimpleType(String name) {
- return definition.isSimpleType(name);
+ protected boolean isType(String name) {
+ return definition.isSimplePainlessType(name);
}
@Override
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessLexer.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessLexer.java
index dd62701b86e4d..7fa10f6e9fbf2 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessLexer.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessLexer.java
@@ -1,9 +1,16 @@
// ANTLR GENERATED CODE: DO NOT EDIT
package org.elasticsearch.painless.antlr;
-import org.antlr.v4.runtime.Lexer;
+
import org.antlr.v4.runtime.CharStream;
-import org.antlr.v4.runtime.*;
-import org.antlr.v4.runtime.atn.*;
+import org.antlr.v4.runtime.Lexer;
+import org.antlr.v4.runtime.RuleContext;
+import org.antlr.v4.runtime.RuntimeMetaData;
+import org.antlr.v4.runtime.Vocabulary;
+import org.antlr.v4.runtime.VocabularyImpl;
+import org.antlr.v4.runtime.atn.ATN;
+import org.antlr.v4.runtime.atn.ATNDeserializer;
+import org.antlr.v4.runtime.atn.LexerATNSimulator;
+import org.antlr.v4.runtime.atn.PredictionContextCache;
import org.antlr.v4.runtime.dfa.DFA;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
@@ -14,16 +21,16 @@ abstract class PainlessLexer extends Lexer {
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
- WS=1, COMMENT=2, LBRACK=3, RBRACK=4, LBRACE=5, RBRACE=6, LP=7, RP=8, DOT=9,
- NSDOT=10, COMMA=11, SEMICOLON=12, IF=13, IN=14, ELSE=15, WHILE=16, DO=17,
- FOR=18, CONTINUE=19, BREAK=20, RETURN=21, NEW=22, TRY=23, CATCH=24, THROW=25,
- THIS=26, INSTANCEOF=27, BOOLNOT=28, BWNOT=29, MUL=30, DIV=31, REM=32,
- ADD=33, SUB=34, LSH=35, RSH=36, USH=37, LT=38, LTE=39, GT=40, GTE=41,
- EQ=42, EQR=43, NE=44, NER=45, BWAND=46, XOR=47, BWOR=48, BOOLAND=49, BOOLOR=50,
- COND=51, COLON=52, ELVIS=53, REF=54, ARROW=55, FIND=56, MATCH=57, INCR=58,
- DECR=59, ASSIGN=60, AADD=61, ASUB=62, AMUL=63, ADIV=64, AREM=65, AAND=66,
- AXOR=67, AOR=68, ALSH=69, ARSH=70, AUSH=71, OCTAL=72, HEX=73, INTEGER=74,
- DECIMAL=75, STRING=76, REGEX=77, TRUE=78, FALSE=79, NULL=80, TYPE=81,
+ WS=1, COMMENT=2, LBRACK=3, RBRACK=4, LBRACE=5, RBRACE=6, LP=7, RP=8, DOT=9,
+ NSDOT=10, COMMA=11, SEMICOLON=12, IF=13, IN=14, ELSE=15, WHILE=16, DO=17,
+ FOR=18, CONTINUE=19, BREAK=20, RETURN=21, NEW=22, TRY=23, CATCH=24, THROW=25,
+ THIS=26, INSTANCEOF=27, BOOLNOT=28, BWNOT=29, MUL=30, DIV=31, REM=32,
+ ADD=33, SUB=34, LSH=35, RSH=36, USH=37, LT=38, LTE=39, GT=40, GTE=41,
+ EQ=42, EQR=43, NE=44, NER=45, BWAND=46, XOR=47, BWOR=48, BOOLAND=49, BOOLOR=50,
+ COND=51, COLON=52, ELVIS=53, REF=54, ARROW=55, FIND=56, MATCH=57, INCR=58,
+ DECR=59, ASSIGN=60, AADD=61, ASUB=62, AMUL=63, ADIV=64, AREM=65, AAND=66,
+ AXOR=67, AOR=68, ALSH=69, ARSH=70, AUSH=71, OCTAL=72, HEX=73, INTEGER=74,
+ DECIMAL=75, STRING=76, REGEX=77, TRUE=78, FALSE=79, NULL=80, TYPE=81,
ID=82, DOTINTEGER=83, DOTID=84;
public static final int AFTER_DOT = 1;
public static String[] modeNames = {
@@ -31,39 +38,39 @@ abstract class PainlessLexer extends Lexer {
};
public static final String[] ruleNames = {
- "WS", "COMMENT", "LBRACK", "RBRACK", "LBRACE", "RBRACE", "LP", "RP", "DOT",
- "NSDOT", "COMMA", "SEMICOLON", "IF", "IN", "ELSE", "WHILE", "DO", "FOR",
- "CONTINUE", "BREAK", "RETURN", "NEW", "TRY", "CATCH", "THROW", "THIS",
- "INSTANCEOF", "BOOLNOT", "BWNOT", "MUL", "DIV", "REM", "ADD", "SUB", "LSH",
- "RSH", "USH", "LT", "LTE", "GT", "GTE", "EQ", "EQR", "NE", "NER", "BWAND",
- "XOR", "BWOR", "BOOLAND", "BOOLOR", "COND", "COLON", "ELVIS", "REF", "ARROW",
- "FIND", "MATCH", "INCR", "DECR", "ASSIGN", "AADD", "ASUB", "AMUL", "ADIV",
- "AREM", "AAND", "AXOR", "AOR", "ALSH", "ARSH", "AUSH", "OCTAL", "HEX",
- "INTEGER", "DECIMAL", "STRING", "REGEX", "TRUE", "FALSE", "NULL", "TYPE",
+ "WS", "COMMENT", "LBRACK", "RBRACK", "LBRACE", "RBRACE", "LP", "RP", "DOT",
+ "NSDOT", "COMMA", "SEMICOLON", "IF", "IN", "ELSE", "WHILE", "DO", "FOR",
+ "CONTINUE", "BREAK", "RETURN", "NEW", "TRY", "CATCH", "THROW", "THIS",
+ "INSTANCEOF", "BOOLNOT", "BWNOT", "MUL", "DIV", "REM", "ADD", "SUB", "LSH",
+ "RSH", "USH", "LT", "LTE", "GT", "GTE", "EQ", "EQR", "NE", "NER", "BWAND",
+ "XOR", "BWOR", "BOOLAND", "BOOLOR", "COND", "COLON", "ELVIS", "REF", "ARROW",
+ "FIND", "MATCH", "INCR", "DECR", "ASSIGN", "AADD", "ASUB", "AMUL", "ADIV",
+ "AREM", "AAND", "AXOR", "AOR", "ALSH", "ARSH", "AUSH", "OCTAL", "HEX",
+ "INTEGER", "DECIMAL", "STRING", "REGEX", "TRUE", "FALSE", "NULL", "TYPE",
"ID", "DOTINTEGER", "DOTID"
};
private static final String[] _LITERAL_NAMES = {
- null, null, null, "'{'", "'}'", "'['", "']'", "'('", "')'", "'.'", "'?.'",
- "','", "';'", "'if'", "'in'", "'else'", "'while'", "'do'", "'for'", "'continue'",
- "'break'", "'return'", "'new'", "'try'", "'catch'", "'throw'", "'this'",
- "'instanceof'", "'!'", "'~'", "'*'", "'/'", "'%'", "'+'", "'-'", "'<<'",
- "'>>'", "'>>>'", "'<'", "'<='", "'>'", "'>='", "'=='", "'==='", "'!='",
- "'!=='", "'&'", "'^'", "'|'", "'&&'", "'||'", "'?'", "':'", "'?:'", "'::'",
- "'->'", "'=~'", "'==~'", "'++'", "'--'", "'='", "'+='", "'-='", "'*='",
- "'/='", "'%='", "'&='", "'^='", "'|='", "'<<='", "'>>='", "'>>>='", null,
+ null, null, null, "'{'", "'}'", "'['", "']'", "'('", "')'", "'.'", "'?.'",
+ "','", "';'", "'if'", "'in'", "'else'", "'while'", "'do'", "'for'", "'continue'",
+ "'break'", "'return'", "'new'", "'try'", "'catch'", "'throw'", "'this'",
+ "'instanceof'", "'!'", "'~'", "'*'", "'/'", "'%'", "'+'", "'-'", "'<<'",
+ "'>>'", "'>>>'", "'<'", "'<='", "'>'", "'>='", "'=='", "'==='", "'!='",
+ "'!=='", "'&'", "'^'", "'|'", "'&&'", "'||'", "'?'", "':'", "'?:'", "'::'",
+ "'->'", "'=~'", "'==~'", "'++'", "'--'", "'='", "'+='", "'-='", "'*='",
+ "'/='", "'%='", "'&='", "'^='", "'|='", "'<<='", "'>>='", "'>>>='", null,
null, null, null, null, null, "'true'", "'false'", "'null'"
};
private static final String[] _SYMBOLIC_NAMES = {
- null, "WS", "COMMENT", "LBRACK", "RBRACK", "LBRACE", "RBRACE", "LP", "RP",
- "DOT", "NSDOT", "COMMA", "SEMICOLON", "IF", "IN", "ELSE", "WHILE", "DO",
- "FOR", "CONTINUE", "BREAK", "RETURN", "NEW", "TRY", "CATCH", "THROW",
- "THIS", "INSTANCEOF", "BOOLNOT", "BWNOT", "MUL", "DIV", "REM", "ADD",
- "SUB", "LSH", "RSH", "USH", "LT", "LTE", "GT", "GTE", "EQ", "EQR", "NE",
- "NER", "BWAND", "XOR", "BWOR", "BOOLAND", "BOOLOR", "COND", "COLON", "ELVIS",
- "REF", "ARROW", "FIND", "MATCH", "INCR", "DECR", "ASSIGN", "AADD", "ASUB",
- "AMUL", "ADIV", "AREM", "AAND", "AXOR", "AOR", "ALSH", "ARSH", "AUSH",
- "OCTAL", "HEX", "INTEGER", "DECIMAL", "STRING", "REGEX", "TRUE", "FALSE",
+ null, "WS", "COMMENT", "LBRACK", "RBRACK", "LBRACE", "RBRACE", "LP", "RP",
+ "DOT", "NSDOT", "COMMA", "SEMICOLON", "IF", "IN", "ELSE", "WHILE", "DO",
+ "FOR", "CONTINUE", "BREAK", "RETURN", "NEW", "TRY", "CATCH", "THROW",
+ "THIS", "INSTANCEOF", "BOOLNOT", "BWNOT", "MUL", "DIV", "REM", "ADD",
+ "SUB", "LSH", "RSH", "USH", "LT", "LTE", "GT", "GTE", "EQ", "EQR", "NE",
+ "NER", "BWAND", "XOR", "BWOR", "BOOLAND", "BOOLOR", "COND", "COLON", "ELVIS",
+ "REF", "ARROW", "FIND", "MATCH", "INCR", "DECR", "ASSIGN", "AADD", "ASUB",
+ "AMUL", "ADIV", "AREM", "AAND", "AXOR", "AOR", "ALSH", "ARSH", "AUSH",
+ "OCTAL", "HEX", "INTEGER", "DECIMAL", "STRING", "REGEX", "TRUE", "FALSE",
"NULL", "TYPE", "ID", "DOTINTEGER", "DOTID"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
@@ -106,7 +113,7 @@ public Vocabulary getVocabulary() {
* See also
* The lexer hack.
*/
- protected abstract boolean isSimpleType(String name);
+ protected abstract boolean isType(String name);
/**
* Is the preceding {@code /} a the beginning of a regex (true) or a division
@@ -164,7 +171,7 @@ private boolean REGEX_sempred(RuleContext _localctx, int predIndex) {
private boolean TYPE_sempred(RuleContext _localctx, int predIndex) {
switch (predIndex) {
case 2:
- return isSimpleType(getText()) ;
+ return isType(getText()) ;
}
return true;
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java
index 9cd3334aa51da..bef57d22e9ea9 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java
@@ -1,9 +1,24 @@
// ANTLR GENERATED CODE: DO NOT EDIT
package org.elasticsearch.painless.antlr;
-import org.antlr.v4.runtime.atn.*;
+
+import org.antlr.v4.runtime.FailedPredicateException;
+import org.antlr.v4.runtime.NoViableAltException;
+import org.antlr.v4.runtime.Parser;
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.RuleContext;
+import org.antlr.v4.runtime.RuntimeMetaData;
+import org.antlr.v4.runtime.TokenStream;
+import org.antlr.v4.runtime.Vocabulary;
+import org.antlr.v4.runtime.VocabularyImpl;
+import org.antlr.v4.runtime.atn.ATN;
+import org.antlr.v4.runtime.atn.ATNDeserializer;
+import org.antlr.v4.runtime.atn.ParserATNSimulator;
+import org.antlr.v4.runtime.atn.PredictionContextCache;
import org.antlr.v4.runtime.dfa.DFA;
-import org.antlr.v4.runtime.*;
-import org.antlr.v4.runtime.tree.*;
+import org.antlr.v4.runtime.tree.ParseTreeVisitor;
+import org.antlr.v4.runtime.tree.TerminalNode;
+
import java.util.List;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
@@ -14,57 +29,57 @@ class PainlessParser extends Parser {
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
- WS=1, COMMENT=2, LBRACK=3, RBRACK=4, LBRACE=5, RBRACE=6, LP=7, RP=8, DOT=9,
- NSDOT=10, COMMA=11, SEMICOLON=12, IF=13, IN=14, ELSE=15, WHILE=16, DO=17,
- FOR=18, CONTINUE=19, BREAK=20, RETURN=21, NEW=22, TRY=23, CATCH=24, THROW=25,
- THIS=26, INSTANCEOF=27, BOOLNOT=28, BWNOT=29, MUL=30, DIV=31, REM=32,
- ADD=33, SUB=34, LSH=35, RSH=36, USH=37, LT=38, LTE=39, GT=40, GTE=41,
- EQ=42, EQR=43, NE=44, NER=45, BWAND=46, XOR=47, BWOR=48, BOOLAND=49, BOOLOR=50,
- COND=51, COLON=52, ELVIS=53, REF=54, ARROW=55, FIND=56, MATCH=57, INCR=58,
- DECR=59, ASSIGN=60, AADD=61, ASUB=62, AMUL=63, ADIV=64, AREM=65, AAND=66,
- AXOR=67, AOR=68, ALSH=69, ARSH=70, AUSH=71, OCTAL=72, HEX=73, INTEGER=74,
- DECIMAL=75, STRING=76, REGEX=77, TRUE=78, FALSE=79, NULL=80, TYPE=81,
+ WS=1, COMMENT=2, LBRACK=3, RBRACK=4, LBRACE=5, RBRACE=6, LP=7, RP=8, DOT=9,
+ NSDOT=10, COMMA=11, SEMICOLON=12, IF=13, IN=14, ELSE=15, WHILE=16, DO=17,
+ FOR=18, CONTINUE=19, BREAK=20, RETURN=21, NEW=22, TRY=23, CATCH=24, THROW=25,
+ THIS=26, INSTANCEOF=27, BOOLNOT=28, BWNOT=29, MUL=30, DIV=31, REM=32,
+ ADD=33, SUB=34, LSH=35, RSH=36, USH=37, LT=38, LTE=39, GT=40, GTE=41,
+ EQ=42, EQR=43, NE=44, NER=45, BWAND=46, XOR=47, BWOR=48, BOOLAND=49, BOOLOR=50,
+ COND=51, COLON=52, ELVIS=53, REF=54, ARROW=55, FIND=56, MATCH=57, INCR=58,
+ DECR=59, ASSIGN=60, AADD=61, ASUB=62, AMUL=63, ADIV=64, AREM=65, AAND=66,
+ AXOR=67, AOR=68, ALSH=69, ARSH=70, AUSH=71, OCTAL=72, HEX=73, INTEGER=74,
+ DECIMAL=75, STRING=76, REGEX=77, TRUE=78, FALSE=79, NULL=80, TYPE=81,
ID=82, DOTINTEGER=83, DOTID=84;
public static final int
- RULE_source = 0, RULE_function = 1, RULE_parameters = 2, RULE_statement = 3,
- RULE_rstatement = 4, RULE_dstatement = 5, RULE_trailer = 6, RULE_block = 7,
- RULE_empty = 8, RULE_initializer = 9, RULE_afterthought = 10, RULE_declaration = 11,
- RULE_decltype = 12, RULE_declvar = 13, RULE_trap = 14, RULE_expression = 15,
- RULE_unary = 16, RULE_chain = 17, RULE_primary = 18, RULE_postfix = 19,
- RULE_postdot = 20, RULE_callinvoke = 21, RULE_fieldaccess = 22, RULE_braceaccess = 23,
- RULE_arrayinitializer = 24, RULE_listinitializer = 25, RULE_mapinitializer = 26,
- RULE_maptoken = 27, RULE_arguments = 28, RULE_argument = 29, RULE_lambda = 30,
+ RULE_source = 0, RULE_function = 1, RULE_parameters = 2, RULE_statement = 3,
+ RULE_rstatement = 4, RULE_dstatement = 5, RULE_trailer = 6, RULE_block = 7,
+ RULE_empty = 8, RULE_initializer = 9, RULE_afterthought = 10, RULE_declaration = 11,
+ RULE_decltype = 12, RULE_declvar = 13, RULE_trap = 14, RULE_expression = 15,
+ RULE_unary = 16, RULE_chain = 17, RULE_primary = 18, RULE_postfix = 19,
+ RULE_postdot = 20, RULE_callinvoke = 21, RULE_fieldaccess = 22, RULE_braceaccess = 23,
+ RULE_arrayinitializer = 24, RULE_listinitializer = 25, RULE_mapinitializer = 26,
+ RULE_maptoken = 27, RULE_arguments = 28, RULE_argument = 29, RULE_lambda = 30,
RULE_lamtype = 31, RULE_funcref = 32;
public static final String[] ruleNames = {
- "source", "function", "parameters", "statement", "rstatement", "dstatement",
- "trailer", "block", "empty", "initializer", "afterthought", "declaration",
- "decltype", "declvar", "trap", "expression", "unary", "chain", "primary",
- "postfix", "postdot", "callinvoke", "fieldaccess", "braceaccess", "arrayinitializer",
- "listinitializer", "mapinitializer", "maptoken", "arguments", "argument",
+ "source", "function", "parameters", "statement", "rstatement", "dstatement",
+ "trailer", "block", "empty", "initializer", "afterthought", "declaration",
+ "decltype", "declvar", "trap", "expression", "unary", "chain", "primary",
+ "postfix", "postdot", "callinvoke", "fieldaccess", "braceaccess", "arrayinitializer",
+ "listinitializer", "mapinitializer", "maptoken", "arguments", "argument",
"lambda", "lamtype", "funcref"
};
private static final String[] _LITERAL_NAMES = {
- null, null, null, "'{'", "'}'", "'['", "']'", "'('", "')'", "'.'", "'?.'",
- "','", "';'", "'if'", "'in'", "'else'", "'while'", "'do'", "'for'", "'continue'",
- "'break'", "'return'", "'new'", "'try'", "'catch'", "'throw'", "'this'",
- "'instanceof'", "'!'", "'~'", "'*'", "'/'", "'%'", "'+'", "'-'", "'<<'",
- "'>>'", "'>>>'", "'<'", "'<='", "'>'", "'>='", "'=='", "'==='", "'!='",
- "'!=='", "'&'", "'^'", "'|'", "'&&'", "'||'", "'?'", "':'", "'?:'", "'::'",
- "'->'", "'=~'", "'==~'", "'++'", "'--'", "'='", "'+='", "'-='", "'*='",
- "'/='", "'%='", "'&='", "'^='", "'|='", "'<<='", "'>>='", "'>>>='", null,
+ null, null, null, "'{'", "'}'", "'['", "']'", "'('", "')'", "'.'", "'?.'",
+ "','", "';'", "'if'", "'in'", "'else'", "'while'", "'do'", "'for'", "'continue'",
+ "'break'", "'return'", "'new'", "'try'", "'catch'", "'throw'", "'this'",
+ "'instanceof'", "'!'", "'~'", "'*'", "'/'", "'%'", "'+'", "'-'", "'<<'",
+ "'>>'", "'>>>'", "'<'", "'<='", "'>'", "'>='", "'=='", "'==='", "'!='",
+ "'!=='", "'&'", "'^'", "'|'", "'&&'", "'||'", "'?'", "':'", "'?:'", "'::'",
+ "'->'", "'=~'", "'==~'", "'++'", "'--'", "'='", "'+='", "'-='", "'*='",
+ "'/='", "'%='", "'&='", "'^='", "'|='", "'<<='", "'>>='", "'>>>='", null,
null, null, null, null, null, "'true'", "'false'", "'null'"
};
private static final String[] _SYMBOLIC_NAMES = {
- null, "WS", "COMMENT", "LBRACK", "RBRACK", "LBRACE", "RBRACE", "LP", "RP",
- "DOT", "NSDOT", "COMMA", "SEMICOLON", "IF", "IN", "ELSE", "WHILE", "DO",
- "FOR", "CONTINUE", "BREAK", "RETURN", "NEW", "TRY", "CATCH", "THROW",
- "THIS", "INSTANCEOF", "BOOLNOT", "BWNOT", "MUL", "DIV", "REM", "ADD",
- "SUB", "LSH", "RSH", "USH", "LT", "LTE", "GT", "GTE", "EQ", "EQR", "NE",
- "NER", "BWAND", "XOR", "BWOR", "BOOLAND", "BOOLOR", "COND", "COLON", "ELVIS",
- "REF", "ARROW", "FIND", "MATCH", "INCR", "DECR", "ASSIGN", "AADD", "ASUB",
- "AMUL", "ADIV", "AREM", "AAND", "AXOR", "AOR", "ALSH", "ARSH", "AUSH",
- "OCTAL", "HEX", "INTEGER", "DECIMAL", "STRING", "REGEX", "TRUE", "FALSE",
+ null, "WS", "COMMENT", "LBRACK", "RBRACK", "LBRACE", "RBRACE", "LP", "RP",
+ "DOT", "NSDOT", "COMMA", "SEMICOLON", "IF", "IN", "ELSE", "WHILE", "DO",
+ "FOR", "CONTINUE", "BREAK", "RETURN", "NEW", "TRY", "CATCH", "THROW",
+ "THIS", "INSTANCEOF", "BOOLNOT", "BWNOT", "MUL", "DIV", "REM", "ADD",
+ "SUB", "LSH", "RSH", "USH", "LT", "LTE", "GT", "GTE", "EQ", "EQR", "NE",
+ "NER", "BWAND", "XOR", "BWOR", "BOOLAND", "BOOLOR", "COND", "COLON", "ELVIS",
+ "REF", "ARROW", "FIND", "MATCH", "INCR", "DECR", "ASSIGN", "AADD", "ASUB",
+ "AMUL", "ADIV", "AREM", "AAND", "AXOR", "AOR", "ALSH", "ARSH", "AUSH",
+ "OCTAL", "HEX", "INTEGER", "DECIMAL", "STRING", "REGEX", "TRUE", "FALSE",
"NULL", "TYPE", "ID", "DOTINTEGER", "DOTID"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
@@ -162,7 +177,7 @@ public final SourceContext source() throws RecognitionException {
setState(66);
function();
}
- }
+ }
}
setState(71);
_errHandler.sync(this);
@@ -178,7 +193,7 @@ public final SourceContext source() throws RecognitionException {
setState(72);
statement();
}
- }
+ }
}
setState(77);
_errHandler.sync(this);
@@ -426,7 +441,7 @@ public RstatementContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_rstatement; }
-
+
public RstatementContext() { }
public void copyFrom(RstatementContext ctx) {
super.copyFrom(ctx);
@@ -805,7 +820,7 @@ public final RstatementContext rstatement() throws RecognitionException {
match(TRY);
setState(164);
block();
- setState(166);
+ setState(166);
_errHandler.sync(this);
_alt = 1;
do {
@@ -821,7 +836,7 @@ public final RstatementContext rstatement() throws RecognitionException {
default:
throw new NoViableAltException(this);
}
- setState(168);
+ setState(168);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,12,_ctx);
} while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER );
@@ -845,7 +860,7 @@ public DstatementContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_dstatement; }
-
+
public DstatementContext() { }
public void copyFrom(DstatementContext ctx) {
super.copyFrom(ctx);
@@ -1148,7 +1163,7 @@ public final BlockContext block() throws RecognitionException {
setState(194);
statement();
}
- }
+ }
}
setState(199);
_errHandler.sync(this);
@@ -1407,7 +1422,7 @@ public final DecltypeContext decltype() throws RecognitionException {
setState(224);
match(RBRACE);
}
- }
+ }
}
setState(229);
_errHandler.sync(this);
@@ -1532,7 +1547,7 @@ public ExpressionContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_expression; }
-
+
public ExpressionContext() { }
public void copyFrom(ExpressionContext ctx) {
super.copyFrom(ctx);
@@ -1943,7 +1958,7 @@ private ExpressionContext expression(int _p) throws RecognitionException {
}
break;
}
- }
+ }
}
setState(297);
_errHandler.sync(this);
@@ -1967,7 +1982,7 @@ public UnaryContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_unary; }
-
+
public UnaryContext() { }
public void copyFrom(UnaryContext ctx) {
super.copyFrom(ctx);
@@ -2135,7 +2150,7 @@ public ChainContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_chain; }
-
+
public ChainContext() { }
public void copyFrom(ChainContext ctx) {
super.copyFrom(ctx);
@@ -2214,7 +2229,7 @@ public final ChainContext chain() throws RecognitionException {
setState(314);
postfix();
}
- }
+ }
}
setState(319);
_errHandler.sync(this);
@@ -2240,7 +2255,7 @@ public final ChainContext chain() throws RecognitionException {
setState(322);
postfix();
}
- }
+ }
}
setState(327);
_errHandler.sync(this);
@@ -2274,7 +2289,7 @@ public PrimaryContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_primary; }
-
+
public PrimaryContext() { }
public void copyFrom(PrimaryContext ctx) {
super.copyFrom(ctx);
@@ -2799,7 +2814,7 @@ public ArrayinitializerContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_arrayinitializer; }
-
+
public ArrayinitializerContext() { }
public void copyFrom(ArrayinitializerContext ctx) {
super.copyFrom(ctx);
@@ -2886,7 +2901,7 @@ public final ArrayinitializerContext arrayinitializer() throws RecognitionExcept
match(NEW);
setState(372);
match(TYPE);
- setState(377);
+ setState(377);
_errHandler.sync(this);
_alt = 1;
do {
@@ -2906,7 +2921,7 @@ public final ArrayinitializerContext arrayinitializer() throws RecognitionExcept
default:
throw new NoViableAltException(this);
}
- setState(379);
+ setState(379);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,31,_ctx);
} while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER );
@@ -2927,7 +2942,7 @@ public final ArrayinitializerContext arrayinitializer() throws RecognitionExcept
setState(382);
postfix();
}
- }
+ }
}
setState(387);
_errHandler.sync(this);
@@ -2989,7 +3004,7 @@ public final ArrayinitializerContext arrayinitializer() throws RecognitionExcept
setState(406);
postfix();
}
- }
+ }
}
setState(411);
_errHandler.sync(this);
@@ -3542,7 +3557,7 @@ public FuncrefContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_funcref; }
-
+
public FuncrefContext() { }
public void copyFrom(FuncrefContext ctx) {
super.copyFrom(ctx);
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java
index 3ac6cb7fd37c4..a481c99a99d12 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java
@@ -986,19 +986,20 @@ public AExpression visitBraceaccess(BraceaccessContext ctx, AExpression prefix)
@Override
public ANode visitNewstandardarray(NewstandardarrayContext ctx) {
- String type = ctx.TYPE().getText();
+ StringBuilder type = new StringBuilder(ctx.TYPE().getText());
List expressions = new ArrayList<>();
for (ExpressionContext expression : ctx.expression()) {
+ type.append("[]");
expressions.add((AExpression)visit(expression));
}
- return buildPostfixChain(new ENewArray(location(ctx), type, expressions, false), ctx.postdot(), ctx.postfix());
+ return buildPostfixChain(new ENewArray(location(ctx), type.toString(), expressions, false), ctx.postdot(), ctx.postfix());
}
@Override
public ANode visitNewinitializedarray(NewinitializedarrayContext ctx) {
- String type = ctx.TYPE().getText();
+ String type = ctx.TYPE().getText() + "[]";
List expressions = new ArrayList<>();
for (ExpressionContext expression : ctx.expression()) {
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java
index eaf8045bf1c65..5a897e04a8d98 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java
@@ -19,7 +19,6 @@
package org.elasticsearch.painless.node;
-import org.elasticsearch.painless.Definition;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
@@ -51,7 +50,7 @@ void extractVariables(Set variables) {
@Override
void analyze(Locals locals) {
try {
- actual = Definition.TypeToClass(locals.getDefinition().getType(type));
+ actual = locals.getDefinition().getJavaClassFromPainlessType(type);
} catch (IllegalArgumentException exception) {
throw createError(new IllegalArgumentException("Not a type [" + type + "]."));
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EFunctionRef.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EFunctionRef.java
index c82b1003a55f1..21bef9aa2ed5d 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EFunctionRef.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EFunctionRef.java
@@ -66,7 +66,7 @@ void analyze(Locals locals) {
try {
if ("this".equals(type)) {
// user's own function
- Method interfaceMethod = locals.getDefinition().ClassToType(expected).struct.functionalMethod;
+ Method interfaceMethod = locals.getDefinition().getPainlessStructFromJavaClass(expected).functionalMethod;
if (interfaceMethod == null) {
throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " +
"to [" + Definition.ClassToName(expected) + "], not a functional interface");
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java
index 54403b51f04bd..5296d79e214ed 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java
@@ -58,7 +58,7 @@ void analyze(Locals locals) {
// ensure the specified type is part of the definition
try {
- clazz = Definition.TypeToClass(locals.getDefinition().getType(this.type));
+ clazz = locals.getDefinition().getJavaClassFromPainlessType(this.type);
} catch (IllegalArgumentException exception) {
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ELambda.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ELambda.java
index a7213e75ca485..e40d21ab110ab 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ELambda.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ELambda.java
@@ -120,7 +120,7 @@ void analyze(Locals locals) {
}
} else {
// we know the method statically, infer return type and any unknown/def types
- interfaceMethod = locals.getDefinition().ClassToType(expected).struct.functionalMethod;
+ interfaceMethod = locals.getDefinition().getPainlessStructFromJavaClass(expected).functionalMethod;
if (interfaceMethod == null) {
throw createError(new IllegalArgumentException("Cannot pass lambda to [" + Definition.ClassToName(expected) +
"], not a functional interface"));
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EListInit.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EListInit.java
index d957be0aadb50..05b10796cb4f9 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EListInit.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EListInit.java
@@ -61,13 +61,13 @@ void analyze(Locals locals) {
actual = ArrayList.class;
- constructor = locals.getDefinition().ClassToType(actual).struct.constructors.get(new MethodKey("", 0));
+ constructor = locals.getDefinition().getPainlessStructFromJavaClass(actual).constructors.get(new MethodKey("", 0));
if (constructor == null) {
throw createError(new IllegalStateException("Illegal tree structure."));
}
- method = locals.getDefinition().ClassToType(actual).struct.methods.get(new MethodKey("add", 1));
+ method = locals.getDefinition().getPainlessStructFromJavaClass(actual).methods.get(new MethodKey("add", 1));
if (method == null) {
throw createError(new IllegalStateException("Illegal tree structure."));
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EMapInit.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EMapInit.java
index 2cd864da24b65..f5763042b8191 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EMapInit.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EMapInit.java
@@ -67,13 +67,13 @@ void analyze(Locals locals) {
actual = HashMap.class;
- constructor = locals.getDefinition().ClassToType(actual).struct.constructors.get(new MethodKey("", 0));
+ constructor = locals.getDefinition().getPainlessStructFromJavaClass(actual).constructors.get(new MethodKey("", 0));
if (constructor == null) {
throw createError(new IllegalStateException("Illegal tree structure."));
}
- method = locals.getDefinition().ClassToType(actual).struct.methods.get(new MethodKey("put", 2));
+ method = locals.getDefinition().getPainlessStructFromJavaClass(actual).methods.get(new MethodKey("put", 2));
if (method == null) {
throw createError(new IllegalStateException("Illegal tree structure."));
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewArray.java
index c1d58cb2f2ad9..1a0a718ae7fc8 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewArray.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewArray.java
@@ -19,7 +19,6 @@
package org.elasticsearch.painless.node;
-import org.elasticsearch.painless.Definition;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
@@ -38,8 +37,6 @@ public final class ENewArray extends AExpression {
private final List arguments;
private final boolean initialize;
- private Class> array;
-
public ENewArray(Location location, String type, List arguments, boolean initialize) {
super(location);
@@ -64,7 +61,7 @@ void analyze(Locals locals) {
Class> clazz;
try {
- clazz = Definition.TypeToClass(locals.getDefinition().getType(this.type));
+ clazz = locals.getDefinition().getJavaClassFromPainlessType(this.type);
} catch (IllegalArgumentException exception) {
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
}
@@ -72,15 +69,13 @@ void analyze(Locals locals) {
for (int argument = 0; argument < arguments.size(); ++argument) {
AExpression expression = arguments.get(argument);
- expression.expected = initialize ? clazz : int.class;
+ expression.expected = initialize ? clazz.getComponentType() : int.class;
expression.internal = true;
expression.analyze(locals);
arguments.set(argument, expression.cast(locals));
}
- actual = Definition.TypeToClass(locals.getDefinition().getType(
- locals.getDefinition().ClassToType(clazz).struct, initialize ? 1 : arguments.size()));
- array = Definition.defClassToObjectClass(actual);
+ actual = clazz;
}
@Override
@@ -89,7 +84,7 @@ void write(MethodWriter writer, Globals globals) {
if (initialize) {
writer.push(arguments.size());
- writer.newArray(MethodWriter.getType(array.getComponentType()));
+ writer.newArray(MethodWriter.getType(actual.getComponentType()));
for (int index = 0; index < arguments.size(); ++index) {
AExpression argument = arguments.get(index);
@@ -97,7 +92,7 @@ void write(MethodWriter writer, Globals globals) {
writer.dup();
writer.push(index);
argument.write(writer, globals);
- writer.arrayStore(MethodWriter.getType(array.getComponentType()));
+ writer.arrayStore(MethodWriter.getType(actual.getComponentType()));
}
} else {
for (AExpression argument : arguments) {
@@ -105,9 +100,9 @@ void write(MethodWriter writer, Globals globals) {
}
if (arguments.size() > 1) {
- writer.visitMultiANewArrayInsn(MethodWriter.getType(array).getDescriptor(), arguments.size());
+ writer.visitMultiANewArrayInsn(MethodWriter.getType(actual).getDescriptor(), arguments.size());
} else {
- writer.newArray(MethodWriter.getType(array.getComponentType()));
+ writer.newArray(MethodWriter.getType(actual.getComponentType()));
}
}
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewObj.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewObj.java
index 2a96d68bcb417..e3a926ef2244b 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewObj.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewObj.java
@@ -58,12 +58,12 @@ void extractVariables(Set variables) {
@Override
void analyze(Locals locals) {
try {
- actual = Definition.TypeToClass(locals.getDefinition().getType(this.type));
+ actual = locals.getDefinition().getJavaClassFromPainlessType(this.type);
} catch (IllegalArgumentException exception) {
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
}
- Struct struct = locals.getDefinition().ClassToType(actual).struct;
+ Struct struct = locals.getDefinition().getPainlessStructFromJavaClass(actual);
constructor = struct.constructors.get(new Definition.MethodKey("", arguments.size()));
if (constructor != null) {
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ERegex.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ERegex.java
index 5c3b4cadf6ee9..fa249b9df6237 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ERegex.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ERegex.java
@@ -72,7 +72,7 @@ void analyze(Locals locals) {
}
constant = new Constant(
- location, locals.getDefinition().PatternType.type, "regexAt$" + location.getOffset(), this::initializeConstant);
+ location, MethodWriter.getType(Pattern.class), "regexAt$" + location.getOffset(), this::initializeConstant);
actual = Pattern.class;
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EStatic.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EStatic.java
index f5c2c6e9da354..5ebf30f5781cf 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EStatic.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EStatic.java
@@ -19,7 +19,6 @@
package org.elasticsearch.painless.node;
-import org.elasticsearch.painless.Definition;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
@@ -49,7 +48,7 @@ void extractVariables(Set variables) {
@Override
void analyze(Locals locals) {
try {
- actual = Definition.TypeToClass(locals.getDefinition().getType(type));
+ actual = locals.getDefinition().getJavaClassFromPainlessType(type);
} catch (IllegalArgumentException exception) {
throw createError(new IllegalArgumentException("Not a type [" + type + "]."));
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java
index 6712eccd914c5..0e2ab70897fe5 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java
@@ -63,9 +63,9 @@ void analyze(Locals locals) {
} else if (prefix.actual == def.class) {
sub = new PSubDefArray(location, index);
} else if (Map.class.isAssignableFrom(prefix.actual)) {
- sub = new PSubMapShortcut(location, locals.getDefinition().ClassToType(prefix.actual).struct, index);
+ sub = new PSubMapShortcut(location, locals.getDefinition().getPainlessStructFromJavaClass(prefix.actual), index);
} else if (List.class.isAssignableFrom(prefix.actual)) {
- sub = new PSubListShortcut(location, locals.getDefinition().ClassToType(prefix.actual).struct, index);
+ sub = new PSubListShortcut(location, locals.getDefinition().getPainlessStructFromJavaClass(prefix.actual), index);
} else {
throw createError(
new IllegalArgumentException("Illegal array access on type [" + Definition.ClassToName(prefix.actual) + "]."));
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java
index 498fb83239395..6fff5a8e93f3e 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java
@@ -71,10 +71,10 @@ void analyze(Locals locals) {
throw createError(new IllegalArgumentException("Illegal call [" + name + "] on array type."));
}
- Struct struct = locals.getDefinition().ClassToType(prefix.actual).struct;
+ Struct struct = locals.getDefinition().getPainlessStructFromJavaClass(prefix.actual);
if (prefix.actual.isPrimitive()) {
- struct = locals.getDefinition().ClassToType(Definition.getBoxedType(prefix.actual)).struct;
+ struct = locals.getDefinition().getPainlessStructFromJavaClass(Definition.getBoxedType(prefix.actual));
}
MethodKey methodKey = new MethodKey(name, arguments.size());
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java
index 1f492758af618..de2c05dfa9b28 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java
@@ -67,7 +67,7 @@ void analyze(Locals locals) {
} else if (prefix.actual == def.class) {
sub = new PSubDefField(location, value);
} else {
- Struct struct = locals.getDefinition().ClassToType(prefix.actual).struct;
+ Struct struct = locals.getDefinition().getPainlessStructFromJavaClass(prefix.actual);
Field field = prefix instanceof EStatic ? struct.staticMembers.get(value) : struct.members.get(value);
if (field != null) {
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefCall.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefCall.java
index d98c2f2276eaa..6428e47d1bacc 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefCall.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefCall.java
@@ -20,7 +20,6 @@
package org.elasticsearch.painless.node;
import org.elasticsearch.painless.DefBootstrap;
-
import org.elasticsearch.painless.Definition.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SCatch.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SCatch.java
index 535ad5235b07c..98e45ca29f416 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SCatch.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SCatch.java
@@ -19,7 +19,6 @@
package org.elasticsearch.painless.node;
-import org.elasticsearch.painless.Definition;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Locals.Variable;
@@ -68,7 +67,7 @@ void analyze(Locals locals) {
Class> clazz;
try {
- clazz = Definition.TypeToClass(locals.getDefinition().getType(this.type));
+ clazz = locals.getDefinition().getJavaClassFromPainlessType(this.type);
} catch (IllegalArgumentException exception) {
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java
index f00db583ceae4..9f3f86abf438b 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java
@@ -19,7 +19,6 @@
package org.elasticsearch.painless.node;
-import org.elasticsearch.painless.Definition;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Locals.Variable;
@@ -63,7 +62,7 @@ void analyze(Locals locals) {
Class> clazz;
try {
- clazz = Definition.TypeToClass(locals.getDefinition().getType(this.type));
+ clazz = locals.getDefinition().getJavaClassFromPainlessType(this.type);
} catch (IllegalArgumentException exception) {
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java
index 04de0c0696e96..a3c8319825a26 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java
@@ -71,7 +71,7 @@ void analyze(Locals locals) {
Class> clazz;
try {
- clazz = Definition.TypeToClass(locals.getDefinition().getType(this.type));
+ clazz = locals.getDefinition().getJavaClassFromPainlessType(this.type);
} catch (IllegalArgumentException exception) {
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFunction.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFunction.java
index 5fa62f27e94dc..1b1e6bd2ef84b 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFunction.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFunction.java
@@ -119,7 +119,7 @@ void extractVariables(Set variables) {
void generateSignature(Definition definition) {
try {
- rtnType = Definition.TypeToClass(definition.getType(rtnTypeStr));
+ rtnType = definition.getJavaClassFromPainlessType(rtnTypeStr);
} catch (IllegalArgumentException exception) {
throw createError(new IllegalArgumentException("Illegal return type [" + rtnTypeStr + "] for function [" + name + "]."));
}
@@ -133,7 +133,7 @@ void generateSignature(Definition definition) {
for (int param = 0; param < this.paramTypeStrs.size(); ++param) {
try {
- Class> paramType = Definition.TypeToClass(definition.getType(this.paramTypeStrs.get(param)));
+ Class> paramType = definition.getJavaClassFromPainlessType(this.paramTypeStrs.get(param));
paramClasses[param] = Definition.defClassToObjectClass(paramType);
paramTypes.add(paramType);
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachIterable.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachIterable.java
index ca30d641e7468..11e0f15d7e4f8 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachIterable.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachIterable.java
@@ -25,7 +25,6 @@
import org.elasticsearch.painless.Definition.Cast;
import org.elasticsearch.painless.Definition.Method;
import org.elasticsearch.painless.Definition.MethodKey;
-import org.elasticsearch.painless.Definition.Type;
import org.elasticsearch.painless.Definition.def;
import org.elasticsearch.painless.Globals;
import org.elasticsearch.painless.Locals;
@@ -78,12 +77,11 @@ void analyze(Locals locals) {
if (expression.actual == def.class) {
method = null;
} else {
- Type actualType = locals.getDefinition().ClassToType(expression.actual);
- method = actualType.struct.methods.get(new MethodKey("iterator", 0));
+ method = locals.getDefinition().getPainlessStructFromJavaClass(expression.actual).methods.get(new MethodKey("iterator", 0));
if (method == null) {
throw createError(new IllegalArgumentException(
- "Unable to create iterator for the type [" + actualType.name + "]."));
+ "Unable to create iterator for the type [" + Definition.ClassToName(expression.actual) + "]."));
}
}
diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefBootstrapTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefBootstrapTests.java
index 8fd96d67d5b53..52528c358fc82 100644
--- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefBootstrapTests.java
+++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefBootstrapTests.java
@@ -1,5 +1,3 @@
-package org.elasticsearch.painless;
-
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
@@ -19,6 +17,8 @@
* under the License.
*/
+package org.elasticsearch.painless;
+
import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/PainlessDocGenerator.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/PainlessDocGenerator.java
index ed38f4c511f59..309b6be97f20b 100644
--- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/PainlessDocGenerator.java
+++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/PainlessDocGenerator.java
@@ -26,9 +26,6 @@
import org.elasticsearch.painless.Definition.Field;
import org.elasticsearch.painless.Definition.Method;
import org.elasticsearch.painless.Definition.Struct;
-import org.elasticsearch.painless.Definition.Type;
-import org.elasticsearch.painless.spi.Whitelist;
-
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Modifier;
@@ -44,12 +41,14 @@
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;
+import static org.elasticsearch.painless.spi.Whitelist.BASE_WHITELISTS;
/**
* Generates an API reference from the method and type whitelists in {@link Definition}.
*/
public class PainlessDocGenerator {
- private static final Definition definition = new Definition(Whitelist.BASE_WHITELISTS);
+
+ private static final Definition definition = new Definition(BASE_WHITELISTS);
private static final Logger logger = ESLoggerFactory.getLogger(PainlessDocGenerator.class);
private static final Comparator FIELD_NAME = comparing(f -> f.name);
private static final Comparator METHOD_NAME = comparing(m -> m.name);
@@ -68,41 +67,41 @@ public static void main(String[] args) throws IOException {
Files.newOutputStream(indexPath, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE),
false, StandardCharsets.UTF_8.name())) {
emitGeneratedWarning(indexStream);
- List types = definition.allSimpleTypes().stream().sorted(comparing(t -> t.name)).collect(toList());
- for (Type type : types) {
- if (type.clazz.isPrimitive()) {
+ List structs = definition.getStructs().stream().sorted(comparing(t -> t.name)).collect(toList());
+ for (Struct struct : structs) {
+ if (struct.clazz.isPrimitive()) {
// Primitives don't have methods to reference
continue;
}
- if ("def".equals(type.name)) {
+ if ("def".equals(struct.name)) {
// def is special but doesn't have any methods all of its own.
continue;
}
indexStream.print("include::");
- indexStream.print(type.struct.name);
+ indexStream.print(struct.name);
indexStream.println(".asciidoc[]");
- Path typePath = apiRootPath.resolve(type.struct.name + ".asciidoc");
- logger.info("Writing [{}.asciidoc]", type.name);
+ Path typePath = apiRootPath.resolve(struct.name + ".asciidoc");
+ logger.info("Writing [{}.asciidoc]", struct.name);
try (PrintStream typeStream = new PrintStream(
Files.newOutputStream(typePath, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE),
false, StandardCharsets.UTF_8.name())) {
emitGeneratedWarning(typeStream);
typeStream.print("[[");
- emitAnchor(typeStream, type.struct);
+ emitAnchor(typeStream, struct);
typeStream.print("]]++");
- typeStream.print(type.name);
+ typeStream.print(struct.name);
typeStream.println("++::");
Consumer documentField = field -> PainlessDocGenerator.documentField(typeStream, field);
Consumer documentMethod = method -> PainlessDocGenerator.documentMethod(typeStream, method);
- type.struct.staticMembers.values().stream().sorted(FIELD_NAME).forEach(documentField);
- type.struct.members.values().stream().sorted(FIELD_NAME).forEach(documentField);
- type.struct.staticMethods.values().stream().sorted(METHOD_NAME.thenComparing(NUMBER_OF_ARGS)).forEach(documentMethod);
- type.struct.constructors.values().stream().sorted(NUMBER_OF_ARGS).forEach(documentMethod);
+ struct.staticMembers.values().stream().sorted(FIELD_NAME).forEach(documentField);
+ struct.members.values().stream().sorted(FIELD_NAME).forEach(documentField);
+ struct.staticMethods.values().stream().sorted(METHOD_NAME.thenComparing(NUMBER_OF_ARGS)).forEach(documentMethod);
+ struct.constructors.values().stream().sorted(NUMBER_OF_ARGS).forEach(documentMethod);
Map inherited = new TreeMap<>();
- type.struct.methods.values().stream().sorted(METHOD_NAME.thenComparing(NUMBER_OF_ARGS)).forEach(method -> {
- if (method.owner == type.struct) {
+ struct.methods.values().stream().sorted(METHOD_NAME.thenComparing(NUMBER_OF_ARGS)).forEach(method -> {
+ if (method.owner == struct) {
documentMethod(typeStream, method);
} else {
inherited.put(method.owner.name, method.owner);
@@ -139,7 +138,7 @@ private static void documentField(PrintStream stream, Field field) {
stream.print("static ");
}
- emitType(stream, definition.ClassToType(field.clazz));
+ emitType(stream, field.clazz);
stream.print(' ');
String javadocRoot = javadocRoot(field);
@@ -170,7 +169,7 @@ private static void documentMethod(PrintStream stream, Method method) {
}
if (false == method.name.equals("")) {
- emitType(stream, definition.ClassToType(method.rtn));
+ emitType(stream, method.rtn);
stream.print(' ');
}
@@ -188,7 +187,7 @@ private static void documentMethod(PrintStream stream, Method method) {
} else {
stream.print(", ");
}
- emitType(stream, definition.ClassToType(arg));
+ emitType(stream, arg);
}
stream.print(")++");
@@ -234,19 +233,19 @@ private static String methodName(Method method) {
}
/**
- * Emit a {@link Type}. If the type is primitive or an array of primitives this just emits the name of the type. Otherwise this emits an
- * internal link with the text.
+ * Emit a {@link Class}. If the type is primitive or an array of primitives this just emits the name of the type. Otherwise this emits
+ an internal link with the text.
*/
- private static void emitType(PrintStream stream, Type type) {
- emitStruct(stream, type.struct);
- for (int i = 0; i < type.dimensions; i++) {
+ private static void emitType(PrintStream stream, Class> clazz) {
+ emitStruct(stream, definition.getPainlessStructFromJavaClass(clazz));
+ while ((clazz = clazz.getComponentType()) != null) {
stream.print("[]");
}
}
/**
- * Emit a {@link Struct}. If the {@linkplain Struct} is primitive or def this just emits the name of the struct. Otherwise this emits an
- * internal link with the name.
+ * Emit a {@link Struct}. If the {@linkplain Struct} is primitive or def this just emits the name of the struct. Otherwise this emits
+ * an internal link with the name.
*/
private static void emitStruct(PrintStream stream, Struct struct) {
if (false == struct.clazz.isPrimitive() && false == struct.name.equals("def")) {
@@ -279,14 +278,13 @@ private static void emitJavadocLink(PrintStream stream, String root, Method meth
stream.print(method.owner.clazz.getName());
}
for (Class> clazz: method.arguments) {
- Type arg = definition.ClassToType(clazz);
if (first) {
first = false;
} else {
stream.print("%2D");
}
- stream.print(arg.struct.clazz.getName());
- if (arg.dimensions > 0) {
+ stream.print(clazz.getName());
+ if (clazz.isArray()) {
stream.print(":A");
}
}
diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/node/NodeToStringTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/node/NodeToStringTests.java
index 6dbe480d4b5a3..fd8190aa2c2eb 100644
--- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/node/NodeToStringTests.java
+++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/node/NodeToStringTests.java
@@ -284,12 +284,12 @@ public void testEMapInit() {
}
public void testENewArray() {
- assertToString("(SSource (SReturn (ENewArray int dims (Args (ENumeric 10)))))", "return new int[10]");
- assertToString("(SSource (SReturn (ENewArray int dims (Args (ENumeric 10) (ENumeric 4) (ENumeric 5)))))",
+ assertToString("(SSource (SReturn (ENewArray int[] dims (Args (ENumeric 10)))))", "return new int[10]");
+ assertToString("(SSource (SReturn (ENewArray int[][][] dims (Args (ENumeric 10) (ENumeric 4) (ENumeric 5)))))",
"return new int[10][4][5]");
- assertToString("(SSource (SReturn (ENewArray int init (Args (ENumeric 1) (ENumeric 2) (ENumeric 3)))))",
+ assertToString("(SSource (SReturn (ENewArray int[] init (Args (ENumeric 1) (ENumeric 2) (ENumeric 3)))))",
"return new int[] {1, 2, 3}");
- assertToString("(SSource (SReturn (ENewArray def init (Args (ENumeric 1) (ENumeric 2) (EString 'bird')))))",
+ assertToString("(SSource (SReturn (ENewArray def[] init (Args (ENumeric 1) (ENumeric 2) (EString 'bird')))))",
"return new def[] {1, 2, 'bird'}");
}
@@ -372,7 +372,7 @@ public void testPField() {
assertToString("(SSource (SReturn (PField nullSafe (EVariable params) a)))", "return params?.a");
assertToString(
"(SSource\n"
- + " (SDeclBlock (SDeclaration int[] a (ENewArray int dims (Args (ENumeric 10)))))\n"
+ + " (SDeclBlock (SDeclaration int[] a (ENewArray int[] dims (Args (ENumeric 10)))))\n"
+ " (SReturn (PField (EVariable a) length)))",
"int[] a = new int[10];\n"
+ "return a.length");
@@ -403,7 +403,7 @@ public void testPSubBrace() {
public void testPSubCallInvoke() {
Location l = new Location(getTestName(), 0);
- Struct c = definition.ClassToType(Integer.class).struct;
+ Struct c = definition.getPainlessStructFromJavaClass(Integer.class);
Method m = c.methods.get(new MethodKey("toString", 0));
PSubCallInvoke node = new PSubCallInvoke(l, m, null, emptyList());
node.prefix = new EVariable(l, "a");
@@ -458,7 +458,7 @@ public void testPSubDefField() {
public void testPSubField() {
Location l = new Location(getTestName(), 0);
- Struct s = definition.getType(Boolean.class.getSimpleName()).struct;
+ Struct s = definition.getPainlessStructFromJavaClass(Boolean.class);
Field f = s.staticMembers.get("TRUE");
PSubField node = new PSubField(l, f);
node.prefix = new EStatic(l, "Boolean");
@@ -468,7 +468,7 @@ public void testPSubField() {
public void testPSubListShortcut() {
Location l = new Location(getTestName(), 0);
- Struct s = definition.getType(List.class.getSimpleName()).struct;
+ Struct s = definition.getPainlessStructFromJavaClass(List.class);
PSubListShortcut node = new PSubListShortcut(l, s, new EConstant(l, 1));
node.prefix = new EVariable(l, "a");
assertEquals("(PSubListShortcut (EVariable a) (EConstant Integer 1))", node.toString());
@@ -476,7 +476,7 @@ public void testPSubListShortcut() {
new PSubNullSafeCallInvoke(l, node).toString());
l = new Location(getTestName(), 0);
- s = definition.getType(List.class.getSimpleName()).struct;
+ s = definition.getPainlessStructFromJavaClass(List.class);
node = new PSubListShortcut(l, s, new EBinary(l, Operation.ADD, new EConstant(l, 1), new EConstant(l, 4)));
node.prefix = new EVariable(l, "a");
assertEquals("(PSubListShortcut (EVariable a) (EBinary (EConstant Integer 1) + (EConstant Integer 4)))", node.toString());
@@ -484,7 +484,7 @@ public void testPSubListShortcut() {
public void testPSubMapShortcut() {
Location l = new Location(getTestName(), 0);
- Struct s = definition.getType(Map.class.getSimpleName()).struct;
+ Struct s = definition.getPainlessStructFromJavaClass(Map.class);
PSubMapShortcut node = new PSubMapShortcut(l, s, new EConstant(l, "cat"));
node.prefix = new EVariable(l, "a");
assertEquals("(PSubMapShortcut (EVariable a) (EConstant String 'cat'))", node.toString());
@@ -492,7 +492,7 @@ public void testPSubMapShortcut() {
new PSubNullSafeCallInvoke(l, node).toString());
l = new Location(getTestName(), 1);
- s = definition.getType(Map.class.getSimpleName()).struct;
+ s = definition.getPainlessStructFromJavaClass(Map.class);
node = new PSubMapShortcut(l, s, new EBinary(l, Operation.ADD, new EConstant(l, 1), new EConstant(l, 4)));
node.prefix = new EVariable(l, "a");
assertEquals("(PSubMapShortcut (EVariable a) (EBinary (EConstant Integer 1) + (EConstant Integer 4)))", node.toString());
@@ -500,7 +500,7 @@ public void testPSubMapShortcut() {
public void testPSubShortcut() {
Location l = new Location(getTestName(), 0);
- Struct s = definition.getType(FeatureTest.class.getName()).struct;
+ Struct s = definition.getPainlessStructFromJavaClass(FeatureTest.class);
Method getter = s.methods.get(new MethodKey("getX", 0));
Method setter = s.methods.get(new MethodKey("setX", 1));
PSubShortcut node = new PSubShortcut(l, "x", FeatureTest.class.getName(), getter, setter);