From 3aeb66885bacbc175fc51c93e303173d2a654a74 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Tue, 10 May 2016 05:44:16 -0400 Subject: [PATCH] painless: use better typing for dynamic method calls --- .../org/elasticsearch/painless/WriterExternal.java | 11 +++++++---- .../painless/WhenThingsGoWrongTests.java | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterExternal.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterExternal.java index ab05e1b6e56..1ead39c467b 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterExternal.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterExternal.java @@ -20,6 +20,7 @@ package org.elasticsearch.painless; import org.antlr.v4.runtime.ParserRuleContext; +import org.elasticsearch.painless.Definition.Cast; import org.elasticsearch.painless.Definition.Constructor; import org.elasticsearch.painless.Definition.Field; import org.elasticsearch.painless.Definition.Method; @@ -714,14 +715,16 @@ class WriterExternal { // first parameter is the receiver, we never know its type: always Object signature.append(WriterConstants.OBJECT_TYPE.getDescriptor()); - // TODO: remove our explicit conversions and feed more type information for args/return value, - // it can avoid some unnecessary boxing etc. for (int i = 0; i < arguments.size(); i++) { - signature.append(WriterConstants.OBJECT_TYPE.getDescriptor()); + ExpressionMetadata arg = metadata.getExpressionMetadata(arguments.get(i)); + // disable any implicit casts/conversion for arguments, let invokeDynamic take care + arg.to = arg.from; + arg.cast = new Cast(arg.from, arg.from); + signature.append(arg.from.type.getDescriptor()); writer.visit(arguments.get(i)); } signature.append(')'); - // return value + // return value: currently always Object. making this better may be tricky... signature.append(WriterConstants.OBJECT_TYPE.getDescriptor()); execute.visitInvokeDynamicInsn((String)sourceenmd.target, signature.toString(), WriterConstants.DEF_BOOTSTRAP_HANDLE, new Object[] { DynamicCallSite.METHOD_CALL }); diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java index 3f79ae1974b..975e2301877 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java @@ -19,6 +19,7 @@ package org.elasticsearch.painless; +import java.lang.invoke.WrongMethodTypeException; import java.util.Arrays; import java.util.Collections; @@ -140,7 +141,7 @@ public class WhenThingsGoWrongTests extends ScriptTestCase { } public void testDynamicWrongArgs() { - expectThrows(ClassCastException.class, () -> { + expectThrows(WrongMethodTypeException.class, () -> { exec("def x = new ArrayList(); return x.get('bogus');"); }); }