diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt index f2b8790eba4..90c915098b4 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt @@ -44,7 +44,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() { valueDescription = "", description = "Provide source compatibility with specified language version" ) - var languageVersion: String? by FreezableVar(null) + var languageVersion: String? by NullableStringFreezableVar(null) @get:Transient var autoAdvanceApiVersion: Boolean by FreezableVar(true) @@ -55,14 +55,14 @@ abstract class CommonCompilerArguments : CommonToolArguments() { valueDescription = "", description = "Allow to use declarations only from the specified version of bundled libraries" ) - var apiVersion: String? by FreezableVar(null) + var apiVersion: String? by NullableStringFreezableVar(null) @Argument( value = "-kotlin-home", valueDescription = "", description = "Path to Kotlin compiler home directory, used for runtime libraries discovery" ) - var kotlinHome: String? by FreezableVar(null) + var kotlinHome: String? by NullableStringFreezableVar(null) @Argument(value = "-P", valueDescription = PLUGIN_OPTION_FORMAT, description = "Pass an option to a plugin") var pluginOptions: Array? by FreezableVar(null) @@ -101,14 +101,14 @@ abstract class CommonCompilerArguments : CommonToolArguments() { valueDescription = "", description = "Path to the kotlin-compiler.jar or directory where IntelliJ configuration files can be found" ) - var intellijPluginRoot: String? by FreezableVar(null) + var intellijPluginRoot: String? by NullableStringFreezableVar(null) @Argument( value = "-Xcoroutines", valueDescription = "{enable|warn|error}", description = "Enable coroutines or report warnings or errors on declarations and use sites of 'suspend' modifier" ) - var coroutinesState: String? by FreezableVar(WARN) + var coroutinesState: String? by NullableStringFreezableVar(WARN) @Argument( value = "-Xnew-inference", @@ -162,7 +162,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() { valueDescription = "", description = "Dump detailed performance statistics to the specified file" ) - var dumpPerf: String? by FreezableVar(null) + var dumpPerf: String? by NullableStringFreezableVar(null) @Argument( value = "-Xprogressive", diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/Freezable.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/Freezable.kt index 51786ddbd08..885d8be5d04 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/Freezable.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/Freezable.kt @@ -20,7 +20,7 @@ import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty abstract class Freezable { - protected inner class FreezableVar(private var value: T) : ReadWriteProperty { + protected open inner class FreezableVar(private var value: T) : ReadWriteProperty { override fun getValue(thisRef: Any, property: KProperty<*>) = value override fun setValue(thisRef: Any, property: KProperty<*>, value: T) { @@ -29,6 +29,14 @@ abstract class Freezable { } } + protected inner class NullableStringFreezableVar(value: String?) : FreezableVar(value) { + private val defaultValue = value + + override fun setValue(thisRef: Any, property: KProperty<*>, value: String?) { + super.setValue(thisRef, property, if (value.isNullOrEmpty()) defaultValue else value) + } + } + private var frozen: Boolean = false private fun getInstanceWithFreezeStatus(value: Boolean) = if (value == frozen) this else copyBean(this).apply { frozen = value } diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt index a3a61b0f608..2b6ce988760 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt @@ -26,7 +26,7 @@ class K2JSCompilerArguments : CommonCompilerArguments() { @GradleOption(DefaultValues.StringNullDefault::class) @Argument(value = "-output", valueDescription = "", description = "Output file path") - var outputFile: String? by FreezableVar(null) + var outputFile: String? by NullableStringFreezableVar(null) @GradleOption(DefaultValues.BooleanTrueDefault::class) @Argument(value = "-no-stdlib", description = "Don't use bundled Kotlin stdlib") @@ -37,7 +37,7 @@ class K2JSCompilerArguments : CommonCompilerArguments() { valueDescription = "", description = "Paths to Kotlin libraries with .meta.js and .kjsm files, separated by system path separator" ) - var libraries: String? by FreezableVar(null) + var libraries: String? by NullableStringFreezableVar(null) @GradleOption(DefaultValues.BooleanFalseDefault::class) @Argument(value = "-source-map", description = "Generate source map") @@ -45,7 +45,7 @@ class K2JSCompilerArguments : CommonCompilerArguments() { @GradleOption(DefaultValues.StringNullDefault::class) @Argument(value = "-source-map-prefix", description = "Prefix for paths in a source map") - var sourceMapPrefix: String? by FreezableVar(null) + var sourceMapPrefix: String? by NullableStringFreezableVar(null) @Argument( value = "-source-map-base-dirs", @@ -53,7 +53,7 @@ class K2JSCompilerArguments : CommonCompilerArguments() { valueDescription = "", description = "Base directories which are used to calculate relative paths to source files in source map" ) - var sourceMapBaseDirs: String? by FreezableVar(null) + var sourceMapBaseDirs: String? by NullableStringFreezableVar(null) @GradleOption(DefaultValues.JsSourceMapContentModes::class) @Argument( @@ -61,7 +61,7 @@ class K2JSCompilerArguments : CommonCompilerArguments() { valueDescription = "{ always, never, inlining }", description = "Embed source files into source map" ) - var sourceMapEmbedSources: String? by FreezableVar(null) + var sourceMapEmbedSources: String? by NullableStringFreezableVar(K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_INLINING) @GradleOption(DefaultValues.BooleanTrueDefault::class) @Argument(value = "-meta-info", description = "Generate .meta.js and .kjsm files with metadata. Use to create a library") @@ -69,7 +69,7 @@ class K2JSCompilerArguments : CommonCompilerArguments() { @GradleOption(DefaultValues.JsEcmaVersions::class) @Argument(value = "-target", valueDescription = "{ v5 }", description = "Generate JS files for specific ECMA version") - var target: String? by FreezableVar(null) + var target: String? by NullableStringFreezableVar(null) @GradleOption(DefaultValues.JsModuleKinds::class) @Argument( @@ -77,25 +77,25 @@ class K2JSCompilerArguments : CommonCompilerArguments() { valueDescription = "{ plain, amd, commonjs, umd }", description = "Kind of a module generated by compiler" ) - var moduleKind: String? by FreezableVar(K2JsArgumentConstants.MODULE_PLAIN) + var moduleKind: String? by NullableStringFreezableVar(K2JsArgumentConstants.MODULE_PLAIN) @GradleOption(DefaultValues.JsMain::class) @Argument(value = "-main", valueDescription = "{$CALL,$NO_CALL}", description = "Whether a main function should be called") - var main: String? by FreezableVar(null) + var main: String? by NullableStringFreezableVar(null) @Argument( value = "-output-prefix", valueDescription = "", description = "Path to file which will be added to the beginning of output file" ) - var outputPrefix: String? by FreezableVar(null) + var outputPrefix: String? by NullableStringFreezableVar(null) @Argument( value = "-output-postfix", valueDescription = "", description = "Path to file which will be added to the end of output file" ) - var outputPostfix: String? by FreezableVar(null) + var outputPostfix: String? by NullableStringFreezableVar(null) // Advanced options @@ -112,5 +112,5 @@ class K2JSCompilerArguments : CommonCompilerArguments() { valueDescription = "", description = "Paths to friend modules" ) - var friendModules: String? by FreezableVar(null) + var friendModules: String? by NullableStringFreezableVar(null) } diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSDceArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSDceArguments.kt index 2d98fe27bf6..7e747490e9a 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSDceArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSDceArguments.kt @@ -27,7 +27,7 @@ class K2JSDceArguments : CommonToolArguments() { description = "Output directory" ) @GradleOption(DefaultValues.StringNullDefault::class) - var outputDirectory: String? by FreezableVar(null) + var outputDirectory: String? by NullableStringFreezableVar(null) @Argument( value = "-keep", diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt index dfd060fc498..4ecb49dbba5 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt @@ -16,10 +16,10 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { } @Argument(value = "-d", valueDescription = "", description = "Destination for generated class files") - var destination: String? by FreezableVar(null) + var destination: String? by NullableStringFreezableVar(null) @Argument(value = "-classpath", shortName = "-cp", valueDescription = "", description = "Paths where to find user class files") - var classpath: String? by FreezableVar(null) + var classpath: String? by NullableStringFreezableVar(null) @GradleOption(DefaultValues.BooleanFalseDefault::class) @Argument(value = "-include-runtime", description = "Include Kotlin runtime in to resulting .jar") @@ -31,7 +31,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { valueDescription = "", description = "Path to JDK home directory to include into classpath, if differs from default JAVA_HOME" ) - var jdkHome: String? by FreezableVar(null) + var jdkHome: String? by NullableStringFreezableVar(null) @GradleOption(DefaultValues.BooleanFalseDefault::class) @Argument(value = "-no-jdk", description = "Don't include Java runtime into classpath") @@ -56,7 +56,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { var scriptTemplates: Array? by FreezableVar(null) @Argument(value = "-module-name", valueDescription = "", description = "Name of the generated .kotlin_module file") - var moduleName: String? by FreezableVar(null) + var moduleName: String? by NullableStringFreezableVar(null) @GradleOption(DefaultValues.JvmTargetVersions::class) @Argument( @@ -64,7 +64,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { valueDescription = "", description = "Target version of the generated JVM bytecode (1.6 or 1.8), default is 1.6" ) - var jvmTarget: String? by FreezableVar(JvmTarget.DEFAULT.description) + var jvmTarget: String? by NullableStringFreezableVar(JvmTarget.DEFAULT.description) @GradleOption(DefaultValues.BooleanFalseDefault::class) @Argument(value = "-java-parameters", description = "Generate metadata for Java 1.8 reflection on method parameters") @@ -76,7 +76,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { var useIR: Boolean by FreezableVar(false) @Argument(value = "-Xmodule-path", valueDescription = "", description = "Paths where to find Java 9+ modules") - var javaModulePath: String? by FreezableVar(null) + var javaModulePath: String? by NullableStringFreezableVar(null) @Argument( value = "-Xadd-modules", @@ -112,7 +112,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { valueDescription = "{disable|enable}", description = "Normalize constructor calls (disable: don't normalize; enable: normalize), default is disable" ) - var constructorCallNormalizationMode: String? by FreezableVar(null) + var constructorCallNormalizationMode: String? by NullableStringFreezableVar(null) @Argument( value = "-Xassertions", valueDescription = "{always-enable|always-disable|jvm|legacy}", @@ -123,7 +123,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { "-Xassertions=legacy: calculate condition on each call, check depends on jvm assertion settings in the kotlin package;\n" + "default: legacy" ) - var assertionsMode: String? by FreezableVar(JVMAssertionsMode.DEFAULT.description) + var assertionsMode: String? by NullableStringFreezableVar(JVMAssertionsMode.DEFAULT.description) @Argument( value = "-Xbuild-file", @@ -131,7 +131,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { valueDescription = "", description = "Path to the .xml build file to compile" ) - var buildFile: String? by FreezableVar(null) + var buildFile: String? by NullableStringFreezableVar(null) @Argument(value = "-Xmultifile-parts-inherit", description = "Compile multifile classes as a hierarchy of parts and facade") var inheritMultifileParts: Boolean by FreezableVar(false) @@ -157,7 +157,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { valueDescription = "", description = "Path to JSON file to dump Java to Kotlin declaration mappings" ) - var declarationsOutputPath: String? by FreezableVar(null) + var declarationsOutputPath: String? by NullableStringFreezableVar(null) @Argument(value = "-Xsingle-module", description = "Combine modules for source files and binary dependencies into a single module") var singleModule: Boolean by FreezableVar(false) @@ -218,7 +218,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { description = "Specify behavior for Checker Framework compatqual annotations (NullableDecl/NonNullDecl).\n" + "Default value is 'enable'" ) - var supportCompatqualCheckerFrameworkAnnotations: String? by FreezableVar(null) + var supportCompatqualCheckerFrameworkAnnotations: String? by NullableStringFreezableVar(null) @Argument( value = "-Xno-exception-on-explicit-equals-for-boxed-null", diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.kt index 7d28460a90f..be7c3f83ac9 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.kt @@ -22,7 +22,7 @@ class K2MetadataCompilerArguments : CommonCompilerArguments() { } @Argument(value = "-d", valueDescription = "", description = "Destination for generated .kotlin_metadata files") - var destination: String? by FreezableVar(null) + var destination: String? by NullableStringFreezableVar(null) @Argument( value = "-classpath", @@ -30,10 +30,10 @@ class K2MetadataCompilerArguments : CommonCompilerArguments() { valueDescription = "", description = "Paths where to find library .kotlin_metadata files" ) - var classpath: String? by FreezableVar(null) + var classpath: String? by NullableStringFreezableVar(null) @Argument(value = "-module-name", valueDescription = "", description = "Name of the generated .kotlin_module file") - var moduleName: String? by FreezableVar(null) + var moduleName: String? by NullableStringFreezableVar(null) @Argument( value = "-Xjps", diff --git a/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/compiler.xml b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/compiler.xml new file mode 100644 index 00000000000..1c358218b27 --- /dev/null +++ b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/copyright/profiles_settings.xml b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/copyright/profiles_settings.xml new file mode 100644 index 00000000000..e7bedf3377d --- /dev/null +++ b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/libraries/KotlinJavaRuntime.xml b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/libraries/KotlinJavaRuntime.xml new file mode 100644 index 00000000000..bcc4ed94e22 --- /dev/null +++ b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/libraries/KotlinJavaRuntime.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/misc.xml b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/misc.xml new file mode 100644 index 00000000000..5a967a62c8a --- /dev/null +++ b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/modules.xml b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/modules.xml new file mode 100644 index 00000000000..83db3b6328a --- /dev/null +++ b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/lib/kotlin-runtime.jar b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/lib/kotlin-runtime.jar new file mode 100644 index 00000000000..a4ef023c369 Binary files /dev/null and b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/lib/kotlin-runtime.jar differ diff --git a/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/module.iml b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/module.iml new file mode 100644 index 00000000000..94371e52a2a --- /dev/null +++ b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/module.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/src/foo.kt b/idea/testData/configuration/noKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings/src/foo.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt index 62f47fa44f1..becddbb71a2 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt @@ -22,6 +22,7 @@ import com.intellij.openapi.util.io.FileUtil import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider import org.jetbrains.kotlin.config.LanguageVersion +import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JsCompilerArgumentsHolder import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder import org.jetbrains.kotlin.idea.project.getLanguageVersionSettings import org.jetbrains.kotlin.idea.project.languageVersionSettings @@ -112,6 +113,17 @@ open class ConfigureKotlinInTempDirTest : AbstractConfigureKotlinInTempDirTest() Assert.assertEquals(ApiVersion.KOTLIN_1_1, settings.apiVersion) } + fun testNoKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings() { + val application = ApplicationManager.getApplication() as ApplicationImpl + application.isSaveAllowed = true + Kotlin2JsCompilerArgumentsHolder.getInstance(project).update { + sourceMapPrefix = "" + sourceMapEmbedSources = "" + } + application.saveAll() + Assert.assertTrue(project.baseDir.findFileByRelativePath(".idea/kotlinc.xml") == null) + } + //todo[Sedunov]: wait for fix in platform to avoid misunderstood from Java newbies (also PluginStartupComponent) /*fun testKotlinSdkAdded() { Assert.assertTrue(ProjectJdkTable.getInstance().allJdks.any { it.sdkType is KotlinSdkType }) diff --git a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt.173 b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt.173 index d4eb4b8ce50..88f2b67b33f 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt.173 +++ b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInTempDirTest.kt.173 @@ -109,6 +109,17 @@ open class ConfigureKotlinInTempDirTest : AbstractConfigureKotlinInTempDirTest() Assert.assertEquals(ApiVersion.KOTLIN_1_1, settings.apiVersion) } + fun testNoKotlincExistsNoSettingsLatestRuntimeNullizeEmptyStrings() { + val application = ApplicationManager.getApplication() as ApplicationImpl + application.doNotSave(false) + Kotlin2JsCompilerArgumentsHolder.getInstance(project).update { + sourceMapPrefix = "" + sourceMapEmbedSources = "" + } + application.saveAll() + Assert.assertTrue(project.baseDir.findFileByRelativePath(".idea/kotlinc.xml") == null) + } + //todo[Sedunov]: wait for fix in platform to avoid misunderstood from Java newbies (also PluginStartupComponent) /*fun testKotlinSdkAdded() { Assert.assertTrue(ProjectJdkTable.getInstance().allJdks.any { it.sdkType is KotlinSdkType })