Kotlin Facet: Add coroutine support setting

This commit is contained in:
Alexey Sedunov
2016-12-12 15:27:47 +03:00
committed by Stanislav Erokhin
parent 664485f4bb
commit 9460426d26
6 changed files with 166 additions and 80 deletions
@@ -79,6 +79,10 @@ public abstract class CommonCompilerArguments {
@Argument(value = "Xcoroutines=enable")
public boolean coroutinesEnable;
@Argument(value = "Xcoroutine-support", description = "Coroutines: produce error/warning/compile silently")
// Possible values: "enabled", "warning", "disabled"
public String coroutineSupport;
@Argument(value = "P", description = "Pass an option to a plugin")
@ValueDescription(PLUGIN_OPTION_FORMAT)
public String[] pluginOptions;
@@ -61,6 +61,22 @@ data class KotlinVersionInfo(
}
}
enum class CoroutineSupport(
override val description: String,
val compilerArgument: String
) : DescriptionAware {
ENABLED("Enabled", "enabled"),
ENABLED_WITH_WARNING("Enabled with warning", "warning"),
DISABLED("Disabled", "disabled");
companion object {
val DEFAULT = ENABLED_WITH_WARNING
@JvmStatic fun byCompilerArgument(value: String?) = CoroutineSupport.values().firstOrNull { it.compilerArgument == value }
?: CoroutineSupport.DEFAULT
}
}
class KotlinCompilerInfo {
// To be serialized
@Property private var _commonCompilerArguments: CommonCompilerArguments.DummyImpl? = null
@@ -71,6 +87,12 @@ class KotlinCompilerInfo {
}
var k2jsCompilerArguments: K2JSCompilerArguments? = null
var compilerSettings: CompilerSettings? = null
@get:Transient var coroutineSupport: CoroutineSupport
get() = CoroutineSupport.byCompilerArgument(commonCompilerArguments?.coroutineSupport)
set(value) {
commonCompilerArguments?.coroutineSupport = value.compilerArgument
}
}
class KotlinFacetSettings {
@@ -13,7 +13,7 @@
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="27e96" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27e96" layout-manager="GridLayoutManager" row-count="7" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
@@ -32,7 +32,7 @@
</component>
<component id="ba279" class="javax.swing.JLabel" binding="additionalArgsLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="org/jetbrains/kotlin/idea/KotlinBundle" key="kotlin.compiler.option.additional.command.line.parameters"/>
@@ -40,7 +40,7 @@
</component>
<component id="7a827" class="com.intellij.ui.RawCommandLineEditor" binding="additionalArgsOptionsField">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
@@ -50,7 +50,7 @@
</component>
<component id="c45a6" class="javax.swing.JCheckBox" binding="keepAliveCheckBox">
<constraints>
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="4" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Keep compiler process alive between invocations"/>
@@ -58,7 +58,7 @@
</component>
<component id="ae60b" class="javax.swing.JLabel" binding="scriptTemplatesLabel">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="1" use-parent-layout="false"/>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="1" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="71c3f"/>
@@ -67,7 +67,7 @@
</component>
<component id="71c3f" class="javax.swing.JTextField" binding="scriptTemplatesField">
<constraints>
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="1" use-parent-layout="false">
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="1" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
@@ -75,7 +75,7 @@
</component>
<component id="56390" class="javax.swing.JLabel" binding="scriptTemplatesClasspathLabel">
<constraints>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="1" use-parent-layout="false"/>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="1" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="644d9"/>
@@ -84,7 +84,7 @@
</component>
<component id="644d9" class="javax.swing.JTextField" binding="scriptTemplatesClasspathField">
<constraints>
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="1" use-parent-layout="false">
<grid row="6" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="1" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
@@ -116,6 +116,32 @@
</component>
</children>
</grid>
<grid id="6b551" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="12453" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
<preferred-size width="201" height="16"/>
</grid>
</constraints>
<properties>
<text value="Coro&amp;utines (experimental)"/>
</properties>
</component>
<component id="4cb8f" class="javax.swing.JComboBox" binding="coroutineSupportComboBox">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
</children>
</grid>
</children>
</grid>
<grid id="2f977" binding="k2jvmPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -36,12 +36,10 @@ import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments;
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments;
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments;
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants;
import org.jetbrains.kotlin.config.CompilerSettings;
import org.jetbrains.kotlin.config.JvmTarget;
import org.jetbrains.kotlin.config.LanguageVersion;
import org.jetbrains.kotlin.config.TargetPlatformKind;
import org.jetbrains.kotlin.config.*;
import org.jetbrains.kotlin.idea.KotlinBundle;
import org.jetbrains.kotlin.idea.PluginStartupComponent;
import org.jetbrains.kotlin.idea.facet.DescriptionListCellRenderer;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
@@ -51,6 +49,14 @@ import java.util.Map;
public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Configurable.NoScroll{
private static final Map<String, String> moduleKindDescriptions = new LinkedHashMap<String, String>();
static {
moduleKindDescriptions.put(K2JsArgumentConstants.MODULE_PLAIN, "Plain (put to global scope)");
moduleKindDescriptions.put(K2JsArgumentConstants.MODULE_AMD, "AMD");
moduleKindDescriptions.put(K2JsArgumentConstants.MODULE_COMMONJS, "CommonJS");
moduleKindDescriptions.put(K2JsArgumentConstants.MODULE_UMD, "UMD (detect AMD or CommonJS if available, fallback to plain)");
}
private final CommonCompilerArguments commonCompilerArguments;
private final K2JSCompilerArguments k2jsCompilerArguments;
private final K2JVMCompilerArguments k2jvmCompilerArguments;
@@ -83,13 +89,7 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co
private JComboBox jvmVersionComboBox;
private JComboBox languageVersionComboBox;
private JPanel languageVersionPanel;
static {
moduleKindDescriptions.put(K2JsArgumentConstants.MODULE_PLAIN, "Plain (put to global scope)");
moduleKindDescriptions.put(K2JsArgumentConstants.MODULE_AMD, "AMD");
moduleKindDescriptions.put(K2JsArgumentConstants.MODULE_COMMONJS, "CommonJS");
moduleKindDescriptions.put(K2JsArgumentConstants.MODULE_UMD, "UMD (detect AMD or CommonJS if available, fallback to plain)");
}
private JComboBox coroutineSupportComboBox;
public KotlinCompilerConfigurableTab(
Project project,
@@ -131,6 +131,7 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co
fillModuleKindList();
fillJvmVersionList();
fillLanguageVersionList();
fillCoroutineSupportList();
if (compilerWorkspaceSettings == null) {
keepAliveCheckBox.setVisible(false);
@@ -138,6 +139,56 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co
}
}
@SuppressWarnings("unused")
public KotlinCompilerConfigurableTab(Project project) {
this(project,
KotlinCommonCompilerArgumentsHolder.getInstance(project).getSettings(),
Kotlin2JsCompilerArgumentsHolder.getInstance(project).getSettings(),
KotlinCompilerSettings.getInstance(project).getSettings(),
ServiceManager.getService(project, KotlinCompilerWorkspaceSettings.class),
Kotlin2JvmCompilerArgumentsHolder.getInstance(project).getSettings(),
true);
}
@NotNull
private static String getModuleKindDescription(@NotNull String moduleKind) {
String result = moduleKindDescriptions.get(moduleKind);
assert result != null : "Module kind " + moduleKind + " was not added to combobox, therefore it should not be here";
return result;
}
@NotNull
private static String getModuleKindOrDefault(@Nullable String moduleKindId) {
if (moduleKindId == null) {
moduleKindId = K2JsArgumentConstants.MODULE_PLAIN;
}
return moduleKindId;
}
private static String getJvmVersionOrDefault(@Nullable String jvmVersion) {
return jvmVersion != null ? jvmVersion : JvmTarget.DEFAULT.getDescription();
}
private static String getLanguageVersionOrDefault(@Nullable String languageVersion) {
return languageVersion != null ? languageVersion : LanguageVersion.LATEST.getVersionString();
}
private static void setupFileChooser(
@NotNull JLabel label,
@NotNull TextFieldWithBrowseButton fileChooser,
@NotNull String title
) {
label.setLabelFor(fileChooser);
fileChooser.addBrowseFolderListener(title, null, null,
new FileChooserDescriptor(true, false, false, false, false, false),
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT, false);
}
private static boolean isModified(@NotNull TextFieldWithBrowseButton chooser, @Nullable String currentValue) {
return !StringUtil.equals(StringUtil.nullize(chooser.getText(), true), currentValue);
}
@SuppressWarnings("unchecked")
private void fillJvmVersionList() {
jvmVersionComboBox.addItem(TargetPlatformKind.Jvm.JVM_1_6.INSTANCE.getVersion().getDescription());
@@ -150,19 +201,16 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co
}
}
public void setTargetPlatform(@Nullable TargetPlatformKind<?> targetPlatform) {
k2jsPanel.setVisible(TargetPlatformKind.JavaScript.INSTANCE.equals(targetPlatform));
@SuppressWarnings("unchecked")
private void fillCoroutineSupportList() {
for (CoroutineSupport coroutineSupport : CoroutineSupport.values()) {
coroutineSupportComboBox.addItem(coroutineSupport);
}
coroutineSupportComboBox.setRenderer(new DescriptionListCellRenderer());
}
@SuppressWarnings("unused")
public KotlinCompilerConfigurableTab(Project project) {
this(project,
KotlinCommonCompilerArgumentsHolder.getInstance(project).getSettings(),
Kotlin2JsCompilerArgumentsHolder.getInstance(project).getSettings(),
KotlinCompilerSettings.getInstance(project).getSettings(),
ServiceManager.getService(project, KotlinCompilerWorkspaceSettings.class),
Kotlin2JvmCompilerArgumentsHolder.getInstance(project).getSettings(),
true);
public void setTargetPlatform(@Nullable TargetPlatformKind<?> targetPlatform) {
k2jsPanel.setVisible(TargetPlatformKind.JavaScript.INSTANCE.equals(targetPlatform));
}
@SuppressWarnings("unchecked")
@@ -178,13 +226,6 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co
});
}
@NotNull
private static String getModuleKindDescription(@NotNull String moduleKind) {
String result = moduleKindDescriptions.get(moduleKind);
assert result != null : "Module kind " + moduleKind + " was not added to combobox, therefore it should not be here";
return result;
}
@NotNull
@Override
public String getId() {
@@ -207,6 +248,7 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co
public boolean isModified() {
return ComparingUtils.isModified(generateNoWarningsCheckBox, commonCompilerArguments.suppressWarnings) ||
(showLanguageVersion && !getSelectedLanguageVersion().equals(getLanguageVersionOrDefault(commonCompilerArguments.languageVersion))) ||
!coroutineSupportComboBox.getSelectedItem().equals(CoroutineSupport.byCompilerArgument(k2jsCompilerArguments.moduleKind)) ||
ComparingUtils.isModified(additionalArgsOptionsField, compilerSettings.getAdditionalArguments()) ||
ComparingUtils.isModified(scriptTemplatesField, compilerSettings.getScriptTemplates()) ||
ComparingUtils.isModified(scriptTemplatesClasspathField, compilerSettings.getScriptTemplatesClasspath()) ||
@@ -245,6 +287,7 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co
if (showLanguageVersion) {
commonCompilerArguments.languageVersion = getSelectedLanguageVersion();
}
commonCompilerArguments.coroutineSupport = ((CoroutineSupport) coroutineSupportComboBox.getSelectedItem()).getCompilerArgument();
compilerSettings.setAdditionalArguments(additionalArgsOptionsField.getText());
compilerSettings.setScriptTemplates(scriptTemplatesField.getText());
compilerSettings.setScriptTemplatesClasspath(scriptTemplatesClasspathField.getText());
@@ -273,28 +316,13 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co
BuildManager.getInstance().clearState(project);
}
@NotNull
private static String getModuleKindOrDefault(@Nullable String moduleKindId) {
if (moduleKindId == null) {
moduleKindId = K2JsArgumentConstants.MODULE_PLAIN;
}
return moduleKindId;
}
private static String getJvmVersionOrDefault(@Nullable String jvmVersion) {
return jvmVersion != null ? jvmVersion : JvmTarget.DEFAULT.getDescription();
}
private static String getLanguageVersionOrDefault(@Nullable String languageVersion) {
return languageVersion != null ? languageVersion : LanguageVersion.LATEST.getVersionString();
}
@Override
public void reset() {
generateNoWarningsCheckBox.setSelected(commonCompilerArguments.suppressWarnings);
if (showLanguageVersion) {
languageVersionComboBox.setSelectedItem(getLanguageVersionOrDefault(commonCompilerArguments.languageVersion));
}
coroutineSupportComboBox.setSelectedItem(CoroutineSupport.byCompilerArgument(commonCompilerArguments.coroutineSupport));
additionalArgsOptionsField.setText(compilerSettings.getAdditionalArguments());
scriptTemplatesField.setText(compilerSettings.getScriptTemplates());
scriptTemplatesClasspathField.setText(compilerSettings.getScriptTemplatesClasspath());
@@ -332,20 +360,4 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co
public String getHelpTopic() {
return "reference.compiler.kotlin";
}
private static void setupFileChooser(
@NotNull JLabel label,
@NotNull TextFieldWithBrowseButton fileChooser,
@NotNull String title
) {
label.setLabelFor(fileChooser);
fileChooser.addBrowseFolderListener(title, null, null,
new FileChooserDescriptor(true, false, false, false, false, false),
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT, false);
}
private static boolean isModified(@NotNull TextFieldWithBrowseButton chooser, @Nullable String currentValue) {
return !StringUtil.equals(StringUtil.nullize(chooser.getText(), true), currentValue);
}
}
@@ -0,0 +1,30 @@
/*
* 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.idea.facet
import org.jetbrains.kotlin.utils.DescriptionAware
import java.awt.Component
import javax.swing.DefaultListCellRenderer
import javax.swing.JList
class DescriptionListCellRenderer : DefaultListCellRenderer() {
override fun getListCellRendererComponent(list: JList<*>?, value: Any?, index: Int, isSelected: Boolean, cellHasFocus: Boolean): Component {
return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus).apply {
text = (value as? DescriptionAware)?.description ?: ""
}
}
}
@@ -22,10 +22,10 @@ import com.intellij.facet.ui.libraries.FrameworkLibraryValidator
import com.intellij.util.ui.FormBuilder
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.TargetPlatformKind
import org.jetbrains.kotlin.utils.DescriptionAware
import java.awt.BorderLayout
import java.awt.Component
import javax.swing.*
import javax.swing.JComboBox
import javax.swing.JComponent
import javax.swing.JPanel
class KotlinFacetEditorGeneralTab(
private val configuration: KotlinFacetConfiguration,
@@ -33,14 +33,6 @@ class KotlinFacetEditorGeneralTab(
validatorsManager: FacetValidatorsManager,
private val compilerTab: KotlinFacetEditorCompilerTab
) : FacetEditorTab() {
class DescriptionListCellRenderer : DefaultListCellRenderer() {
override fun getListCellRendererComponent(list: JList<*>?, value: Any?, index: Int, isSelected: Boolean, cellHasFocus: Boolean): Component {
return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus).apply {
text = (value as? DescriptionAware)?.description ?: ""
}
}
}
inner class VersionValidator : FacetEditorValidator() {
override fun check(): ValidationResult {
val apiLevel = apiVersionComboBox.selectedItem as? LanguageVersion? ?: return ValidationResult.OK