1 | package com.github.dakusui.osynth.core.utils; | |
2 | ||
3 | import com.github.dakusui.osynth.core.InvocationController; | |
4 | import com.github.dakusui.osynth.core.MethodHandler; | |
5 | import com.github.dakusui.osynth.core.MethodSignature; | |
6 | import com.github.dakusui.osynth.core.SynthesizedObject; | |
7 | import com.github.dakusui.osynth.exceptions.OsynthException; | |
8 | ||
9 | import java.lang.invoke.MethodHandle; | |
10 | import java.lang.invoke.MethodHandles; | |
11 | import java.lang.reflect.Constructor; | |
12 | import java.lang.reflect.Method; | |
13 | import java.util.Arrays; | |
14 | import java.util.List; | |
15 | import java.util.Objects; | |
16 | import java.util.Optional; | |
17 | import java.util.function.Function; | |
18 | import java.util.stream.Stream; | |
19 | ||
20 | import static com.github.dakusui.osynth.core.utils.MessageUtils.messageForMissingMethodHandler; | |
21 | import static com.github.dakusui.pcond.forms.Predicates.isNotNull; | |
22 | import static com.github.dakusui.pcond.forms.Predicates.transform; | |
23 | import static com.github.dakusui.valid8j.Assertions.that; | |
24 | import static java.util.stream.Collectors.joining; | |
25 | ||
26 | public enum MethodUtils { | |
27 | ; | |
28 | ||
29 | public static MethodHandler createMethodHandlerFromFallbackObject(final Object fallbackObject, MethodSignature methodSignature) { | |
30 | assert that(fallbackObject, isNotNull()); | |
31 |
1
1. createMethodHandlerFromFallbackObject : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::createMethodHandlerFromFallbackObject → KILLED |
return createMethodHandlerDelegatingToObject(fallbackObject, methodSignature); |
32 | } | |
33 | ||
34 | public static MethodHandler createMethodHandlerDelegatingToObject(Object object, MethodSignature methodSignature) { | |
35 | assert object != null; | |
36 |
2
1. createMethodHandlerDelegatingToObject : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::createMethodHandlerDelegatingToObject → KILLED 2. lambda$createMethodHandlerDelegatingToObject$1 : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::lambda$createMethodHandlerDelegatingToObject$1 → KILLED |
return (synthesizedObject, args) -> execute(() -> { |
37 | Method method = getMethodFromClass(synthesizedObject, object.getClass(), methodSignature.name(), methodSignature.parameterTypes()); | |
38 |
1
1. lambda$null$0 : removed call to java/lang/reflect/Method::setAccessible → KILLED |
method.setAccessible(true); |
39 |
1
1. lambda$null$0 : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::lambda$null$0 → KILLED |
return method.invoke(object, args); |
40 | }); | |
41 | } | |
42 | ||
43 | public static Optional<MethodHandler> createMethodHandlerFromInterfaceClass(Class<?> fromClass, MethodSignature methodSignature) { | |
44 |
1
1. createMethodHandlerFromInterfaceClass : replaced return value with Optional.empty for com/github/dakusui/osynth/core/utils/MethodUtils::createMethodHandlerFromInterfaceClass → KILLED |
return findMethodHandleFor(methodSignature, fromClass).map(MethodUtils::toMethodHandler); |
45 | } | |
46 | ||
47 | static MethodHandler toMethodHandler(MethodHandle methodHandle) { | |
48 |
2
1. lambda$toMethodHandler$3 : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::lambda$toMethodHandler$3 → KILLED 2. toMethodHandler : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::toMethodHandler → KILLED |
return (SynthesizedObject synthesizedObject, Object[] arguments) -> execute( |
49 |
1
1. lambda$null$2 : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::lambda$null$2 → KILLED |
() -> methodHandle.bindTo(synthesizedObject).invokeWithArguments(arguments)); |
50 | } | |
51 | ||
52 | static Optional<MethodHandle> findMethodHandleFor(MethodSignature methodSignature, Class<?> fromClass) { | |
53 |
2
1. findMethodHandleFor : replaced return value with Optional.empty for com/github/dakusui/osynth/core/utils/MethodUtils::findMethodHandleFor → KILLED 2. lambda$findMethodHandleFor$4 : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::lambda$findMethodHandleFor$4 → KILLED |
return findMethodMatchingWith(methodSignature, fromClass).filter(Method::isDefault).map(m -> methodHandleFor(m, fromClass)); |
54 | } | |
55 | ||
56 | private static MethodHandle methodHandleFor(Method m, Class<?> fromClass) { | |
57 | assert that(fromClass, transform(AssertionUtils.classGetMethod(m.getName(), m.getParameterTypes())).check(isNotNull())); | |
58 |
2
1. lambda$methodHandleFor$5 : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::lambda$methodHandleFor$5 → KILLED 2. methodHandleFor : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::methodHandleFor → KILLED |
return execute(() -> createMethodHandlesLookupFor(fromClass).in(fromClass).unreflectSpecial(m, fromClass)); |
59 | } | |
60 | ||
61 | public static synchronized MethodHandles.Lookup createMethodHandlesLookupFor(Class<?> anInterfaceClass) { | |
62 |
1
1. createMethodHandlesLookupFor : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::createMethodHandlesLookupFor → KILLED |
return execute(() -> { |
63 | Constructor<MethodHandles.Lookup> constructor; | |
64 | constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class); | |
65 |
1
1. lambda$createMethodHandlesLookupFor$6 : removed call to java/lang/reflect/Constructor::setAccessible → KILLED |
constructor.setAccessible(true); |
66 |
1
1. lambda$createMethodHandlesLookupFor$6 : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::lambda$createMethodHandlesLookupFor$6 → KILLED |
return constructor.newInstance(anInterfaceClass); |
67 | }); | |
68 | } | |
69 | ||
70 | /** | |
71 | * A method to uniform a way to handle exceptions. | |
72 | * | |
73 | * @param block A block to execute hand to handle possible exceptions. | |
74 | * @param <T> A type of the returned value. | |
75 | * @return A returned value from the block. | |
76 | */ | |
77 | public static <T> T execute(FailableSupplier<T> block) { | |
78 |
1
1. execute : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::execute → KILLED |
return execute(block, Throwable::getMessage); |
79 | } | |
80 | ||
81 | public static <T> T execute(FailableSupplier<T> block, Function<Throwable, String> messageComposerOnFailure) { | |
82 | try { | |
83 |
1
1. execute : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::execute → KILLED |
return block.get(); |
84 | } catch (Error e) { | |
85 | throw e; | |
86 | } catch (Throwable e) { | |
87 | throw OsynthException.from(messageComposerOnFailure.apply(e), e); | |
88 | } | |
89 | } | |
90 | ||
91 | public static Object[] toEmptyArrayIfNull(Object[] args) { | |
92 |
1
1. toEmptyArrayIfNull : negated conditional → KILLED |
if (args == null) |
93 |
1
1. toEmptyArrayIfNull : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::toEmptyArrayIfNull → KILLED |
return InvocationController.EMPTY_ARGS; |
94 |
1
1. toEmptyArrayIfNull : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::toEmptyArrayIfNull → KILLED |
return args; |
95 | } | |
96 | ||
97 | public static Optional<MethodHandler> createMethodHandlerFromInterfaces(List<Class<?>> interfaces, MethodSignature methodSignature) { | |
98 |
1
1. createMethodHandlerFromInterfaces : replaced return value with Optional.empty for com/github/dakusui/osynth/core/utils/MethodUtils::createMethodHandlerFromInterfaces → KILLED |
return interfaces.stream() |
99 |
1
1. lambda$createMethodHandlerFromInterfaces$7 : replaced return value with Optional.empty for com/github/dakusui/osynth/core/utils/MethodUtils::lambda$createMethodHandlerFromInterfaces$7 → KILLED |
.map((Class<?> eachInterfaceClass) -> createMethodHandlerFromInterfaceClass(eachInterfaceClass, methodSignature)) |
100 | .filter(Optional::isPresent) | |
101 | .map(Optional::get) | |
102 | .findFirst(); | |
103 | } | |
104 | ||
105 | public static boolean isToStringOverridden(Class<?> aClass) { | |
106 |
2
1. isToStringOverridden : negated conditional → KILLED 2. isToStringOverridden : replaced boolean return with true for com/github/dakusui/osynth/core/utils/MethodUtils::isToStringOverridden → KILLED |
return !getMethodFromClass(aClass, "toString").getDeclaringClass().equals(Object.class); |
107 | } | |
108 | ||
109 | public static Method getMethodFromClass(Class<?> aClass, String methodName, Class<?>... parameterTypes) { | |
110 |
1
1. getMethodFromClass : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::getMethodFromClass → KILLED |
return getMethodFromClass(aClass, aClass, methodName, parameterTypes); |
111 | } | |
112 | ||
113 | private static Method getMethodFromClass(Object objectForErrorMessageFormatting, Class<?> aClass, String methodName, Class<?>... parameterTypes) { | |
114 | try { | |
115 |
1
1. getMethodFromClass : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::getMethodFromClass → KILLED |
return aClass.getMethod(methodName, parameterTypes); |
116 | } catch (NoSuchMethodException e) { | |
117 | throw new UnsupportedOperationException(messageForMissingMethodHandler(methodName, parameterTypes, objectForErrorMessageFormatting, e), e); | |
118 | } | |
119 | } | |
120 | ||
121 | public static String simpleClassNameOf(Class<?> aClass) { | |
122 |
3
1. simpleClassNameOf : changed conditional boundary → KILLED 2. simpleClassNameOf : negated conditional → KILLED 3. simpleClassNameOf : negated conditional → KILLED |
if (aClass.getSimpleName().length() > 0 && !aClass.isSynthetic()) |
123 |
1
1. simpleClassNameOf : replaced return value with "" for com/github/dakusui/osynth/core/utils/MethodUtils::simpleClassNameOf → KILLED |
return aClass.getSimpleName(); |
124 | final String label; | |
125 | final Optional<String> m; | |
126 |
1
1. simpleClassNameOf : negated conditional → KILLED |
if (aClass.isSynthetic()) { |
127 | label = "lambda"; | |
128 | m = Optional.of(enclosingClassNameOfLambda(aClass.getCanonicalName())); | |
129 | } else { | |
130 | label = "anonymous"; | |
131 | m = Optional.empty(); | |
132 | } | |
133 |
1
1. simpleClassNameOf : replaced return value with "" for com/github/dakusui/osynth/core/utils/MethodUtils::simpleClassNameOf → KILLED |
return streamSupertypes(aClass) |
134 |
2
1. lambda$simpleClassNameOf$8 : negated conditional → KILLED 2. lambda$simpleClassNameOf$8 : replaced boolean return with true for com/github/dakusui/osynth/core/utils/MethodUtils::lambda$simpleClassNameOf$8 → KILLED |
.filter(each -> !Objects.equals(Object.class, each)) |
135 | .map(MethodUtils::simpleClassNameOf) | |
136 | .collect(joining(",", label + ":(", ")")) + | |
137 |
1
1. lambda$simpleClassNameOf$9 : replaced return value with "" for com/github/dakusui/osynth/core/utils/MethodUtils::lambda$simpleClassNameOf$9 → KILLED |
m.map(v -> ":declared in " + v).orElse(""); |
138 | } | |
139 | ||
140 | public static String prettierToString(Object object) { | |
141 |
1
1. prettierToString : negated conditional → KILLED |
if (object == null) |
142 |
1
1. prettierToString : replaced return value with "" for com/github/dakusui/osynth/core/utils/MethodUtils::prettierToString → KILLED |
return "null"; |
143 | Class<?> aClass = object.getClass(); | |
144 |
2
1. prettierToString : negated conditional → KILLED 2. prettierToString : replaced return value with "" for com/github/dakusui/osynth/core/utils/MethodUtils::prettierToString → KILLED |
return isToStringOverridden(aClass) ? |
145 | object.toString() : | |
146 | simpleClassNameOf(aClass) + "@" + System.identityHashCode(object); | |
147 | } | |
148 | ||
149 | private static String enclosingClassNameOfLambda(String canonicalNameOfLambda) { | |
150 | String ret = canonicalNameOfLambda.substring(0, canonicalNameOfLambda.lastIndexOf("$$")); | |
151 | int b = ret.lastIndexOf("$"); | |
152 |
2
1. enclosingClassNameOfLambda : changed conditional boundary → SURVIVED 2. enclosingClassNameOfLambda : negated conditional → SURVIVED |
if (b < 0) |
153 |
1
1. enclosingClassNameOfLambda : replaced return value with "" for com/github/dakusui/osynth/core/utils/MethodUtils::enclosingClassNameOfLambda → KILLED |
return ret; |
154 |
2
1. enclosingClassNameOfLambda : Replaced integer addition with subtraction → SURVIVED 2. enclosingClassNameOfLambda : replaced return value with "" for com/github/dakusui/osynth/core/utils/MethodUtils::enclosingClassNameOfLambda → SURVIVED |
return ret.substring(b + "$".length()); |
155 | } | |
156 | ||
157 | private static Stream<Class<?>> streamSupertypes(Class<?> klass) { | |
158 |
1
1. streamSupertypes : replaced return value with Stream.empty for com/github/dakusui/osynth/core/utils/MethodUtils::streamSupertypes → KILLED |
return Stream.concat( |
159 | Stream.of(klass.getSuperclass()), | |
160 | Arrays.stream(klass.getInterfaces())) | |
161 | .filter(Objects::nonNull); | |
162 | } | |
163 | ||
164 | /** | |
165 | * An interface to define a block which possibly throws an exception. | |
166 | * Intended to be used with {@link MethodUtils#execute} method. | |
167 | * | |
168 | * @param <T> A type of the value retuned by the block. | |
169 | */ | |
170 | public interface FailableSupplier<T> { | |
171 | T get() throws Throwable; | |
172 | } | |
173 | ||
174 | private static Optional<Method> findMethodMatchingWith(MethodSignature methodSignature, Class<?> fromClass) { | |
175 | try { | |
176 |
1
1. findMethodMatchingWith : replaced return value with Optional.empty for com/github/dakusui/osynth/core/utils/MethodUtils::findMethodMatchingWith → KILLED |
return Optional.of(fromClass.getMethod(methodSignature.name(), methodSignature.parameterTypes())); |
177 | } catch (NoSuchMethodException e) { | |
178 | return Optional.empty(); | |
179 | } | |
180 | } | |
181 | ||
182 | public static MethodHandler withName(String name, MethodHandler methodHandler) { | |
183 |
1
1. withName : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils::withName → KILLED |
return new MethodHandler() { |
184 | @Override | |
185 | public Object handle(SynthesizedObject synthesizedObject, Object[] objects) throws Throwable { | |
186 |
1
1. handle : replaced return value with null for com/github/dakusui/osynth/core/utils/MethodUtils$1::handle → KILLED |
return methodHandler.handle(synthesizedObject, objects); |
187 | } | |
188 | ||
189 | @Override | |
190 | public String toString() { | |
191 |
1
1. toString : replaced return value with "" for com/github/dakusui/osynth/core/utils/MethodUtils$1::toString → SURVIVED |
return name; |
192 | } | |
193 | }; | |
194 | } | |
195 | } | |
Mutations | ||
31 |
1.1 |
|
36 |
1.1 2.2 |
|
38 |
1.1 |
|
39 |
1.1 |
|
44 |
1.1 |
|
48 |
1.1 2.2 |
|
49 |
1.1 |
|
53 |
1.1 2.2 |
|
58 |
1.1 2.2 |
|
62 |
1.1 |
|
65 |
1.1 |
|
66 |
1.1 |
|
78 |
1.1 |
|
83 |
1.1 |
|
92 |
1.1 |
|
93 |
1.1 |
|
94 |
1.1 |
|
98 |
1.1 |
|
99 |
1.1 |
|
106 |
1.1 2.2 |
|
110 |
1.1 |
|
115 |
1.1 |
|
122 |
1.1 2.2 3.3 |
|
123 |
1.1 |
|
126 |
1.1 |
|
133 |
1.1 |
|
134 |
1.1 2.2 |
|
137 |
1.1 |
|
141 |
1.1 |
|
142 |
1.1 |
|
144 |
1.1 2.2 |
|
152 |
1.1 2.2 |
|
153 |
1.1 |
|
154 |
1.1 2.2 |
|
158 |
1.1 |
|
176 |
1.1 |
|
183 |
1.1 |
|
186 |
1.1 |
|
191 |
1.1 |