if (method != null) { function = ReflectJvmMapping.getKotlinFunction(method); predicate = p -> KParameter.Kind.VALUE.equals(p.getKind()); predicate = p -> KParameter.Kind.VALUE.equals(p.getKind()) || KParameter.Kind.INSTANCE.equals(p.getKind()); .collect(Collectors.toList()) .get(index); return (parameter.getType().isMarkedNullable() || parameter.isOptional());
@Nullable private String[] getParameterNames(List<KParameter> parameters) { List<KParameter> filteredParameters = parameters .stream() // Extension receivers of extension methods must be included as they appear as normal method parameters in Java .filter(p -> KParameter.Kind.VALUE.equals(p.getKind()) || KParameter.Kind.EXTENSION_RECEIVER.equals(p.getKind())) .collect(Collectors.toList()); String[] parameterNames = new String[filteredParameters.size()]; for (int i = 0; i < filteredParameters.size(); i++) { KParameter parameter = filteredParameters.get(i); // extension receivers are not explicitly named, but require a name for Java interoperability // $receiver is not a valid Kotlin identifier, but valid in Java, so it can be used here String name = KParameter.Kind.EXTENSION_RECEIVER.equals(parameter.getKind()) ? "$receiver" : parameter.getName(); if (name == null) { return null; } parameterNames[i] = name; } return parameterNames; }
private static boolean parameterMatches(List<KParameter> constructorArguments, KFunction<?> kotlinFunction) { boolean foundInstance = false; int constructorArgIndex = 0; for (KParameter parameter : kotlinFunction.getParameters()) { if (parameter.getKind() == Kind.INSTANCE) { foundInstance = true; continue; } if (constructorArguments.size() <= constructorArgIndex) { return false; } KParameter constructorParameter = constructorArguments.get(constructorArgIndex); if (!constructorParameter.getName().equals(parameter.getName()) || !constructorParameter.getType().equals(parameter.getType())) { return false; } constructorArgIndex++; } return foundInstance; }
if (parameter.isOptional() && !isPresent.test(parameter)) { mask = mask | (1 << (index % Integer.SIZE)); if (parameter.getKind() == Kind.VALUE) { index++;
/** * Instantiate a Kotlin class using the provided constructor. * @param ctor the constructor of the Kotlin class to instantiate * @param args the constructor arguments to apply * (use {@code null} for unspecified parameter if needed) */ public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws IllegalAccessException, InvocationTargetException, InstantiationException { KFunction<T> kotlinConstructor = ReflectJvmMapping.getKotlinFunction(ctor); if (kotlinConstructor == null) { return ctor.newInstance(args); } List<KParameter> parameters = kotlinConstructor.getParameters(); Map<KParameter, Object> argParameters = new HashMap<>(parameters.size()); Assert.isTrue(args.length <= parameters.size(), "Number of provided arguments should be less of equals than number of constructor parameters"); for (int i = 0 ; i < args.length ; i++) { if (!(parameters.get(i).isOptional() && args[i] == null)) { argParameters.put(parameters.get(i), args[i]); } } return kotlinConstructor.callBy(argParameters); }
/** * Returns {@literal} whether the given {@link MethodParameter} is nullable. Its declaring method can reference a * Kotlin function, property or interface property. * * @return {@literal true} if {@link MethodParameter} is nullable. * @since 2.0.1 */ static boolean isNullable(MethodParameter parameter) { Method method = parameter.getMethod(); if (method == null) { throw new IllegalStateException(String.format("Cannot obtain method from parameter %s!", parameter)); } KFunction<?> kotlinFunction = ReflectJvmMapping.getKotlinFunction(method); if (kotlinFunction == null) { // Fallback to own lookup because there's no public Kotlin API for that kind of lookup until // https://youtrack.jetbrains.com/issue/KT-20768 gets resolved. kotlinFunction = findKFunction(method)// .orElseThrow(() -> new IllegalArgumentException( String.format("Cannot resolve %s to a Kotlin function!", parameter))); } KType type = parameter.getParameterIndex() == -1 // ? kotlinFunction.getReturnType() // : kotlinFunction.getParameters().get(parameter.getParameterIndex() + 1).getType(); return type.isMarkedNullable(); }
@SuppressWarnings("unchecked") private static Optional<Method> findPublicCopyMethod(Method defaultKotlinMethod) { Class<?> type = defaultKotlinMethod.getDeclaringClass(); KClass<?> kotlinClass = JvmClassMappingKt.getKotlinClass(type); KFunction<?> primaryConstructor = KClasses.getPrimaryConstructor(kotlinClass); if (primaryConstructor == null) { return Optional.empty(); } List<KParameter> constructorArguments = primaryConstructor.getParameters() // .stream() // .filter(it -> it.getKind() == Kind.VALUE) // .collect(Collectors.toList()); return Arrays.stream(type.getDeclaredMethods()).filter(it -> it.getName().equals("copy") // && !it.isSynthetic() // && !Modifier.isStatic(it.getModifiers()) // && it.getReturnType().equals(type) // && it.getParameterCount() == constructorArguments.size()) // .filter(it -> { KFunction<?> kotlinFunction = ReflectJvmMapping.getKotlinFunction(it); if (kotlinFunction == null) { return false; } return parameterMatches(constructorArguments, kotlinFunction); }).findFirst(); }
KotlinCopyByProperty(KFunction<?> copyFunction, PersistentProperty<?> property) { this.parameterPosition = findIndex(copyFunction, property.getName()); this.parameterCount = copyFunction.getParameters().size(); this.defaultMask = KotlinDefaultMask.from(copyFunction, it -> property.getName().equals(it.getName())); }
/** * Instantiate a Kotlin class using the provided constructor. * @param ctor the constructor of the Kotlin class to instantiate * @param args the constructor arguments to apply * (use {@code null} for unspecified parameter if needed) */ public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws IllegalAccessException, InvocationTargetException, InstantiationException { KFunction<T> kotlinConstructor = ReflectJvmMapping.getKotlinFunction(ctor); if (kotlinConstructor == null) { return ctor.newInstance(args); } List<KParameter> parameters = kotlinConstructor.getParameters(); Map<KParameter, Object> argParameters = new HashMap<>(parameters.size()); Assert.isTrue(args.length <= parameters.size(), "Number of provided arguments should be less of equals than number of constructor parameters"); for (int i = 0 ; i < args.length ; i++) { if (!(parameters.get(i).isOptional() && args[i] == null)) { argParameters.put(parameters.get(i), args[i]); } } return kotlinConstructor.callBy(argParameters); }
if(kotlinFunction != null) { KParameter kParameter = kotlinFunction.getParameters().get(parameterIndex + 1); required = !kParameter.getType().isMarkedNullable(); } else { required = false;
if (method != null) { function = ReflectJvmMapping.getKotlinFunction(method); predicate = p -> KParameter.Kind.VALUE.equals(p.getKind()); predicate = p -> KParameter.Kind.VALUE.equals(p.getKind()) || KParameter.Kind.INSTANCE.equals(p.getKind()); .collect(Collectors.toList()) .get(index); return (parameter.getType().isMarkedNullable() || parameter.isOptional());
@Nullable private String[] getParameterNames(List<KParameter> parameters) { List<KParameter> filteredParameters = parameters .stream() // Extension receivers of extension methods must be included as they appear as normal method parameters in Java .filter(p -> KParameter.Kind.VALUE.equals(p.getKind()) || KParameter.Kind.EXTENSION_RECEIVER.equals(p.getKind())) .collect(Collectors.toList()); String[] parameterNames = new String[filteredParameters.size()]; for (int i = 0; i < filteredParameters.size(); i++) { KParameter parameter = filteredParameters.get(i); // extension receivers are not explicitly named, but require a name for Java interoperability // $receiver is not a valid Kotlin identifier, but valid in Java, so it can be used here String name = KParameter.Kind.EXTENSION_RECEIVER.equals(parameter.getKind()) ? "$receiver" : parameter.getName(); if (name == null) { return null; } parameterNames[i] = name; } return parameterNames; }
Class<Object> type = parameter.getType().getType(); if (it.isOptional() && params[index] == null) { if (type.isPrimitive()) {
if (method != null) { function = ReflectJvmMapping.getKotlinFunction(method); predicate = p -> KParameter.Kind.VALUE.equals(p.getKind()); predicate = p -> KParameter.Kind.VALUE.equals(p.getKind()) || KParameter.Kind.INSTANCE.equals(p.getKind()); .collect(Collectors.toList()) .get(index); return (parameter.getType().isMarkedNullable() || parameter.isOptional());
private static <T> Map<KParameter, Object> getCallArgs(KCallable<?> callable, PersistentProperty<?> property, T bean, @Nullable Object value) { Map<KParameter, Object> args = new LinkedHashMap<>(2, 1); List<KParameter> parameters = callable.getParameters(); for (KParameter parameter : parameters) { if (parameter.getKind() == Kind.INSTANCE) { args.put(parameter, bean); } if (parameter.getKind() == Kind.VALUE && parameter.getName() != null && parameter.getName().equals(property.getName())) { args.put(parameter, value); } } return args; }
/** * Check whether the specified {@link MethodParameter} represents a nullable Kotlin type or an * optional parameter (with a default value in the Kotlin declaration). */ public static boolean isOptional(MethodParameter param) { Method method = param.getMethod(); Constructor<?> ctor = param.getConstructor(); int index = param.getParameterIndex(); if (method != null && index == -1) { KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method); return (function != null && function.getReturnType().isMarkedNullable()); } else { KFunction<?> function = null; if (method != null) { function = ReflectJvmMapping.getKotlinFunction(method); } else if (ctor != null) { function = ReflectJvmMapping.getKotlinFunction(ctor); } if (function != null) { List<KParameter> parameters = function.getParameters(); KParameter parameter = parameters .stream() .filter(p -> KParameter.Kind.VALUE.equals(p.getKind())) .collect(Collectors.toList()) .get(index); return (parameter.getType().isMarkedNullable() || parameter.isOptional()); } } return false; }
@Nullable private String[] getParameterNames(List<KParameter> parameters) { List<KParameter> filteredParameters = parameters .stream() // Extension receivers of extension methods must be included as they appear as normal method parameters in Java .filter(p -> KParameter.Kind.VALUE.equals(p.getKind()) || KParameter.Kind.EXTENSION_RECEIVER.equals(p.getKind())) .collect(Collectors.toList()); String[] parameterNames = new String[filteredParameters.size()]; for (int i = 0; i < filteredParameters.size(); i++) { KParameter parameter = filteredParameters.get(i); // extension receivers are not explicitly named, but require a name for Java interoperability // $receiver is not a valid Kotlin identifier, but valid in Java, so it can be used here String name = KParameter.Kind.EXTENSION_RECEIVER.equals(parameter.getKind()) ? "$receiver" : parameter.getName(); if (name == null) { return null; } parameterNames[i] = name; } return parameterNames; }
@Nullable private String[] getParameterNames(List<KParameter> parameters) { List<KParameter> filteredParameters = parameters .stream() // Extension receivers of extension methods must be included as they appear as normal method parameters in Java .filter(p -> KParameter.Kind.VALUE.equals(p.getKind()) || KParameter.Kind.EXTENSION_RECEIVER.equals(p.getKind())) .collect(Collectors.toList()); String[] parameterNames = new String[filteredParameters.size()]; for (int i = 0; i < filteredParameters.size(); i++) { KParameter parameter = filteredParameters.get(i); // extension receivers are not explicitly named, but require a name for Java interoperability // $receiver is not a valid Kotlin identifier, but valid in Java, so it can be used here String name = KParameter.Kind.EXTENSION_RECEIVER.equals(parameter.getKind()) ? "$receiver" : parameter.getName(); if (name == null) { return null; } parameterNames[i] = name; } return parameterNames; }