diff --git a/idea/idea-analysis/resources/org/jetbrains/kotlin/idea/KotlinBundle.properties b/idea/idea-analysis/resources/org/jetbrains/kotlin/idea/KotlinBundle.properties index 531a9421097..3c11c0b6a01 100644 --- a/idea/idea-analysis/resources/org/jetbrains/kotlin/idea/KotlinBundle.properties +++ b/idea/idea-analysis/resources/org/jetbrains/kotlin/idea/KotlinBundle.properties @@ -223,6 +223,7 @@ add.script.runtime.to.classpath=Add kotlin-script-runtime.jar to the classpath kotlin.compiler.option.generate.no.warnings=Report compiler &warnings kotlin.compiler.option.additional.command.line.parameters=&Additional command line parameters: kotlin.compiler.option.additional.command.line.parameters.dialog.title=Additional command line parameters +kotlin.compiler.option.enable.new.inference.in.ide=Enable new type inference algorithm for IDE analysis (experimental) # Kotlin to JVM kotlin.compiler.jvm.option.panel.title=Kotlin to JVM @@ -252,3 +253,4 @@ android.klint.inspections.group.name=Android Lint for Kotlin scratch.run.button=Run Scratch File scratch.stop.button=Stop scratch execution scratch.clear.button=Clear results + diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/NewInferenceForIDEAnalysisComponent.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/NewInferenceForIDEAnalysisComponent.kt new file mode 100644 index 00000000000..c78aa957449 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/NewInferenceForIDEAnalysisComponent.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.project + +import com.intellij.ide.util.PropertiesComponent +import com.intellij.openapi.project.Project + +object NewInferenceForIDEAnalysisComponent { + private const val inferenceOption = "kotlin.use.new.inference.for.ide.analysis" + private const val defaultState = false + + @JvmStatic + fun setEnabled(project: Project, state: Boolean) { + PropertiesComponent.getInstance(project).setValue(inferenceOption, state, defaultState) + } + + @JvmStatic + fun isEnabled(project: Project): Boolean { + return PropertiesComponent.getInstance(project).getBoolean(inferenceOption, defaultState) + } +} \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt index 56abe973a5d..d396015956c 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt @@ -24,6 +24,7 @@ import com.intellij.openapi.roots.ProjectFileIndex import com.intellij.openapi.roots.ProjectRootModificationTracker import com.intellij.openapi.util.Key import com.intellij.openapi.util.io.FileUtil +import com.intellij.openapi.util.registry.Registry import com.intellij.psi.PsiElement import com.intellij.psi.util.CachedValue import com.intellij.psi.util.CachedValueProvider @@ -138,6 +139,7 @@ fun Project.getLanguageVersionSettings( CoroutineSupport.byCompilerArguments(KotlinCommonCompilerArgumentsHolder.getInstance(this@getLanguageVersionSettings).settings), languageVersion ) + configureNewInferenceSupportInIDE(this@getLanguageVersionSettings) if (isReleaseCoroutines != null) { put( LanguageFeature.ReleaseCoroutines, @@ -194,6 +196,7 @@ private fun Module.computeLanguageVersionSettings(): LanguageVersionSettings { val languageFeatures = facetSettings.mergedCompilerArguments?.configureLanguageFeatures(MessageCollector.NONE)?.apply { configureCoroutinesSupport(facetSettings.coroutineSupport, languageVersion) configureMultiplatformSupport(facetSettings.platform?.kind, this@computeLanguageVersionSettings) + configureNewInferenceSupportInIDE(project) }.orEmpty() val analysisFlags = facetSettings.mergedCompilerArguments?.configureAnalysisFlags(MessageCollector.NONE).orEmpty() @@ -248,6 +251,13 @@ fun MutableMap.configureMultiplatformSup } } +fun MutableMap.configureNewInferenceSupportInIDE( + project: Project +) { + if (NewInferenceForIDEAnalysisComponent.isEnabled(project)) { + putIfAbsent(LanguageFeature.NewInference, LanguageFeature.State.ENABLED) + } +} val PsiElement.languageVersionSettings: LanguageVersionSettings get() { diff --git a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.form b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.form index ad2fbd6d884..21590f996e1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.form +++ b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.form @@ -1,6 +1,6 @@
- + @@ -12,13 +12,13 @@ - + - + @@ -153,7 +153,7 @@ - + @@ -229,7 +229,7 @@ - + @@ -286,7 +286,7 @@ - + @@ -310,7 +310,7 @@ - + @@ -334,7 +334,7 @@ - + @@ -357,7 +357,7 @@ - + @@ -365,7 +365,7 @@ - + @@ -373,13 +373,33 @@ - + + + + + + + + + + + + + + + + + + + + + diff --git a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java index 11c7e693dca..ea81ca3df89 100644 --- a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java +++ b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java @@ -36,8 +36,10 @@ import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants; import org.jetbrains.kotlin.config.*; import org.jetbrains.kotlin.idea.KotlinBundle; import org.jetbrains.kotlin.idea.PluginStartupComponent; +import org.jetbrains.kotlin.idea.configuration.ProjectUtilsKt; import org.jetbrains.kotlin.idea.facet.DescriptionListCellRenderer; import org.jetbrains.kotlin.idea.facet.KotlinFacet; +import org.jetbrains.kotlin.idea.project.NewInferenceForIDEAnalysisComponent; import org.jetbrains.kotlin.idea.roots.RootUtilsKt; import org.jetbrains.kotlin.idea.util.CidrUtil; import org.jetbrains.kotlin.idea.util.application.ApplicationUtilsKt; @@ -110,6 +112,7 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co private JLabel labelForSourceMapPrefix; private JComboBox sourceMapEmbedSources; private JPanel coroutinesPanel; + private ThreeStateCheckBox enableNewInferenceInIDECheckBox; private boolean isEnabled = true; public KotlinCompilerConfigurableTab( @@ -150,6 +153,7 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co } reportWarningsCheckBox.setThirdStateEnabled(isMultiEditor); + enableNewInferenceInIDECheckBox.setThirdStateEnabled(isMultiEditor); if (isProjectSettings) { List modulesOverridingProjectSettings = ArraysKt.mapNotNull( @@ -207,6 +211,7 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co keepAliveCheckBox.setVisible(false); k2jvmPanel.setVisible(false); enableIncrementalCompilationForJsCheckBox.setVisible(false); + enableNewInferenceInIDECheckBox.setVisible(false); } updateOutputDirEnabled(); @@ -438,6 +443,7 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co @Override public boolean isModified() { return isModified(reportWarningsCheckBox, !commonCompilerArguments.getSuppressWarnings()) || + isModified(enableNewInferenceInIDECheckBox, NewInferenceForIDEAnalysisComponent.isEnabled(project)) || !getSelectedLanguageVersionView().equals(KotlinFacetSettingsKt.getLanguageVersionView(commonCompilerArguments)) || !getSelectedAPIVersionView().equals(KotlinFacetSettingsKt.getApiVersionView(commonCompilerArguments)) || !getSelectedCoroutineState().equals(commonCompilerArguments.getCoroutinesState()) || @@ -515,7 +521,8 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co !getSelectedLanguageVersionView().equals(KotlinFacetSettingsKt.getLanguageVersionView(commonCompilerArguments)) || !getSelectedAPIVersionView().equals(KotlinFacetSettingsKt.getApiVersionView(commonCompilerArguments)) || !getSelectedCoroutineState().equals(commonCompilerArguments.getCoroutinesState()) || - !additionalArgsOptionsField.getText().equals(compilerSettings.getAdditionalArguments()); + !additionalArgsOptionsField.getText().equals(compilerSettings.getAdditionalArguments()) || + enableNewInferenceInIDECheckBox.isSelected() != NewInferenceForIDEAnalysisComponent.isEnabled(project); if (shouldInvalidateCaches) { ApplicationUtilsKt.runWriteAction( @@ -531,6 +538,7 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co } commonCompilerArguments.setSuppressWarnings(!reportWarningsCheckBox.isSelected()); + NewInferenceForIDEAnalysisComponent.setEnabled(project, enableNewInferenceInIDECheckBox.isSelected()); KotlinFacetSettingsKt.setLanguageVersionView(commonCompilerArguments, getSelectedLanguageVersionView()); KotlinFacetSettingsKt.setApiVersionView(commonCompilerArguments, getSelectedAPIVersionView()); @@ -583,6 +591,7 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co @Override public void reset() { reportWarningsCheckBox.setSelected(!commonCompilerArguments.getSuppressWarnings()); + enableNewInferenceInIDECheckBox.setSelected(NewInferenceForIDEAnalysisComponent.isEnabled(project)); languageVersionComboBox.setSelectedItem(KotlinFacetSettingsKt.getLanguageVersionView(commonCompilerArguments)); onLanguageLevelChanged(getSelectedLanguageVersionView()); apiVersionComboBox.setSelectedItem(KotlinFacetSettingsKt.getApiVersionView(commonCompilerArguments)); @@ -635,6 +644,10 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co return reportWarningsCheckBox; } + public ThreeStateCheckBox getEnableNewInferenceInIDECheckBox() { + return enableNewInferenceInIDECheckBox; + } + public RawCommandLineEditor getAdditionalArgsOptionsField() { return additionalArgsOptionsField; } diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/projectUtils.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/projectUtils.kt index bbb41c3372d..df3e35d5b97 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/projectUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/projectUtils.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.idea.configuration import com.intellij.openapi.module.Module +import com.intellij.openapi.util.registry.Registry import com.intellij.psi.search.FileTypeIndex import org.jetbrains.kotlin.idea.KotlinFileType @@ -15,4 +16,4 @@ fun hasKotlinFilesOnlyInTests(module: Module): Boolean { fun hasKotlinFilesInSources(module: Module): Boolean { return FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, module.getModuleScope(false)) -} \ No newline at end of file +} diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/MultipleKotlinFacetEditor.kt b/idea/src/org/jetbrains/kotlin/idea/facet/MultipleKotlinFacetEditor.kt index 134fc832de8..c57ad924574 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/MultipleKotlinFacetEditor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/MultipleKotlinFacetEditor.kt @@ -44,6 +44,7 @@ class MultipleKotlinFacetEditor( helper.bind(targetPlatformComboBox, editors) { it.tabEditor.targetPlatformComboBox } with(compilerConfigurable) { helper.bind(reportWarningsCheckBox, editors) { it.compilerConfigurable.reportWarningsCheckBox } + helper.bind(enableNewInferenceInIDECheckBox, editors) { it.compilerConfigurable.enableNewInferenceInIDECheckBox } helper.bind(additionalArgsOptionsField.textField, editors) { it.compilerConfigurable.additionalArgsOptionsField.textField } helper.bind(generateSourceMapsCheckBox, editors) { it.compilerConfigurable.generateSourceMapsCheckBox} helper.bind(outputPrefixFile.textField, editors) { it.compilerConfigurable.outputPrefixFile.textField } diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt index 80563561f5e..1bcda00d3a0 100644 --- a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt @@ -20,6 +20,7 @@ import com.google.common.collect.Lists import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil.toSystemIndependentName import com.intellij.openapi.util.io.FileUtilRt +import com.intellij.openapi.util.registry.Registry import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.vfs.StandardFileSystems import com.intellij.testFramework.LightVirtualFile @@ -707,6 +708,34 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() { result.assertSuccessful() } + /* + * Here we're checking that enabling inference in IDE doesn't affect compilation via JPS + * + * the following two tests are connected: + * - testKotlinProjectWithEnabledNewInferenceInIDE checks that project is compiled when new inference is enabled only in IDE + * - this is done via project component + * - testKotlinProjectWithErrorsBecauseOfNewInference checks that project isn't compiled when new inference is enabled in the compiler + * + * So, if the former will fail => option affects JPS compilation, it's bad. Also, if the latter test fails => test is useless as it's + * compiled with new and old inference. + * + */ + fun testKotlinProjectWithEnabledNewInferenceInIDE() { + doTest() + } + + fun testKotlinProjectWithErrorsBecauseOfNewInference() { + initProject(JVM_MOCK_RUNTIME) + val module = myProject.modules.single() + val args = module.kotlinCompilerArguments + args.newInference = true + myProject.kotlinCommonCompilerArguments = args + + val result = buildAllModules() + result.assertFailed() + result.checkErrors() + } + private fun createKotlinJavaScriptLibraryArchive() { val jarFile = File(workDir, KOTLIN_JS_LIBRARY_JAR) try { diff --git a/jps-plugin/testData/general/KotlinProjectWithEnabledNewInferenceInIDE/kotlinProject.iml b/jps-plugin/testData/general/KotlinProjectWithEnabledNewInferenceInIDE/kotlinProject.iml new file mode 100644 index 00000000000..a0cbe548242 --- /dev/null +++ b/jps-plugin/testData/general/KotlinProjectWithEnabledNewInferenceInIDE/kotlinProject.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/jps-plugin/testData/general/KotlinProjectWithEnabledNewInferenceInIDE/kotlinProject.ipr b/jps-plugin/testData/general/KotlinProjectWithEnabledNewInferenceInIDE/kotlinProject.ipr new file mode 100644 index 00000000000..f04957c330e --- /dev/null +++ b/jps-plugin/testData/general/KotlinProjectWithEnabledNewInferenceInIDE/kotlinProject.ipr @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jps-plugin/testData/general/KotlinProjectWithEnabledNewInferenceInIDE/src/test1.kt b/jps-plugin/testData/general/KotlinProjectWithEnabledNewInferenceInIDE/src/test1.kt new file mode 100644 index 00000000000..5f41546490a --- /dev/null +++ b/jps-plugin/testData/general/KotlinProjectWithEnabledNewInferenceInIDE/src/test1.kt @@ -0,0 +1,5 @@ +fun foo() { + ByteArray(42) { + when (Any()) {} + } +} \ No newline at end of file diff --git a/jps-plugin/testData/general/KotlinProjectWithErrorsBecauseOfNewInference/errors.txt b/jps-plugin/testData/general/KotlinProjectWithErrorsBecauseOfNewInference/errors.txt new file mode 100644 index 00000000000..df2e59d5fe9 --- /dev/null +++ b/jps-plugin/testData/general/KotlinProjectWithErrorsBecauseOfNewInference/errors.txt @@ -0,0 +1 @@ +Type mismatch: inferred type is Unit but Byte was expected at line 3, column 9 diff --git a/jps-plugin/testData/general/KotlinProjectWithErrorsBecauseOfNewInference/kotlinProject.iml b/jps-plugin/testData/general/KotlinProjectWithErrorsBecauseOfNewInference/kotlinProject.iml new file mode 100644 index 00000000000..a0cbe548242 --- /dev/null +++ b/jps-plugin/testData/general/KotlinProjectWithErrorsBecauseOfNewInference/kotlinProject.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/jps-plugin/testData/general/KotlinProjectWithErrorsBecauseOfNewInference/kotlinProject.ipr b/jps-plugin/testData/general/KotlinProjectWithErrorsBecauseOfNewInference/kotlinProject.ipr new file mode 100644 index 00000000000..90747786771 --- /dev/null +++ b/jps-plugin/testData/general/KotlinProjectWithErrorsBecauseOfNewInference/kotlinProject.ipr @@ -0,0 +1,14 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/jps-plugin/testData/general/KotlinProjectWithErrorsBecauseOfNewInference/src/test1.kt b/jps-plugin/testData/general/KotlinProjectWithErrorsBecauseOfNewInference/src/test1.kt new file mode 100644 index 00000000000..5f41546490a --- /dev/null +++ b/jps-plugin/testData/general/KotlinProjectWithErrorsBecauseOfNewInference/src/test1.kt @@ -0,0 +1,5 @@ +fun foo() { + ByteArray(42) { + when (Any()) {} + } +} \ No newline at end of file