001    /*
002     * Copyright 2010-2016 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.kotlin.compilerRunner;
018    
019    import com.intellij.openapi.util.text.StringUtil;
020    import com.intellij.util.Function;
021    import com.intellij.util.containers.ComparatorUtil;
022    import com.sampullara.cli.Argument;
023    import org.jetbrains.annotations.NotNull;
024    import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments;
025    
026    import java.lang.reflect.Field;
027    import java.util.ArrayList;
028    import java.util.List;
029    
030    public class ArgumentUtils {
031        private ArgumentUtils() {}
032    
033        @NotNull
034        public static List<String> convertArgumentsToStringList(@NotNull CommonCompilerArguments arguments)
035                throws InstantiationException, IllegalAccessException {
036            List<String> result = new ArrayList<String>();
037            convertArgumentsToStringList(arguments, arguments.getClass().newInstance(), arguments.getClass(), result);
038            result.addAll(arguments.freeArgs);
039            return result;
040        }
041    
042        private static void convertArgumentsToStringList(
043                @NotNull CommonCompilerArguments arguments,
044                @NotNull CommonCompilerArguments defaultArguments,
045                @NotNull Class<?> clazz,
046                @NotNull List<String> result
047        ) throws IllegalAccessException, InstantiationException {
048            for (Field field : clazz.getDeclaredFields()) {
049                Argument argument = field.getAnnotation(Argument.class);
050                if (argument == null) continue;
051    
052                Object value;
053                Object defaultValue;
054                try {
055                    value = field.get(arguments);
056                    defaultValue = field.get(defaultArguments);
057                }
058                catch (IllegalAccessException ignored) {
059                    // skip this field
060                    continue;
061                }
062    
063                if (ComparatorUtil.equalsNullable(value, defaultValue)) continue;
064    
065                String name = getAlias(argument);
066                if (name == null) {
067                    name = getName(argument, field);
068                }
069    
070                Class<?> fieldType = field.getType();
071    
072                if (fieldType.isArray()) {
073                    Object[] values = (Object[]) value;
074                    if (values.length == 0) continue;
075                    //noinspection unchecked
076                    value = StringUtil.join(values, Function.TO_STRING, argument.delimiter());
077                }
078    
079                result.add(argument.prefix() + name);
080    
081                if (fieldType == boolean.class || fieldType == Boolean.class) continue;
082    
083                result.add(value.toString());
084            }
085    
086            Class<?> superClazz = clazz.getSuperclass();
087            if (superClazz != null) {
088                convertArgumentsToStringList(arguments, defaultArguments, superClazz, result);
089            }
090        }
091    
092        private static String getAlias(Argument argument) {
093            String alias = argument.alias();
094            return alias.isEmpty() ? null : alias;
095        }
096    
097        private static String getName(Argument argument, Field field) {
098            String name = argument.value();
099            return name.isEmpty() ? field.getName() : name;
100        }
101    }