Fix reflection-based operations on compiler arguments after conversion

This commit is contained in:
Alexey Sedunov
2017-07-27 15:20:57 +03:00
parent 50599c933f
commit 2984a5a19f
10 changed files with 162 additions and 95 deletions
@@ -16,13 +16,21 @@
package org.jetbrains.kotlin.compilerRunner;
import com.intellij.util.containers.ContainerUtil;
import kotlin.jvm.JvmClassMappingKt;
import kotlin.reflect.KClass;
import kotlin.reflect.KProperty1;
import kotlin.reflect.KVisibility;
import kotlin.reflect.full.KClasses;
import kotlin.reflect.jvm.ReflectJvmMapping;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.cli.common.arguments.Argument;
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments;
import org.jetbrains.kotlin.cli.common.arguments.ParseCommandLineArgumentsKt;
import org.jetbrains.kotlin.utils.StringsKt;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -33,39 +41,35 @@ public class ArgumentUtils {
@NotNull
public static List<String> convertArgumentsToStringList(@NotNull CommonToolArguments arguments)
throws InstantiationException, IllegalAccessException {
throws InstantiationException, IllegalAccessException, InvocationTargetException {
List<String> result = new ArrayList<>();
convertArgumentsToStringList(arguments, arguments.getClass().newInstance(), arguments.getClass(), result);
Class<? extends CommonToolArguments> argumentsClass = arguments.getClass();
convertArgumentsToStringList(arguments, argumentsClass.newInstance(), JvmClassMappingKt.getKotlinClass(argumentsClass), result);
result.addAll(arguments.getFreeArgs());
return result;
}
@SuppressWarnings("unchecked")
private static void convertArgumentsToStringList(
@NotNull CommonToolArguments arguments,
@NotNull CommonToolArguments defaultArguments,
@NotNull Class<?> clazz,
@NotNull KClass<?> clazz,
@NotNull List<String> result
) throws IllegalAccessException, InstantiationException {
for (Field field : clazz.getDeclaredFields()) {
Argument argument = field.getAnnotation(Argument.class);
) throws IllegalAccessException, InstantiationException, InvocationTargetException {
for (KProperty1 property : KClasses.getMemberProperties(clazz)) {
Argument argument = ContainerUtil.findInstance(property.getAnnotations(), Argument.class);
if (argument == null) continue;
Object value;
Object defaultValue;
try {
value = field.get(arguments);
defaultValue = field.get(defaultArguments);
}
catch (IllegalAccessException ignored) {
// skip this field
continue;
}
if (property.getVisibility() != KVisibility.PUBLIC) continue;
Object value = property.get(arguments);
Object defaultValue = property.get(defaultArguments);
if (value == null || Objects.equals(value, defaultValue)) continue;
Class<?> fieldType = field.getType();
Type propertyJavaType = ReflectJvmMapping.getJavaType(property.getReturnType());
if (fieldType.isArray()) {
if (propertyJavaType instanceof Class && ((Class) propertyJavaType).isArray()) {
Object[] values = (Object[]) value;
if (values.length == 0) continue;
value = StringsKt.join(Arrays.asList(values), ",");
@@ -73,7 +77,7 @@ public class ArgumentUtils {
result.add(argument.value());
if (fieldType == boolean.class || fieldType == Boolean.class) continue;
if (propertyJavaType == boolean.class || propertyJavaType == Boolean.class) continue;
if (ParseCommandLineArgumentsKt.isAdvanced(argument)) {
result.set(result.size() - 1, argument.value() + "=" + value.toString());
@@ -82,10 +86,5 @@ public class ArgumentUtils {
result.add(value.toString());
}
}
Class<?> superClazz = clazz.getSuperclass();
if (superClazz != null) {
convertArgumentsToStringList(arguments, defaultArguments, superClazz, result);
}
}
}