From 98dae05564888737d5a23c7f0e3654527d50f176 Mon Sep 17 00:00:00 2001 From: Luca Molteni Date: Tue, 1 Sep 2020 14:55:31 +0200 Subject: [PATCH 1/2] Support correct type analysis with generic return type of Optional --- .../java/org/mvel2/compiler/PropertyVerifier.java | 10 +++++++++- .../org/mvel2/tests/core/TypesAndInferenceTests.java | 11 +++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/mvel2/compiler/PropertyVerifier.java b/src/main/java/org/mvel2/compiler/PropertyVerifier.java index 5230deba5..ef8590c10 100644 --- a/src/main/java/org/mvel2/compiler/PropertyVerifier.java +++ b/src/main/java/org/mvel2/compiler/PropertyVerifier.java @@ -19,6 +19,7 @@ package org.mvel2.compiler; import java.lang.reflect.Field; +import java.lang.reflect.GenericDeclaration; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -669,7 +670,14 @@ else if (typeArgs.containsKey(returnTypeArg)) { } private static Class type2Class(Type type) { - return type instanceof Class ? (Class) type : (Class) ((ParameterizedType) type).getRawType(); + if (type instanceof Class) { + return (Class) type; + } else if(type instanceof TypeVariable) { // such as T in Optional + GenericDeclaration genericDeclaration = ((TypeVariable) type).getGenericDeclaration(); + return ((Method)genericDeclaration).getReturnType(); + } else { + return (Class) ((ParameterizedType) type).getRawType(); + } } private Class getWithProperty(Class ctx) { diff --git a/src/test/java/org/mvel2/tests/core/TypesAndInferenceTests.java b/src/test/java/org/mvel2/tests/core/TypesAndInferenceTests.java index 0458bbb94..8847491b5 100644 --- a/src/test/java/org/mvel2/tests/core/TypesAndInferenceTests.java +++ b/src/test/java/org/mvel2/tests/core/TypesAndInferenceTests.java @@ -33,6 +33,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.Set; import static org.mvel2.MVEL.*; @@ -1595,4 +1596,14 @@ public void testGenerics1() { assertTrue(result); } + public void testOptionalOfGenerics() { + String str = "Optional.of(\"mystring\").orElse(\"anotherstring\")"; + + ParserConfiguration pconf = new ParserConfiguration(); + ParserContext pctx = new ParserContext(pconf); + pctx.setStrongTyping(true); + pctx.addImport(Optional.class); + Class resultType = analyze(str, pctx); + assertEquals(java.util.Optional.class, resultType); + } } From b55a0e13f84008192f7c9603f1b9c91c1430fee4 Mon Sep 17 00:00:00 2001 From: Luca Molteni Date: Wed, 2 Sep 2020 09:44:59 +0200 Subject: [PATCH 2/2] Better default --- .../org/mvel2/compiler/PropertyVerifier.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/mvel2/compiler/PropertyVerifier.java b/src/main/java/org/mvel2/compiler/PropertyVerifier.java index ef8590c10..1d97f546a 100644 --- a/src/main/java/org/mvel2/compiler/PropertyVerifier.java +++ b/src/main/java/org/mvel2/compiler/PropertyVerifier.java @@ -669,15 +669,21 @@ else if (typeArgs.containsKey(returnTypeArg)) { return getReturnType(ctx, m); } - private static Class type2Class(Type type) { - if (type instanceof Class) { + private static Class type2Class(Type type) { + if (type == null) { + return null; + } + if (type instanceof Class) { return (Class) type; - } else if(type instanceof TypeVariable) { // such as T in Optional + } + if (type instanceof ParameterizedType) { + return type2Class(((ParameterizedType) type).getRawType()); + } + if (type instanceof TypeVariable) { // this is T in Optional GenericDeclaration genericDeclaration = ((TypeVariable) type).getGenericDeclaration(); - return ((Method)genericDeclaration).getReturnType(); - } else { - return (Class) ((ParameterizedType) type).getRawType(); + return genericDeclaration instanceof Method ? ((Method) genericDeclaration).getReturnType() : Object.class; } + throw new UnsupportedOperationException("Unknown type " + type); } private Class getWithProperty(Class ctx) {