[compiler] Use UI DSL in CompilerConfigurable

GitOrigin-RevId: 8e337ec0932da57c78ce124816e4641459235cee
This commit is contained in:
Louis Vignier
2024-03-22 17:23:46 +00:00
committed by intellij-monorepo-bot
parent 3582fa2c1b
commit 0a10bd37e2
5 changed files with 312 additions and 543 deletions
@@ -10,13 +10,13 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class CompilerConfigurable implements SearchableConfigurable.Parent, Configurable.NoScroll {
public class CompilerConfigurable implements SearchableConfigurable.Parent {
static final String CONFIGURABLE_ID = "project.propCompiler";
private final CompilerUIConfigurable myCompilerUIConfigurable;
private final CompilerUIConfigurableKt myCompilerUIConfigurable;
public CompilerConfigurable(Project project) {
myCompilerUIConfigurable = new CompilerUIConfigurable(project);
myCompilerUIConfigurable = new CompilerUIConfigurableKt(project);
}
@Override
@@ -70,7 +70,8 @@ public class CompilerConfigurable implements SearchableConfigurable.Parent, Conf
return new Configurable[0];
}
@NotNull CompilerUIConfigurable getCompilerUIConfigurable() {
@NotNull
CompilerUIConfigurableKt getCompilerUIConfigurable() {
return myCompilerUIConfigurable;
}
}
@@ -1,228 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.compiler.options.CompilerUIConfigurable">
<grid id="1663f" binding="myPanel" layout-manager="GridLayoutManager" row-count="14" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="28" y="24" width="1417" height="706"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="b341d" layout-manager="GridLayoutManager" row-count="2" 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="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="b0748" class="javax.swing.JLabel" binding="myResourcePatternsLabel">
<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"/>
</constraints>
<properties>
<labelFor value="263f1"/>
<text resource-bundle="messages/JavaCompilerBundle" key="label.option.resource.patterns.text"/>
</properties>
</component>
<component id="263f1" class="com.intellij.ui.RawCommandLineEditor" binding="myResourcePatternsField" custom-create="true">
<constraints>
<grid row="0" 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>
<properties>
<focusable value="false"/>
<text value="" noi18n="true"/>
</properties>
</component>
<component id="78174" class="com.intellij.ui.components.JBLabel" binding="myPatternLegendLabel">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="0" indent="1" use-parent-layout="false"/>
</constraints>
<properties>
<componentStyle value="SMALL"/>
<fontColor value="BRIGHTER"/>
<text value=""/>
</properties>
</component>
</children>
</grid>
<component id="889a8" class="javax.swing.JCheckBox" binding="myCbClearOutputDirectory">
<constraints>
<grid row="1" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/JavaCompilerBundle" key="label.option.clear.output.directory.on.rebuild"/>
</properties>
</component>
<component id="348ee" class="javax.swing.JCheckBox" binding="myCbAutoShowFirstError">
<constraints>
<grid row="3" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/JavaCompilerBundle" key="label.option.autoshow.first.error"/>
</properties>
</component>
<component id="b9b2d" class="javax.swing.JCheckBox" binding="myCbEnableAutomake">
<constraints>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/JavaCompilerBundle" key="settings.build.project.automatically"/>
</properties>
</component>
<component id="ba694" class="javax.swing.JCheckBox" binding="myCbParallelCompilation">
<constraints>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/JavaCompilerBundle" key="settings.compile.independent.modules.in.parallel"/>
</properties>
</component>
<component id="91979" class="javax.swing.JLabel" binding="myParallelCompilationLegendLabel">
<constraints>
<grid row="6" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/JavaCompilerBundle" key="settings.parallel.module.compile.may.require.larger.heap.size"/>
</properties>
</component>
<component id="732b1" class="javax.swing.JLabel" binding="myEnableAutomakeLegendLabel">
<constraints>
<grid row="5" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/JavaCompilerBundle" key="settings.auto.build.only.works.while.not.running"/>
</properties>
</component>
<component id="4b44" class="javax.swing.JCheckBox" binding="myCbRebuildOnDependencyChange" default-binding="true">
<constraints>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/JavaCompilerBundle" key="settings.rebuild.module.on.dependency.change"/>
</properties>
</component>
<component id="31cc6" class="javax.swing.JCheckBox" binding="myCbDisplayNotificationPopup">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/JavaCompilerBundle" key="label.option.display.notification.popup"/>
</properties>
</component>
<grid id="6ee49" binding="myAssertNotNullPanel" layout-manager="GridLayoutManager" row-count="1" column-count="3" 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="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="366e" class="javax.swing.JCheckBox" binding="myCbAssertNotNull">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/JavaCompilerBundle" key="add.notnull.assertions"/>
</properties>
</component>
<component id="73479" class="javax.swing.JButton" binding="myConfigureAnnotations">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/JavaCompilerBundle" key="settings.configure.annotations"/>
</properties>
</component>
<hspacer id="4b9fc">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
<component id="5c3dc" class="javax.swing.JLabel" binding="myWarningLabel">
<constraints>
<grid row="13" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value=""/>
</properties>
</component>
<vspacer id="60b1c">
<constraints>
<grid row="12" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="17126" class="javax.swing.JLabel" binding="mySharedHeapSizeLabel">
<constraints>
<grid row="8" 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>
<labelFor value="a28b8"/>
<text resource-bundle="messages/JavaCompilerBundle" key="settings.build.process.heap.size"/>
</properties>
</component>
<component id="a28b8" class="javax.swing.JTextField" binding="mySharedHeapSizeField">
<constraints>
<grid row="8" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<columns value="5"/>
</properties>
</component>
<component id="8c035" class="javax.swing.JLabel" binding="mySharedVMOptionsLabel">
<constraints>
<grid row="9" 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>
<labelFor value="d1ea8"/>
<text resource-bundle="messages/JavaCompilerBundle" key="settings.shared.build.process.vm.options"/>
</properties>
</component>
<component id="d1ea8" class="com.intellij.ui.components.fields.ExpandableTextField" binding="mySharedVMOptionsField">
<constraints>
<grid row="9" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="cfc41" class="javax.swing.JLabel" binding="myHeapSizeLabel">
<constraints>
<grid row="10" 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="messages/JavaCompilerBundle" key="settings.user.local.build.process.heap.size"/>
</properties>
</component>
<component id="618d6" class="javax.swing.JTextField" binding="myHeapSizeField">
<constraints>
<grid row="10" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<columns value="5"/>
</properties>
</component>
<component id="5b86a" class="javax.swing.JLabel" binding="myVMOptionsLabel">
<constraints>
<grid row="11" 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>
<labelFor value="ad4d7"/>
<text resource-bundle="messages/JavaCompilerBundle" key="settings.user.local.build.process.vm.options"/>
</properties>
</component>
<component id="ad4d7" class="com.intellij.ui.components.fields.ExpandableTextField" binding="myVMOptionsField">
<constraints>
<grid row="11" 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>
<properties/>
</component>
</children>
</grid>
</form>
@@ -1,194 +1,23 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.compiler.options;
import com.intellij.codeInsight.NullableNotNullDialog;
import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.compiler.CompilerConfigurationImpl;
import com.intellij.compiler.CompilerWorkspaceConfiguration;
import com.intellij.compiler.MalformedPatternException;
import com.intellij.compiler.impl.javaCompiler.javac.JavacConfiguration;
import com.intellij.compiler.server.BuildManager;
import com.intellij.ide.PowerSaveMode;
import com.intellij.openapi.compiler.JavaCompilerBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
import com.intellij.ui.RawCommandLineEditor;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.fields.ExpandableTextField;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.execution.ParametersListUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.util.List;
import java.util.*;
import static com.intellij.compiler.options.CompilerOptionsFilter.Setting;
public class CompilerUIConfigurable implements SearchableConfigurable, Configurable.NoScroll {
private static final Logger LOG = Logger.getInstance(CompilerUIConfigurable.class);
public final class CompilerUIConfigurable {
static final Set<Setting> EXTERNAL_BUILD_SETTINGS = EnumSet.of(
Setting.EXTERNAL_BUILD, Setting.AUTO_MAKE, Setting.PARALLEL_COMPILATION, Setting.REBUILD_MODULE_ON_DEPENDENCY_CHANGE,
Setting.HEAP_SIZE, Setting.COMPILER_VM_OPTIONS
);
private final Set<Setting> myDisabledSettings = EnumSet.noneOf(Setting.class);
private JPanel myPanel;
private final Project myProject;
private RawCommandLineEditor myResourcePatternsField;
private JCheckBox myCbClearOutputDirectory;
private JCheckBox myCbAssertNotNull;
private JBLabel myPatternLegendLabel;
private JCheckBox myCbAutoShowFirstError;
private JCheckBox myCbDisplayNotificationPopup;
private JCheckBox myCbEnableAutomake;
private JCheckBox myCbParallelCompilation;
private JTextField mySharedHeapSizeField;
private ExpandableTextField mySharedVMOptionsField;
private JTextField myHeapSizeField;
private ExpandableTextField myVMOptionsField;
private JLabel mySharedHeapSizeLabel;
private JLabel mySharedVMOptionsLabel;
private JLabel myHeapSizeLabel;
private JLabel myVMOptionsLabel;
private JCheckBox myCbRebuildOnDependencyChange;
private JLabel myResourcePatternsLabel;
private JLabel myEnableAutomakeLegendLabel;
private JLabel myParallelCompilationLegendLabel;
private JButton myConfigureAnnotations;
private JLabel myWarningLabel;
private JPanel myAssertNotNullPanel;
public CompilerUIConfigurable(@NotNull final Project project) {
myProject = project;
myPatternLegendLabel.setText(XmlStringUtil.wrapInHtml(JavaCompilerBundle.message("compiler.ui.pattern.legend.text")));
/*"All source files located in the generated sources output directory WILL BE EXCLUDED from annotation processing. " +*/
myWarningLabel.setText(JavaCompilerBundle.message("settings.warning"));
myWarningLabel.setFont(myWarningLabel.getFont().deriveFont(Font.BOLD));
myPatternLegendLabel.setForeground(new JBColor(Gray._50, Gray._130));
tweakControls(project);
DocumentAdapter updateStateListener = new DocumentAdapter() {
@Override
protected void textChanged(@NotNull DocumentEvent e) {
mySharedVMOptionsField.setEditable(myVMOptionsField.getDocument().getLength() == 0);
mySharedVMOptionsField.setBackground(myVMOptionsField.getDocument().getLength() == 0 ?
UIUtil.getTextFieldBackground() : UIUtil.getTextFieldDisabledBackground());
mySharedHeapSizeField.setEnabled(
myHeapSizeField.getDocument().getLength() == 0 &&
ContainerUtil.find(ParametersListUtil.parse(myVMOptionsField.getText()),
s -> StringUtil.startsWithIgnoreCase(s, "-Xmx")) == null
);
}
};
myVMOptionsField.getDocument().addDocumentListener(updateStateListener);
myHeapSizeField.getDocument().addDocumentListener(updateStateListener);
myConfigureAnnotations.addActionListener(e -> {
NullableNotNullDialog.showDialogWithInstrumentationOptions(myProject);
myCbAssertNotNull.setSelected(!NullableNotNullManager.getInstance(myProject).getInstrumentedNotNulls().isEmpty());
});
}
private void tweakControls(@NotNull Project project) {
List<CompilerOptionsFilter> managers = CompilerOptionsFilter.EP_NAME.getExtensionList();
boolean showExternalBuildSetting = true;
for (CompilerOptionsFilter manager : managers) {
showExternalBuildSetting = manager.isAvailable(Setting.EXTERNAL_BUILD, project);
if (!showExternalBuildSetting) {
myDisabledSettings.add(Setting.EXTERNAL_BUILD);
break;
}
}
for (Setting setting : Setting.values()) {
if (!showExternalBuildSetting && EXTERNAL_BUILD_SETTINGS.contains(setting)) {
// Disable all nested external compiler settings if 'use external build' is unavailable.
myDisabledSettings.add(setting);
}
else {
for (CompilerOptionsFilter manager : managers) {
if (!manager.isAvailable(setting, project)) {
myDisabledSettings.add(setting);
break;
}
}
}
}
Map<Setting, Collection<JComponent>> controls = Map.ofEntries(
Map.entry(Setting.RESOURCE_PATTERNS, List.of(myResourcePatternsLabel, myResourcePatternsField, myPatternLegendLabel)),
Map.entry(Setting.CLEAR_OUTPUT_DIR_ON_REBUILD, Collections.singleton(myCbClearOutputDirectory)),
Map.entry(Setting.ADD_NOT_NULL_ASSERTIONS, Collections.singleton(myAssertNotNullPanel)),
Map.entry(Setting.AUTO_SHOW_FIRST_ERROR_IN_EDITOR, Collections.singleton(myCbAutoShowFirstError)),
Map.entry(Setting.DISPLAY_NOTIFICATION_POPUP, Collections.singleton(myCbDisplayNotificationPopup)),
Map.entry(Setting.AUTO_MAKE, List.of(myCbEnableAutomake, myEnableAutomakeLegendLabel)),
Map.entry(Setting.PARALLEL_COMPILATION, List.of(myCbParallelCompilation, myParallelCompilationLegendLabel)),
Map.entry(Setting.REBUILD_MODULE_ON_DEPENDENCY_CHANGE, List.of(myCbRebuildOnDependencyChange)),
Map.entry(Setting.HEAP_SIZE, List.of(myHeapSizeLabel, myHeapSizeField, mySharedHeapSizeLabel, mySharedHeapSizeField)),
Map.entry(Setting.COMPILER_VM_OPTIONS, List.of(myVMOptionsLabel, myVMOptionsField, mySharedVMOptionsLabel, mySharedVMOptionsField)));
for (Setting setting : myDisabledSettings) {
Collection<JComponent> components = controls.get(setting);
if (components != null) {
for (JComponent component : components) {
component.setVisible(false);
}
}
}
}
@Override
public void reset() {
final CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
final CompilerWorkspaceConfiguration workspaceConfiguration = CompilerWorkspaceConfiguration.getInstance(myProject);
myCbAutoShowFirstError.setSelected(workspaceConfiguration.AUTO_SHOW_ERRORS_IN_EDITOR);
myCbDisplayNotificationPopup.setSelected(workspaceConfiguration.DISPLAY_NOTIFICATION_POPUP);
myCbClearOutputDirectory.setSelected(workspaceConfiguration.CLEAR_OUTPUT_DIRECTORY);
myCbAssertNotNull.setSelected(configuration.isAddNotNullAssertions());
myCbEnableAutomake.setSelected(workspaceConfiguration.MAKE_PROJECT_ON_SAVE);
myCbParallelCompilation.setSelected(configuration.isParallelCompilationEnabled());
myCbRebuildOnDependencyChange.setSelected(workspaceConfiguration.REBUILD_ON_DEPENDENCY_CHANGE);
int heapSize = workspaceConfiguration.COMPILER_PROCESS_HEAP_SIZE;
myHeapSizeField.setText(heapSize > 0 ? String.valueOf(heapSize) : "");
final int javacPreferred = JavacConfiguration.getOptions(myProject, JavacConfiguration.class).MAXIMUM_HEAP_SIZE; // for compatibility with older projects
mySharedHeapSizeField.setText(String.valueOf(configuration.getBuildProcessHeapSize(javacPreferred)));
final String options = workspaceConfiguration.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS;
myVMOptionsField.setText(options == null ? "" : options.trim());
mySharedVMOptionsField.setText(configuration.getBuildProcessVMOptions());
configuration.convertPatterns();
myResourcePatternsField.setText(patternsToString(configuration.getResourceFilePatterns()));
if (PowerSaveMode.isEnabled()) {
myEnableAutomakeLegendLabel.setText(JavaCompilerBundle.message("disabled.in.power.save.mode"));
myEnableAutomakeLegendLabel.setFont(myEnableAutomakeLegendLabel.getFont().deriveFont(Font.BOLD));
}
else {
myEnableAutomakeLegendLabel.setText(JavaCompilerBundle.message("only.works.while.not.running.debugging"));
myEnableAutomakeLegendLabel.setFont(myEnableAutomakeLegendLabel.getFont().deriveFont(Font.PLAIN));
}
}
private static String patternsToString(final String[] patterns) {
static String patternsToString(final String[] patterns) {
final StringBuilder extensionsString = new StringBuilder();
for (int idx = 0; idx < patterns.length; idx++) {
if (idx > 0) {
@@ -199,60 +28,6 @@ public class CompilerUIConfigurable implements SearchableConfigurable, Configura
return extensionsString.toString();
}
@Override
public void apply() throws ConfigurationException {
CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
final CompilerWorkspaceConfiguration workspaceConfiguration = CompilerWorkspaceConfiguration.getInstance(myProject);
if (!myDisabledSettings.contains(Setting.AUTO_SHOW_FIRST_ERROR_IN_EDITOR)) {
workspaceConfiguration.AUTO_SHOW_ERRORS_IN_EDITOR = myCbAutoShowFirstError.isSelected();
}
if (!myDisabledSettings.contains(Setting.DISPLAY_NOTIFICATION_POPUP)) {
workspaceConfiguration.DISPLAY_NOTIFICATION_POPUP = myCbDisplayNotificationPopup.isSelected();
}
if (!myDisabledSettings.contains(Setting.CLEAR_OUTPUT_DIR_ON_REBUILD)) {
workspaceConfiguration.CLEAR_OUTPUT_DIRECTORY = myCbClearOutputDirectory.isSelected();
}
if (!myDisabledSettings.contains(Setting.EXTERNAL_BUILD)) {
if (!myDisabledSettings.contains(Setting.AUTO_MAKE)) {
workspaceConfiguration.MAKE_PROJECT_ON_SAVE = myCbEnableAutomake.isSelected();
}
if (!myDisabledSettings.contains(Setting.PARALLEL_COMPILATION) && configuration.isParallelCompilationEnabled() != myCbParallelCompilation.isSelected()) {
configuration.setParallelCompilationEnabled(myCbParallelCompilation.isSelected());
}
if (!myDisabledSettings.contains(Setting.REBUILD_MODULE_ON_DEPENDENCY_CHANGE)) {
workspaceConfiguration.REBUILD_ON_DEPENDENCY_CHANGE = myCbRebuildOnDependencyChange.isSelected();
}
if (!myDisabledSettings.contains(Setting.HEAP_SIZE)) {
try {
String heapSizeText = myHeapSizeField.getText().trim();
workspaceConfiguration.COMPILER_PROCESS_HEAP_SIZE = heapSizeText.isEmpty() ? 0 : Integer.parseInt(heapSizeText);
configuration.setBuildProcessHeapSize(Integer.parseInt(mySharedHeapSizeField.getText().trim()));
}
catch (NumberFormatException ignored) {
LOG.info(ignored);
}
}
if (!myDisabledSettings.contains(Setting.COMPILER_VM_OPTIONS)) {
workspaceConfiguration.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS = myVMOptionsField.getText().trim();
configuration.setBuildProcessVMOptions(mySharedVMOptionsField.getText().trim());
}
}
if (!myDisabledSettings.contains(Setting.ADD_NOT_NULL_ASSERTIONS)) {
configuration.setAddNotNullAssertions(myCbAssertNotNull.isSelected());
}
if (!myDisabledSettings.contains(Setting.RESOURCE_PATTERNS)) {
configuration.removeResourceFilePatterns();
String extensionString = myResourcePatternsField.getText().trim();
applyResourcePatterns(extensionString, configuration);
}
if (!myProject.isDefault()) {
BuildManager.getInstance().clearState(myProject);
}
}
public static void applyResourcePatterns(String extensionString, final CompilerConfigurationImpl configuration)
throws ConfigurationException {
StringTokenizer tokenizer = new StringTokenizer(extensionString, ";", false);
@@ -269,83 +44,19 @@ public class CompilerUIConfigurable implements SearchableConfigurable, Configura
}
if (!errors.isEmpty()) {
final StringBuilder pattersnsWithErrors = new StringBuilder();
final StringBuilder patternsWithError = new StringBuilder();
for (final Object error : errors) {
String[] pair = (String[])error;
pattersnsWithErrors.append("\n");
pattersnsWithErrors.append(pair[0]);
pattersnsWithErrors.append(": ");
pattersnsWithErrors.append(pair[1]);
patternsWithError.append("\n");
patternsWithError.append(pair[0]);
patternsWithError.append(": ");
patternsWithError.append(pair[1]);
}
throw new ConfigurationException(
JavaCompilerBundle.message("error.compiler.configurable.malformed.patterns", pattersnsWithErrors.toString()), JavaCompilerBundle
.message("bad.resource.patterns.dialog.title")
JavaCompilerBundle.message("error.compiler.configurable.malformed.patterns", patternsWithError.toString()),
JavaCompilerBundle.message("bad.resource.patterns.dialog.title")
);
}
}
@Override
public boolean isModified() {
final CompilerConfiguration configuration = CompilerConfiguration.getInstance(myProject);
final CompilerWorkspaceConfiguration workspaceConfiguration = CompilerWorkspaceConfiguration.getInstance(myProject);
boolean isModified = !myDisabledSettings.contains(Setting.AUTO_SHOW_FIRST_ERROR_IN_EDITOR)
&& ComparingUtils.isModified(myCbAutoShowFirstError, workspaceConfiguration.AUTO_SHOW_ERRORS_IN_EDITOR);
isModified |= !myDisabledSettings.contains(Setting.DISPLAY_NOTIFICATION_POPUP)
&& ComparingUtils.isModified(myCbDisplayNotificationPopup, workspaceConfiguration.DISPLAY_NOTIFICATION_POPUP);
isModified |= !myDisabledSettings.contains(Setting.AUTO_MAKE)
&& ComparingUtils.isModified(myCbEnableAutomake, workspaceConfiguration.MAKE_PROJECT_ON_SAVE);
isModified |= !myDisabledSettings.contains(Setting.PARALLEL_COMPILATION)
&& ComparingUtils.isModified(myCbParallelCompilation, configuration.isParallelCompilationEnabled());
isModified |= !myDisabledSettings.contains(Setting.REBUILD_MODULE_ON_DEPENDENCY_CHANGE)
&& ComparingUtils.isModified(myCbRebuildOnDependencyChange, workspaceConfiguration.REBUILD_ON_DEPENDENCY_CHANGE);
isModified |= !myDisabledSettings.contains(Setting.HEAP_SIZE)
&& ComparingUtils.isModified(myHeapSizeField, 0, workspaceConfiguration.COMPILER_PROCESS_HEAP_SIZE);
isModified |= !myDisabledSettings.contains(Setting.COMPILER_VM_OPTIONS)
&& ComparingUtils.isModified(myVMOptionsField, workspaceConfiguration.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS);
final CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
isModified |= !myDisabledSettings.contains(Setting.HEAP_SIZE)
&& ComparingUtils.isModified(mySharedHeapSizeField, compilerConfiguration.getBuildProcessHeapSize(0));
isModified |= !myDisabledSettings.contains(Setting.COMPILER_VM_OPTIONS)
&& ComparingUtils.isModified(mySharedVMOptionsField, compilerConfiguration.getBuildProcessVMOptions());
isModified |= !myDisabledSettings.contains(Setting.ADD_NOT_NULL_ASSERTIONS)
&& ComparingUtils.isModified(myCbAssertNotNull, compilerConfiguration.isAddNotNullAssertions());
isModified |= !myDisabledSettings.contains(Setting.CLEAR_OUTPUT_DIR_ON_REBUILD)
&& ComparingUtils.isModified(myCbClearOutputDirectory, workspaceConfiguration.CLEAR_OUTPUT_DIRECTORY);
isModified |= !myDisabledSettings.contains(Setting.RESOURCE_PATTERNS)
&& ComparingUtils.isModified(myResourcePatternsField, patternsToString(compilerConfiguration.getResourceFilePatterns()));
return isModified;
}
@Override
public String getDisplayName() {
return JavaCompilerBundle.message("configurable.CompilerUIConfigurable.display.name");
}
@Override
public String getHelpTopic() {
return null;
}
@Override
@NotNull
public String getId() {
return "compiler.general";
}
@Override
public JComponent createComponent() {
return myPanel;
}
JCheckBox getBuildOnSaveCheckBox() {
return myCbEnableAutomake;
}
private void createUIComponents() {
myResourcePatternsField = new RawCommandLineEditor(ParametersListUtil.COLON_LINE_PARSER, ParametersListUtil.COLON_LINE_JOINER);
myResourcePatternsField.setDialogCaption("Resource patterns");
}
}
@@ -0,0 +1,276 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.compiler.options
import com.intellij.codeInsight.NullableNotNullDialog
import com.intellij.codeInsight.NullableNotNullManager
import com.intellij.compiler.CompilerConfiguration
import com.intellij.compiler.CompilerConfigurationImpl
import com.intellij.compiler.CompilerWorkspaceConfiguration
import com.intellij.compiler.impl.javaCompiler.javac.JavacConfiguration
import com.intellij.compiler.options.CompilerOptionsFilter.Setting
import com.intellij.ide.PowerSaveMode
import com.intellij.openapi.compiler.JavaCompilerBundle
import com.intellij.openapi.options.DslConfigurableBase
import com.intellij.openapi.options.SearchableConfigurable
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.NlsContexts
import com.intellij.openapi.util.text.StringUtil
import com.intellij.ui.DocumentAdapter
import com.intellij.ui.RawCommandLineEditor
import com.intellij.ui.components.fields.ExpandableTextField
import com.intellij.ui.dsl.builder.AlignX
import com.intellij.ui.dsl.builder.BottomGap
import com.intellij.ui.dsl.builder.Cell
import com.intellij.ui.dsl.builder.HyperlinkEventAction
import com.intellij.ui.dsl.builder.RightGap
import com.intellij.ui.dsl.builder.panel
import com.intellij.util.execution.ParametersListUtil
import com.intellij.util.ui.UIUtil
import org.jetbrains.annotations.NonNls
import java.util.EnumSet
import javax.swing.JButton
import javax.swing.JCheckBox
import javax.swing.JComponent
import javax.swing.JTextField
class CompilerUIConfigurableKt(val project: Project) : DslConfigurableBase(), SearchableConfigurable {
val disabledSettings: MutableSet<Setting> = EnumSet.noneOf(Setting::class.java)
lateinit var resourcePatternsField: RawCommandLineEditor
lateinit var cbClearOutputDirectory: JCheckBox
lateinit var cbAssertNotNull: JCheckBox
lateinit var cbAutoShowFirstError: JCheckBox
lateinit var cbDisplayNotificationPopup: JCheckBox
lateinit var cbEnableAutomakeCell: Cell<JCheckBox>
lateinit var cbEnableAutomake: JCheckBox
lateinit var cbParallelCompilation: JCheckBox
lateinit var sharedHeapSizeField: JTextField
lateinit var sharedVMOptionsField: ExpandableTextField
lateinit var heapSizeField: JTextField
lateinit var vmOptionsField: ExpandableTextField
lateinit var cbRebuildOnDependencyChange: JCheckBox
lateinit var configureAnnotations: JButton
override fun createPanel() = panel {
row(JavaCompilerBundle.message("label.option.resource.patterns.text")) {
resourcePatternsField = cell(RawCommandLineEditor(ParametersListUtil.COLON_LINE_PARSER, ParametersListUtil.COLON_LINE_JOINER))
.comment(JavaCompilerBundle.message("compiler.ui.pattern.legend.text"))
.resizableColumn()
.align(AlignX.FILL)
.component
contextHelp(JavaCompilerBundle.message("compiler.ui.pattern.context.help"), JavaCompilerBundle.message("compiler.ui.pattern.context.help.title"))
}
.bottomGap(BottomGap.SMALL)
panel {
row {
cbClearOutputDirectory = checkBox(JavaCompilerBundle.message("label.option.clear.output.directory.on.rebuild"))
.comment(JavaCompilerBundle.message("settings.warning"))
.component
}
row {
cbAssertNotNull = checkBox(JavaCompilerBundle.message("add.notnull.assertions"))
.component
configureAnnotations = link(JavaCompilerBundle.message("settings.configure.annotations")) {
NullableNotNullDialog.showDialogWithInstrumentationOptions(project)
cbAssertNotNull.setSelected(!NullableNotNullManager.getInstance(project).getInstrumentedNotNulls().isEmpty())
}
.component
}
row {
cbAutoShowFirstError = checkBox(JavaCompilerBundle.message("label.option.autoshow.first.error"))
.component
}
row {
cbDisplayNotificationPopup = checkBox(JavaCompilerBundle.message("label.option.display.notification.popup"))
.component
}
row {
cbEnableAutomakeCell = checkBox(JavaCompilerBundle.message("settings.build.project.automatically"))
.comment(JavaCompilerBundle.message("only.works.while.not.running.debugging"))
cbEnableAutomake = cbEnableAutomakeCell.component
}
row {
cbParallelCompilation = checkBox(JavaCompilerBundle.message("settings.compile.independent.modules.in.parallel"))
.comment(JavaCompilerBundle.message("settings.parallel.module.compile.may.require.larger.heap.size"))
.component
}
row {
cbRebuildOnDependencyChange = checkBox(JavaCompilerBundle.message("settings.rebuild.module.on.dependency.change"))
.component
}
}
group(JavaCompilerBundle.message("settings.build.process.group")) {
row(JavaCompilerBundle.message("settings.build.process.heap.size")) {
sharedHeapSizeField = intTextField()
.gap(RightGap.SMALL)
.component
label(JavaCompilerBundle.message("settings.size.mbytes"))
}
row(JavaCompilerBundle.message("settings.shared.build.process.vm.options")) {
sharedVMOptionsField = expandableTextField()
.resizableColumn()
.align(AlignX.FILL)
.component
}
row(JavaCompilerBundle.message("settings.user.local.build.process.heap.size")) {
heapSizeField = intTextField()
.gap(RightGap.SMALL)
.comment(JavaCompilerBundle.message("settings.user.local.build.process.heap.size.comment"))
.component
label(JavaCompilerBundle.message("settings.size.mbytes"))
}
row(JavaCompilerBundle.message("settings.user.local.build.process.vm.options")) {
vmOptionsField = expandableTextField()
.comment(JavaCompilerBundle.message("settings.user.local.build.process.vm.options.comment"))
.resizableColumn()
.align(AlignX.FILL)
.component
}
.bottomGap(BottomGap.SMALL)
}
tweakControls()
val updateStateListener: DocumentAdapter = object : DocumentAdapter() {
override fun textChanged(e: javax.swing.event.DocumentEvent) {
sharedVMOptionsField.isEditable = vmOptionsField.document.length == 0
sharedVMOptionsField.background = when (sharedVMOptionsField.isEditable) {
true -> UIUtil.getTextFieldBackground()
else -> UIUtil.getTextFieldDisabledBackground()
}
sharedHeapSizeField.isEnabled = heapSizeField.document.length == 0 &&
ParametersListUtil.parse(vmOptionsField.text).none { StringUtil.startsWithIgnoreCase(it, "-Xmx") }
}
}
vmOptionsField.getDocument().addDocumentListener(updateStateListener)
heapSizeField.getDocument().addDocumentListener(updateStateListener)
}
fun tweakControls() {
val managers = CompilerOptionsFilter.EP_NAME.extensionList
var showExternalBuildSetting = true
for (manager in managers) {
showExternalBuildSetting = manager.isAvailable(Setting.EXTERNAL_BUILD, project)
if (!showExternalBuildSetting) {
disabledSettings.add(Setting.EXTERNAL_BUILD)
break
}
}
for (setting in Setting.entries) {
if (!showExternalBuildSetting && CompilerUIConfigurable.EXTERNAL_BUILD_SETTINGS.contains(setting)) {
// Disable all nested external compiler settings if 'use external build' is unavailable.
disabledSettings.add(setting)
}
else {
for (manager in managers) {
if (!manager.isAvailable(setting, project)) {
disabledSettings.add(setting)
break
}
}
}
}
val controls: Map<Setting, Collection<JComponent>> = mapOf(
Setting.RESOURCE_PATTERNS to listOf(resourcePatternsField),
Setting.CLEAR_OUTPUT_DIR_ON_REBUILD to listOf(cbClearOutputDirectory),
Setting.ADD_NOT_NULL_ASSERTIONS to listOf(cbAssertNotNull),
Setting.AUTO_SHOW_FIRST_ERROR_IN_EDITOR to listOf(cbAutoShowFirstError),
Setting.DISPLAY_NOTIFICATION_POPUP to listOf(cbDisplayNotificationPopup),
Setting.AUTO_MAKE to listOf(cbEnableAutomake),
Setting.PARALLEL_COMPILATION to listOf(cbParallelCompilation),
Setting.REBUILD_MODULE_ON_DEPENDENCY_CHANGE to listOf(cbRebuildOnDependencyChange),
Setting.HEAP_SIZE to listOf(heapSizeField, sharedHeapSizeField),
Setting.COMPILER_VM_OPTIONS to listOf(vmOptionsField, sharedVMOptionsField),
)
for (setting in disabledSettings) {
val components = controls[setting]
if (components != null) {
components.forEach { it.setVisible(false) }
}
}
}
override fun reset() {
val configuration = CompilerConfiguration.getInstance(project) as CompilerConfigurationImpl
val workspaceConfiguration = CompilerWorkspaceConfiguration.getInstance(project)
cbAutoShowFirstError.setSelected(workspaceConfiguration.AUTO_SHOW_ERRORS_IN_EDITOR)
cbDisplayNotificationPopup.setSelected(workspaceConfiguration.DISPLAY_NOTIFICATION_POPUP)
cbClearOutputDirectory.setSelected(workspaceConfiguration.CLEAR_OUTPUT_DIRECTORY)
cbAssertNotNull.setSelected(configuration.isAddNotNullAssertions())
cbEnableAutomake.setSelected(workspaceConfiguration.MAKE_PROJECT_ON_SAVE)
cbParallelCompilation.setSelected(configuration.isParallelCompilationEnabled())
cbRebuildOnDependencyChange.setSelected(workspaceConfiguration.REBUILD_ON_DEPENDENCY_CHANGE)
val heapSize = workspaceConfiguration.COMPILER_PROCESS_HEAP_SIZE
heapSizeField.setText(if (heapSize > 0) heapSize.toString() else "")
// for compatibility with older projects
val javacPreferred = JavacConfiguration.getOptions(project, JavacConfiguration::class.java).MAXIMUM_HEAP_SIZE
sharedHeapSizeField.setText(configuration.getBuildProcessHeapSize(javacPreferred).toString())
val options = workspaceConfiguration.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS
vmOptionsField.setText(options?.trim() ?: "")
sharedVMOptionsField.setText(configuration.getBuildProcessVMOptions())
configuration.convertPatterns()
resourcePatternsField.setText(CompilerUIConfigurable.patternsToString(configuration.getResourceFilePatterns()))
if (PowerSaveMode.isEnabled()) {
cbEnableAutomakeCell.comment(JavaCompilerBundle.message("disabled.in.power.save.mode"), 70, HyperlinkEventAction.HTML_HYPERLINK_INSTANCE)
}
else {
cbEnableAutomakeCell.comment(JavaCompilerBundle.message("only.works.while.not.running.debugging"), 70, HyperlinkEventAction.HTML_HYPERLINK_INSTANCE)
}
}
override fun isModified(): Boolean {
val configuration = CompilerConfiguration.getInstance(project)
val workspaceConfiguration = CompilerWorkspaceConfiguration.getInstance(project)
var isModified = !disabledSettings.contains(Setting.AUTO_SHOW_FIRST_ERROR_IN_EDITOR)
&& ComparingUtils.isModified(cbAutoShowFirstError, workspaceConfiguration.AUTO_SHOW_ERRORS_IN_EDITOR)
isModified = isModified || !disabledSettings.contains(Setting.DISPLAY_NOTIFICATION_POPUP)
&& ComparingUtils.isModified(cbDisplayNotificationPopup, workspaceConfiguration.DISPLAY_NOTIFICATION_POPUP)
isModified = isModified || !disabledSettings.contains(Setting.AUTO_MAKE)
&& ComparingUtils.isModified(cbEnableAutomake, workspaceConfiguration.MAKE_PROJECT_ON_SAVE)
isModified = isModified || !disabledSettings.contains(Setting.PARALLEL_COMPILATION)
&& ComparingUtils.isModified(cbParallelCompilation, configuration.isParallelCompilationEnabled())
isModified = isModified || !disabledSettings.contains(Setting.REBUILD_MODULE_ON_DEPENDENCY_CHANGE)
&& ComparingUtils.isModified(cbRebuildOnDependencyChange, workspaceConfiguration.REBUILD_ON_DEPENDENCY_CHANGE)
isModified = isModified || !disabledSettings.contains(Setting.HEAP_SIZE)
&& ComparingUtils.isModified(heapSizeField, 0, workspaceConfiguration.COMPILER_PROCESS_HEAP_SIZE)
isModified = isModified || !disabledSettings.contains(Setting.COMPILER_VM_OPTIONS)
&& ComparingUtils.isModified(vmOptionsField, workspaceConfiguration.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS)
val compilerConfiguration = CompilerConfiguration.getInstance(project) as CompilerConfigurationImpl
isModified = isModified || !disabledSettings.contains(Setting.HEAP_SIZE)
&& ComparingUtils.isModified(sharedHeapSizeField, compilerConfiguration.getBuildProcessHeapSize(0))
isModified = isModified || !disabledSettings.contains(Setting.COMPILER_VM_OPTIONS)
&& ComparingUtils.isModified(sharedVMOptionsField, compilerConfiguration.getBuildProcessVMOptions())
isModified = isModified || !disabledSettings.contains(Setting.ADD_NOT_NULL_ASSERTIONS)
&& ComparingUtils.isModified(cbAssertNotNull, compilerConfiguration.isAddNotNullAssertions())
isModified = isModified || !disabledSettings.contains(Setting.CLEAR_OUTPUT_DIR_ON_REBUILD)
&& ComparingUtils.isModified(cbClearOutputDirectory, workspaceConfiguration.CLEAR_OUTPUT_DIRECTORY)
isModified = isModified || !disabledSettings.contains(Setting.RESOURCE_PATTERNS)
&& ComparingUtils.isModified(resourcePatternsField, CompilerUIConfigurable.patternsToString(compilerConfiguration.getResourceFilePatterns()))
return isModified
}
fun getBuildOnSaveCheckBox(): JCheckBox {
return cbEnableAutomake
}
override fun getId(): @NonNls String = "compiler.general"
override fun getDisplayName(): @NlsContexts.ConfigurableName String = JavaCompilerBundle.message("configurable.CompilerUIConfigurable.display.name")
}
@@ -131,13 +131,17 @@ settings.actions.on.save.page.build.project.on.save.checkbox.comment=Not trigger
settings.actions.on.save.page.compiler.settings.link=Compiler settings...
settings.compile.independent.modules.in.parallel=Compile independent modules in parallel
settings.rebuild.module.on.dependency.change=Rebuild module on dependency change
settings.build.process.heap.size=Shared build process heap size (Mbytes):
settings.user.local.build.process.heap.size=User-local build process heap size (Mbytes) (overrides Shared size):
settings.shared.build.process.vm.options=Shared build process VM options:
settings.user.local.build.process.vm.options=User-local build process VM options (overrides Shared options):
settings.auto.build.only.works.while.not.running=(only works while not running / debugging)
settings.parallel.module.compile.may.require.larger.heap.size=(may require larger heap size)
settings.warning=<html>WARNING!<br>If option 'Clear output directory on rebuild' is enabled, the entire contents of directories where generated sources are stored WILL BE CLEARED on rebuild.</html>
settings.size.mbytes=Mbytes
settings.build.process.group=Build Process
settings.build.process.heap.size=Shared heap size:
settings.user.local.build.process.heap.size=User-local heap size:
settings.user.local.build.process.heap.size.comment=Overrides Shared size
settings.shared.build.process.vm.options=Shared VM options:
settings.user.local.build.process.vm.options=User-local VM options:
settings.user.local.build.process.vm.options.comment=Overrides Shared options
settings.auto.build.only.works.while.not.running=Only works while not running / debugging
settings.parallel.module.compile.may.require.larger.heap.size=May require a larger heap size
settings.warning=<b>WARNING!<br>If enabled, the entire contents of directories where generated sources are stored<br>WILL BE CLEARED on rebuild.</b>
settings.use.release.option.for.cross.compilation=Use '--release' option for cross-compilation (Java 9 and later)
settings.project.bytecode.version=Project bytecode version:
settings.per.module.bytecode.version=Per-module bytecode version:
@@ -174,8 +178,8 @@ settings.validators=Validators:
no.compilation.problems.found=No compilation problems found
cannot.package.file=Cannot package file
packaging.files=Packaging Files
only.works.while.not.running.debugging=(only works while not running / debugging)
disabled.in.power.save.mode=(disabled in Power Save mode)
only.works.while.not.running.debugging=Only works while not running / debugging
disabled.in.power.save.mode=Disabled in Power Save mode
path.to.ecj.compiler.tool=Path to ecj compiler tool
choose.members=Choose Members
all.modules=<All Modules>
@@ -236,10 +240,15 @@ progress.text.clearing.build.system.data=Clearing build system data\u2026
separator.choose.members.to.delete=<html>Choose Members To Delete Since They Are Already Defined In <b>{0}</b>
text.empty.profile=Profile name shouldn't be empty
text.profile.exists=Profile {0} already exists
compiler.ui.pattern.legend.text=Use <b>;</b> to separate patterns and <b>!</b> to negate a pattern. \
Accepted wildcards: <b>?</b> \\&mdash; exactly one symbol; <b>*</b> \\&mdash; zero or more symbols; \
<b>/</b> \\&mdash; path separator; <b>/**/</b> \\&mdash; any number of directories; \
<i>\\&lt;dir_name\\&gt;</i>:<i>\\&lt;pattern\\&gt;</i> \\&mdash; restrict to source roots with the specified name
compiler.ui.pattern.legend.text=Use <b>;</b> to separate patterns and <b>!</b> to negate a pattern.
compiler.ui.pattern.context.help.title=Accepted wildcards
compiler.ui.pattern.context.help=<ul>\
<li><code>?</code> \\&#8594; exactly one symbol;\
<li><code>*</code> \\&#8594; zero or more symbols;\
<li><code>/</code> \\&#8594; path separator;\
<li><code>/**/</code> \\&#8594; any number of directories;\
<li><code>\\&lt;dir_name\\&gt;:\\&lt;pattern\\&gt;</code> \\&#8594; restrict to source roots with the specified name.\
</ul>
notification.compiler.auto.build.failure=Auto build failure: {0}
notification.compiler.auto.build.completed.with.errors=Auto build completed with errors
dialog.title.manifest.select.main.class=Select Main Class