Kotlin Facet: Get rid of copy constructors for compiler arguments/settings and use reflection-based copying instead
This commit is contained in:
+1
-35
@@ -20,7 +20,6 @@ import com.intellij.util.SmartList;
|
|||||||
import com.sampullara.cli.Argument;
|
import com.sampullara.cli.Argument;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class CommonCompilerArguments {
|
public abstract class CommonCompilerArguments {
|
||||||
@@ -73,44 +72,11 @@ public abstract class CommonCompilerArguments {
|
|||||||
|
|
||||||
public List<String> unknownExtraFlags = new SmartList<String>();
|
public List<String> unknownExtraFlags = new SmartList<String>();
|
||||||
|
|
||||||
public CommonCompilerArguments() {
|
|
||||||
}
|
|
||||||
|
|
||||||
protected CommonCompilerArguments(CommonCompilerArguments arguments) {
|
|
||||||
this.languageVersion = arguments.languageVersion;
|
|
||||||
this.apiVersion = arguments.apiVersion;
|
|
||||||
this.suppressWarnings = arguments.suppressWarnings;
|
|
||||||
this.verbose = arguments.verbose;
|
|
||||||
this.version = arguments.version;
|
|
||||||
this.help = arguments.help;
|
|
||||||
this.extraHelp = arguments.extraHelp;
|
|
||||||
this.noInline = arguments.noInline;
|
|
||||||
this.repeat = arguments.repeat;
|
|
||||||
this.pluginClasspaths = arguments.pluginClasspaths != null ? Arrays.copyOf(arguments.pluginClasspaths, arguments.pluginClasspaths.length) : null;
|
|
||||||
this.pluginOptions = arguments.pluginOptions != null ? Arrays.copyOf(arguments.pluginOptions, arguments.pluginOptions.length) : null;
|
|
||||||
this.freeArgs.addAll(arguments.freeArgs);
|
|
||||||
this.unknownExtraFlags.addAll(arguments.unknownExtraFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract CommonCompilerArguments copy();
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public String executableScriptFileName() {
|
public String executableScriptFileName() {
|
||||||
return "kotlinc";
|
return "kotlinc";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used only for serialize and deserialize settings. Don't use in other places!
|
// Used only for serialize and deserialize settings. Don't use in other places!
|
||||||
public static final class DummyImpl extends CommonCompilerArguments {
|
public static final class DummyImpl extends CommonCompilerArguments {}
|
||||||
public DummyImpl() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public DummyImpl(DummyImpl arguments) {
|
|
||||||
super(arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CommonCompilerArguments copy() {
|
|
||||||
return new DummyImpl(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
-25
@@ -20,8 +20,6 @@ import com.sampullara.cli.Argument;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.CALL;
|
import static org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.CALL;
|
||||||
import static org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.NO_CALL;
|
import static org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.NO_CALL;
|
||||||
|
|
||||||
@@ -75,29 +73,6 @@ public class K2JSCompilerArguments extends CommonCompilerArguments {
|
|||||||
@ValueDescription("<path>")
|
@ValueDescription("<path>")
|
||||||
public String outputPostfix;
|
public String outputPostfix;
|
||||||
|
|
||||||
public K2JSCompilerArguments() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private K2JSCompilerArguments(K2JSCompilerArguments arguments) {
|
|
||||||
super(arguments);
|
|
||||||
this.outputFile = arguments.outputFile;
|
|
||||||
this.noStdlib = arguments.noStdlib;
|
|
||||||
this.libraryFiles = arguments.libraryFiles != null ? Arrays.copyOf(arguments.libraryFiles, arguments.libraryFiles.length) : null;
|
|
||||||
this.sourceMap = arguments.sourceMap;
|
|
||||||
this.metaInfo = arguments.metaInfo;
|
|
||||||
this.kjsm = arguments.kjsm;
|
|
||||||
this.target = arguments.target;
|
|
||||||
this.moduleKind = arguments.moduleKind;
|
|
||||||
this.main = arguments.main;
|
|
||||||
this.outputPrefix = arguments.outputPrefix;
|
|
||||||
this.outputPostfix = arguments.outputPostfix;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public K2JSCompilerArguments copy() {
|
|
||||||
return new K2JSCompilerArguments(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public String executableScriptFileName() {
|
public String executableScriptFileName() {
|
||||||
|
|||||||
-6
@@ -110,12 +110,6 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
|
|||||||
// Paths to output directories for friend modules.
|
// Paths to output directories for friend modules.
|
||||||
public String[] friendPaths;
|
public String[] friendPaths;
|
||||||
|
|
||||||
@Override
|
|
||||||
public CommonCompilerArguments copy() {
|
|
||||||
// No need to copy these arguments yet
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public String executableScriptFileName() {
|
public String executableScriptFileName() {
|
||||||
|
|||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.cli.common.arguments
|
||||||
|
|
||||||
|
import com.intellij.util.xmlb.XmlSerializerUtil
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
import java.lang.reflect.Modifier
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
fun <T : Any> copyBean(bean: T) = copyFields(bean, bean.javaClass.newInstance(), true)
|
||||||
|
|
||||||
|
fun <From : Any, To : From> mergeBeans(from: From, to: To): To {
|
||||||
|
// TODO: rewrite when updated version of com.intellij.util.xmlb is available on TeamCity
|
||||||
|
return copyFields(from, XmlSerializerUtil.createCopy(to), false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <From : Any, To : From> copyFields(from: From, to: To, deepCopyWhenNeeded: Boolean = false): To {
|
||||||
|
val fromFields = collectFieldsToCopy(from.javaClass)
|
||||||
|
for (fromField in fromFields) {
|
||||||
|
val toField = to.javaClass.getField(fromField.name)
|
||||||
|
val fromValue = fromField.get(from)
|
||||||
|
toField.set(to, if (deepCopyWhenNeeded) fromValue?.copyValueIfNeeded() else fromValue)
|
||||||
|
}
|
||||||
|
return to
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Any.copyValueIfNeeded(): Any {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return when (this) {
|
||||||
|
is ByteArray -> Arrays.copyOf(this, size)
|
||||||
|
is CharArray -> Arrays.copyOf(this, size)
|
||||||
|
is ShortArray -> Arrays.copyOf(this, size)
|
||||||
|
is IntArray -> Arrays.copyOf(this, size)
|
||||||
|
is LongArray -> Arrays.copyOf(this, size)
|
||||||
|
is FloatArray -> Arrays.copyOf(this, size)
|
||||||
|
is DoubleArray -> Arrays.copyOf(this, size)
|
||||||
|
is BooleanArray -> Arrays.copyOf(this, size)
|
||||||
|
|
||||||
|
is Array<*> -> Array(size) { this[it]?.copyValueIfNeeded() }
|
||||||
|
|
||||||
|
is MutableCollection<*> -> (this as Collection<Any?>).mapTo(javaClass.newInstance() as MutableCollection<Any?>) { it?.copyValueIfNeeded() }
|
||||||
|
|
||||||
|
is MutableMap<*, *> -> (javaClass.newInstance() as MutableMap<Any?, Any?>).apply {
|
||||||
|
for ((k, v) in this@copyValueIfNeeded.entries) {
|
||||||
|
put(k?.copyValueIfNeeded(), v?.copyValueIfNeeded())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectFieldsToCopy(clazz: Class<*>): List<Field> {
|
||||||
|
val fromFields = ArrayList<Field>()
|
||||||
|
|
||||||
|
var currentClass: Class<*>? = clazz
|
||||||
|
while (currentClass != null) {
|
||||||
|
for (field in currentClass.declaredFields) {
|
||||||
|
val modifiers = field.modifiers
|
||||||
|
if (!Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)) {
|
||||||
|
fromFields.add(field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentClass = currentClass.superclass
|
||||||
|
}
|
||||||
|
|
||||||
|
return fromFields
|
||||||
|
}
|
||||||
@@ -23,16 +23,6 @@ class CompilerSettings {
|
|||||||
var copyJsLibraryFiles: Boolean = true
|
var copyJsLibraryFiles: Boolean = true
|
||||||
var outputDirectoryForJsLibraryFiles: String = DEFAULT_OUTPUT_DIRECTORY
|
var outputDirectoryForJsLibraryFiles: String = DEFAULT_OUTPUT_DIRECTORY
|
||||||
|
|
||||||
constructor()
|
|
||||||
|
|
||||||
constructor(settings: CompilerSettings) {
|
|
||||||
additionalArguments = settings.additionalArguments
|
|
||||||
scriptTemplates = settings.scriptTemplates
|
|
||||||
scriptTemplatesClasspath = settings.scriptTemplatesClasspath
|
|
||||||
copyJsLibraryFiles = settings.copyJsLibraryFiles
|
|
||||||
outputDirectoryForJsLibraryFiles = settings.outputDirectoryForJsLibraryFiles
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val DEFAULT_ADDITIONAL_ARGUMENTS = "-version"
|
private val DEFAULT_ADDITIONAL_ARGUMENTS = "-version"
|
||||||
private val DEFAULT_OUTPUT_DIRECTORY = "lib"
|
private val DEFAULT_OUTPUT_DIRECTORY = "lib"
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.roots.LibraryOrderEntry
|
|||||||
import com.intellij.openapi.roots.ModuleRootManager
|
import com.intellij.openapi.roots.ModuleRootManager
|
||||||
import com.intellij.openapi.roots.ModuleRootModel
|
import com.intellij.openapi.roots.ModuleRootModel
|
||||||
import com.intellij.util.text.VersionComparatorUtil
|
import com.intellij.util.text.VersionComparatorUtil
|
||||||
|
import org.jetbrains.kotlin.cli.common.arguments.copyBean
|
||||||
import org.jetbrains.kotlin.config.*
|
import org.jetbrains.kotlin.config.*
|
||||||
import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JsCompilerArgumentsHolder
|
import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JsCompilerArgumentsHolder
|
||||||
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder
|
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder
|
||||||
@@ -115,15 +116,15 @@ internal fun KotlinFacetSettings.initializeIfNeeded(module: Module, rootModel: M
|
|||||||
|
|
||||||
with(compilerInfo) {
|
with(compilerInfo) {
|
||||||
if (commonCompilerArguments == null) {
|
if (commonCompilerArguments == null) {
|
||||||
commonCompilerArguments = KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.copy()
|
commonCompilerArguments = copyBean(KotlinCommonCompilerArgumentsHolder.getInstance(project).settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compilerSettings == null) {
|
if (compilerSettings == null) {
|
||||||
compilerSettings = CompilerSettings(KotlinCompilerSettings.getInstance(project).settings)
|
compilerSettings = copyBean(KotlinCompilerSettings.getInstance(project).settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k2jsCompilerArguments == null) {
|
if (k2jsCompilerArguments == null) {
|
||||||
k2jsCompilerArguments = Kotlin2JsCompilerArgumentsHolder.getInstance (project).settings.copy()
|
k2jsCompilerArguments = copyBean(Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,33 +16,29 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.compilerRunner
|
package org.jetbrains.kotlin.compilerRunner
|
||||||
|
|
||||||
import com.intellij.util.xmlb.XmlSerializerUtil
|
|
||||||
import org.jetbrains.jps.api.GlobalOptions
|
import org.jetbrains.jps.api.GlobalOptions
|
||||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||||
import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY
|
import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||||
|
import org.jetbrains.kotlin.cli.common.arguments.mergeBeans
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO
|
||||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil
|
import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil
|
||||||
|
import org.jetbrains.kotlin.config.CompilerSettings
|
||||||
import org.jetbrains.kotlin.daemon.client.CompilationServices
|
import org.jetbrains.kotlin.daemon.client.CompilationServices
|
||||||
import org.jetbrains.kotlin.daemon.client.DaemonReportMessage
|
import org.jetbrains.kotlin.daemon.client.DaemonReportMessage
|
||||||
import org.jetbrains.kotlin.daemon.client.DaemonReportingTargets
|
import org.jetbrains.kotlin.daemon.client.DaemonReportingTargets
|
||||||
import org.jetbrains.kotlin.daemon.client.KotlinCompilerClient
|
import org.jetbrains.kotlin.daemon.client.KotlinCompilerClient
|
||||||
import org.jetbrains.kotlin.config.CompilerSettings
|
|
||||||
import org.jetbrains.kotlin.daemon.common.*
|
import org.jetbrains.kotlin.daemon.common.*
|
||||||
import org.jetbrains.kotlin.jps.build.KotlinBuilder
|
import org.jetbrains.kotlin.jps.build.KotlinBuilder
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||||
import org.jetbrains.kotlin.utils.rethrow
|
|
||||||
import java.io.*
|
import java.io.*
|
||||||
import java.lang.reflect.Field
|
|
||||||
import java.lang.reflect.Modifier
|
|
||||||
import java.rmi.ConnectException
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
@@ -250,36 +246,6 @@ object KotlinCompilerRunner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T : CommonCompilerArguments> mergeBeans(from: CommonCompilerArguments, to: T): T {
|
|
||||||
// TODO: rewrite when updated version of com.intellij.util.xmlb is available on TeamCity
|
|
||||||
val copy = XmlSerializerUtil.createCopy(to)
|
|
||||||
|
|
||||||
val fromFields = collectFieldsToCopy(from.javaClass)
|
|
||||||
for (fromField in fromFields) {
|
|
||||||
val toField = copy.javaClass.getField(fromField.name)
|
|
||||||
toField.set(copy, fromField.get(from))
|
|
||||||
}
|
|
||||||
|
|
||||||
return copy
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun collectFieldsToCopy(clazz: Class<*>): List<Field> {
|
|
||||||
val fromFields = ArrayList<Field>()
|
|
||||||
|
|
||||||
var currentClass: Class<*>? = clazz
|
|
||||||
while (currentClass != null) {
|
|
||||||
for (field in currentClass.declaredFields) {
|
|
||||||
val modifiers = field.modifiers
|
|
||||||
if (!Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)) {
|
|
||||||
fromFields.add(field)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentClass = currentClass.superclass
|
|
||||||
}
|
|
||||||
|
|
||||||
return fromFields
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupK2JvmArguments(moduleFile: File, settings: K2JVMCompilerArguments) {
|
private fun setupK2JvmArguments(moduleFile: File, settings: K2JVMCompilerArguments) {
|
||||||
with(settings) {
|
with(settings) {
|
||||||
module = moduleFile.absolutePath
|
module = moduleFile.absolutePath
|
||||||
|
|||||||
Reference in New Issue
Block a user