mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 17:26:01 +02:00
Resource scope for Build Command Parsers
This commit is contained in:
parent
d1e9395955
commit
0755f5870d
3 changed files with 211 additions and 13 deletions
|
@ -195,6 +195,7 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
|
||||||
assertEquals(null, provider.getLanguageScope());
|
assertEquals(null, provider.getLanguageScope());
|
||||||
assertEquals(null, provider.getSettingEntries(null, null, null));
|
assertEquals(null, provider.getSettingEntries(null, null, null));
|
||||||
assertEquals("", provider.getCompilerPattern());
|
assertEquals("", provider.getCompilerPattern());
|
||||||
|
assertEquals(AbstractBuildCommandParser.ResourceScope.FILE, provider.getResourceScope());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -218,6 +219,8 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
|
||||||
// setters
|
// setters
|
||||||
provider.setCompilerPattern(CUSTOM_PARAMETER_2);
|
provider.setCompilerPattern(CUSTOM_PARAMETER_2);
|
||||||
assertEquals(CUSTOM_PARAMETER_2, provider.getCompilerPattern());
|
assertEquals(CUSTOM_PARAMETER_2, provider.getCompilerPattern());
|
||||||
|
provider.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT);
|
||||||
|
assertEquals(AbstractBuildCommandParser.ResourceScope.PROJECT, provider.getResourceScope());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,11 +239,23 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
|
||||||
// configure provider
|
// configure provider
|
||||||
parser.setResolvingPaths(false);
|
parser.setResolvingPaths(false);
|
||||||
assertFalse(parser.equals(clone0));
|
assertFalse(parser.equals(clone0));
|
||||||
|
parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT);
|
||||||
|
assertEquals(AbstractBuildCommandParser.ResourceScope.PROJECT, parser.getResourceScope());
|
||||||
|
parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.FOLDER);
|
||||||
|
assertEquals(AbstractBuildCommandParser.ResourceScope.FOLDER, parser.getResourceScope());
|
||||||
|
parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.FILE);
|
||||||
|
assertEquals(AbstractBuildCommandParser.ResourceScope.FILE, parser.getResourceScope());
|
||||||
|
|
||||||
// check another clone after configuring
|
// check another clone after changing settings
|
||||||
{
|
{
|
||||||
|
parser.setResolvingPaths(false);
|
||||||
|
assertFalse(parser.equals(clone0));
|
||||||
|
parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT);
|
||||||
|
assertEquals(AbstractBuildCommandParser.ResourceScope.PROJECT, parser.getResourceScope());
|
||||||
MockBuildCommandParser clone = parser.clone();
|
MockBuildCommandParser clone = parser.clone();
|
||||||
assertTrue(parser.equals(clone));
|
assertTrue(parser.equals(clone));
|
||||||
|
assertEquals(parser.isResolvingPaths(), clone.isResolvingPaths());
|
||||||
|
assertEquals(parser.getResourceScope(), clone.getResourceScope());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check 'expand relative paths' flag
|
// check 'expand relative paths' flag
|
||||||
|
@ -251,6 +266,16 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
|
||||||
assertFalse(parser.equals(clone));
|
assertFalse(parser.equals(clone));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check resource scope
|
||||||
|
{
|
||||||
|
parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT);
|
||||||
|
assertEquals(AbstractBuildCommandParser.ResourceScope.PROJECT, parser.getResourceScope());
|
||||||
|
MockBuildCommandParser clone = parser.clone();
|
||||||
|
assertEquals(AbstractBuildCommandParser.ResourceScope.PROJECT, clone.getResourceScope());
|
||||||
|
clone.setResourceScope(AbstractBuildCommandParser.ResourceScope.FOLDER);
|
||||||
|
assertFalse(parser.equals(clone));
|
||||||
|
}
|
||||||
|
|
||||||
// check cloneShallow()
|
// check cloneShallow()
|
||||||
{
|
{
|
||||||
MockBuildCommandParser parser2 = parser.clone();
|
MockBuildCommandParser parser2 = parser.clone();
|
||||||
|
|
|
@ -21,6 +21,10 @@ import org.eclipse.cdt.core.IMarkerGenerator;
|
||||||
import org.eclipse.cdt.core.errorparsers.RegexErrorParser;
|
import org.eclipse.cdt.core.errorparsers.RegexErrorParser;
|
||||||
import org.eclipse.cdt.core.errorparsers.RegexErrorPattern;
|
import org.eclipse.cdt.core.errorparsers.RegexErrorPattern;
|
||||||
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
|
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
|
||||||
|
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
|
||||||
|
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsLogger;
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class for providers parsing compiler option from build command when present in build output.
|
* Abstract class for providers parsing compiler option from build command when present in build output.
|
||||||
|
@ -29,12 +33,24 @@ import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractBuildCommandParser extends AbstractLanguageSettingsOutputScanner {
|
public abstract class AbstractBuildCommandParser extends AbstractLanguageSettingsOutputScanner {
|
||||||
public static final Object JOB_FAMILY_BUILD_COMMAND_PARSER = "org.eclipse.cdt.managedbuilder.AbstractBuildCommandParser"; //$NON-NLS-1$
|
public static final Object JOB_FAMILY_BUILD_COMMAND_PARSER = "org.eclipse.cdt.managedbuilder.AbstractBuildCommandParser"; //$NON-NLS-1$
|
||||||
|
|
||||||
private static final String ATTR_PARAMETER = "parameter"; //$NON-NLS-1$
|
private static final String ATTR_PARAMETER = "parameter"; //$NON-NLS-1$
|
||||||
|
private static final String ATTR_RESOURCE_SCOPE = "resource-scope"; //$NON-NLS-1$
|
||||||
|
private static final String VALUE_FILE_SCOPE = "per-file"; //$NON-NLS-1$
|
||||||
|
private static final String VALUE_FOLDER_SCOPE = "per-folder"; //$NON-NLS-1$
|
||||||
|
private static final String VALUE_PROJECT_SCOPE = "per-project"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
|
||||||
private static final String LEADING_PATH_PATTERN = "\\S+[/\\\\]"; //$NON-NLS-1$
|
private static final String LEADING_PATH_PATTERN = "\\S+[/\\\\]"; //$NON-NLS-1$
|
||||||
private static final Pattern OPTIONS_PATTERN = Pattern.compile("-[^\\s\"']*(\\s*((\".*?\")|('.*?')|([^-\\s][^\\s]+)))?"); //$NON-NLS-1$
|
private static final Pattern OPTIONS_PATTERN = Pattern.compile("-[^\\s\"']*(\\s*((\".*?\")|('.*?')|([^-\\s][^\\s]+)))?"); //$NON-NLS-1$
|
||||||
private static final int OPTION_GROUP = 0;
|
private static final int OPTION_GROUP = 0;
|
||||||
|
|
||||||
|
public enum ResourceScope {
|
||||||
|
FILE,
|
||||||
|
FOLDER,
|
||||||
|
PROJECT,
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: design patterns to keep file group the same and matching {@link #FILE_GROUP}
|
* Note: design patterns to keep file group the same and matching {@link #FILE_GROUP}
|
||||||
*/
|
*/
|
||||||
|
@ -45,6 +61,8 @@ public abstract class AbstractBuildCommandParser extends AbstractLanguageSetting
|
||||||
};
|
};
|
||||||
private static final int FILE_GROUP = 2;
|
private static final int FILE_GROUP = 2;
|
||||||
|
|
||||||
|
// cached value from properties, do not need to use in equals() and hashCode()
|
||||||
|
private ResourceScope resourceScope = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The compiler command pattern without specifying compiler options.
|
* The compiler command pattern without specifying compiler options.
|
||||||
|
@ -76,6 +94,85 @@ public abstract class AbstractBuildCommandParser extends AbstractLanguageSetting
|
||||||
return "\\s*\"?("+LEADING_PATH_PATTERN+")?(" + compilerPattern + ")\"?";
|
return "\\s*\"?("+LEADING_PATH_PATTERN+")?(" + compilerPattern + ")\"?";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return resource scope of the entries, i.e. level in resource hierarchy where language settings entries
|
||||||
|
* will be applied by the provider. Resource scope can be one of the following:
|
||||||
|
* <br>- {@code AbstractBuildCommandParser.ResourceScope.FILE} - apply entries to the file being parsed.
|
||||||
|
* <br>- {@code AbstractBuildCommandParser.ResourceScope.FOLDER} - apply entries to the enclosing folder.
|
||||||
|
* <br>- {@code AbstractBuildCommandParser.ResourceScope.PROJECT} - apply entries to the project level.
|
||||||
|
*/
|
||||||
|
public ResourceScope getResourceScope() {
|
||||||
|
if (resourceScope == null) {
|
||||||
|
String scopeStr = getProperty(ATTR_RESOURCE_SCOPE);
|
||||||
|
if (scopeStr.equals(VALUE_FILE_SCOPE)) {
|
||||||
|
resourceScope = ResourceScope.FILE;
|
||||||
|
} else if (scopeStr.equals(VALUE_FOLDER_SCOPE)) {
|
||||||
|
resourceScope = ResourceScope.FOLDER;
|
||||||
|
} else if (scopeStr.equals(VALUE_PROJECT_SCOPE)) {
|
||||||
|
resourceScope = ResourceScope.PROJECT;
|
||||||
|
} else {
|
||||||
|
resourceScope = ResourceScope.FILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resourceScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set resource scope of the entries, i.e. level in resource hierarchy where language settings entries
|
||||||
|
* will be applied by the provider.
|
||||||
|
*
|
||||||
|
* @param rcScope - resource scope can be one of the following:
|
||||||
|
* <br>- {@code AbstractBuildCommandParser.ResourceScope.FILE} - apply entries to the file being parsed.
|
||||||
|
* <br>- {@code AbstractBuildCommandParser.ResourceScope.FOLDER} - apply entries to the enclosing folder.
|
||||||
|
* <br>- {@code AbstractBuildCommandParser.ResourceScope.PROJECT} - apply entries to the project level.
|
||||||
|
*/
|
||||||
|
public void setResourceScope(ResourceScope rcScope) {
|
||||||
|
resourceScope = rcScope;
|
||||||
|
switch (rcScope) {
|
||||||
|
case FILE:
|
||||||
|
setProperty(ATTR_RESOURCE_SCOPE, VALUE_FILE_SCOPE);
|
||||||
|
break;
|
||||||
|
case FOLDER:
|
||||||
|
setProperty(ATTR_RESOURCE_SCOPE, VALUE_FOLDER_SCOPE);
|
||||||
|
break;
|
||||||
|
case PROJECT:
|
||||||
|
setProperty(ATTR_RESOURCE_SCOPE, VALUE_PROJECT_SCOPE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
setProperty(ATTR_RESOURCE_SCOPE, VALUE_FILE_SCOPE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setSettingEntries(List<ICLanguageSettingEntry> entries) {
|
||||||
|
IResource rc = null;
|
||||||
|
switch (getResourceScope()) {
|
||||||
|
case FILE:
|
||||||
|
rc = currentResource;
|
||||||
|
break;
|
||||||
|
case FOLDER:
|
||||||
|
if (currentResource instanceof IFile) {
|
||||||
|
rc = currentResource.getParent();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PROJECT:
|
||||||
|
if (currentResource != null) {
|
||||||
|
rc = currentResource.getProject();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
setSettingEntries(currentCfgDescription, rc, currentLanguageId, entries);
|
||||||
|
|
||||||
|
// AG FIXME - temporary log to remove before CDT Juno release
|
||||||
|
LanguageSettingsLogger.logInfo(getPrefixForLog()
|
||||||
|
+ getClass().getSimpleName() + " collected " + (entries!=null ? ("" + entries.size()) : "null") + " entries for " + rc);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adjust count for file group taking into consideration extra groups added by {@link #getCompilerPatternExtended()}.
|
* Adjust count for file group taking into consideration extra groups added by {@link #getCompilerPatternExtended()}.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
import org.eclipse.swt.widgets.Button;
|
import org.eclipse.swt.widgets.Button;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Group;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
import org.eclipse.swt.widgets.Text;
|
import org.eclipse.swt.widgets.Text;
|
||||||
|
|
||||||
|
@ -46,7 +47,10 @@ public final class GCCBuildCommandParserOptionPage extends AbstractLanguageSetti
|
||||||
private Button runOnceRadioButton;
|
private Button runOnceRadioButton;
|
||||||
private Button runEveryBuildRadioButton;
|
private Button runEveryBuildRadioButton;
|
||||||
private Button expandRelativePathCheckBox;
|
private Button expandRelativePathCheckBox;
|
||||||
private Button applyToProjectCheckBox;
|
|
||||||
|
private Button scopeProjectRadioButton;
|
||||||
|
private Button scopeFolderRadioButton;
|
||||||
|
private Button scopeFileRadioButton;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -157,25 +161,97 @@ public final class GCCBuildCommandParserOptionPage extends AbstractLanguageSetti
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Group resourceScopeGroup = new Group(composite, SWT.NONE);
|
||||||
{
|
{
|
||||||
applyToProjectCheckBox = new Button(composite, SWT.CHECK);
|
// resourceScopeGroup.setText("Define scope of discovered entries");
|
||||||
applyToProjectCheckBox.setText("Apply discovered settings on project level");
|
// resourceScopeGroup.setText("Apply discovered entries to");
|
||||||
|
resourceScopeGroup.setText("Scope to keep discovered entries");
|
||||||
|
resourceScopeGroup.setLayout(new GridLayout(2, false));
|
||||||
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
|
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||||
gd.horizontalSpan = 2;
|
gd.horizontalSpan = 2;
|
||||||
applyToProjectCheckBox.setLayoutData(gd);
|
resourceScopeGroup.setLayoutData(gd);
|
||||||
|
}
|
||||||
|
|
||||||
// applyToProjectCheckBox.setSelection(provider.isExpandRelativePaths());
|
{
|
||||||
// applyToProjectCheckBox.setEnabled(fEditable);
|
scopeFileRadioButton = new Button(resourceScopeGroup, SWT.RADIO);
|
||||||
applyToProjectCheckBox.setSelection(false);
|
scopeFileRadioButton.setText("Per file, use when settings vary for different files");
|
||||||
applyToProjectCheckBox.setEnabled(false);
|
// applyToResourceRadioButton.setText("File level, use when settings vary for different files");
|
||||||
applyToProjectCheckBox.addSelectionListener(new SelectionAdapter() {
|
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||||
|
gd.horizontalSpan = 2;
|
||||||
|
scopeFileRadioButton.setLayoutData(gd);
|
||||||
|
|
||||||
|
scopeFileRadioButton.setSelection(provider.getResourceScope() == AbstractBuildCommandParser.ResourceScope.FILE);
|
||||||
|
scopeFileRadioButton.setEnabled(fEditable);
|
||||||
|
scopeFileRadioButton.addSelectionListener(new SelectionAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void widgetSelected(SelectionEvent e) {
|
public void widgetSelected(SelectionEvent e) {
|
||||||
boolean enabled = applyToProjectCheckBox.getSelection();
|
boolean enabled = scopeFileRadioButton.getSelection();
|
||||||
AbstractBuildCommandParser provider = getRawProvider();
|
AbstractBuildCommandParser provider = getRawProvider();
|
||||||
if (enabled != provider.isResolvingPaths()) {
|
if (enabled != (provider.getResourceScope() == AbstractBuildCommandParser.ResourceScope.FILE)) {
|
||||||
AbstractBuildCommandParser selectedProvider = getWorkingCopy(providerId);
|
AbstractBuildCommandParser selectedProvider = getWorkingCopy(providerId);
|
||||||
selectedProvider.setResolvingPaths(enabled);
|
selectedProvider.setResourceScope(AbstractBuildCommandParser.ResourceScope.FILE);
|
||||||
|
providerTab.refreshItem(selectedProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void widgetDefaultSelected(SelectionEvent e) {
|
||||||
|
widgetSelected(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
scopeFolderRadioButton = new Button(resourceScopeGroup, SWT.RADIO);
|
||||||
|
scopeFolderRadioButton.setText("Per folder, use when settings are the same for all files in a folder");
|
||||||
|
// applyToEnclosingFolderRadioButton.setText("Enclosing folder, use when settings are the same for all files in a folder");
|
||||||
|
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||||
|
gd.horizontalSpan = 2;
|
||||||
|
scopeFolderRadioButton.setLayoutData(gd);
|
||||||
|
|
||||||
|
scopeFolderRadioButton.setSelection(provider.getResourceScope() == AbstractBuildCommandParser.ResourceScope.FOLDER);
|
||||||
|
scopeFolderRadioButton.setEnabled(fEditable);
|
||||||
|
scopeFolderRadioButton.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
boolean enabled = scopeFolderRadioButton.getSelection();
|
||||||
|
AbstractBuildCommandParser provider = getRawProvider();
|
||||||
|
if (enabled != (provider.getResourceScope() == AbstractBuildCommandParser.ResourceScope.FOLDER)) {
|
||||||
|
AbstractBuildCommandParser selectedProvider = getWorkingCopy(providerId);
|
||||||
|
selectedProvider.setResourceScope(AbstractBuildCommandParser.ResourceScope.FOLDER);
|
||||||
|
providerTab.refreshItem(selectedProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void widgetDefaultSelected(SelectionEvent e) {
|
||||||
|
widgetSelected(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
scopeProjectRadioButton = new Button(resourceScopeGroup, SWT.RADIO);
|
||||||
|
scopeProjectRadioButton.setText("Per project, use when settings are the same for all files in the project");
|
||||||
|
// applyToProjectRadioButton.setText("Project level, use when settings are the same for all files in the project");
|
||||||
|
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||||
|
gd.horizontalSpan = 2;
|
||||||
|
scopeProjectRadioButton.setLayoutData(gd);
|
||||||
|
|
||||||
|
scopeProjectRadioButton.setSelection(provider.getResourceScope() == AbstractBuildCommandParser.ResourceScope.PROJECT);
|
||||||
|
scopeProjectRadioButton.setEnabled(fEditable);
|
||||||
|
scopeProjectRadioButton.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
boolean enabled = scopeProjectRadioButton.getSelection();
|
||||||
|
AbstractBuildCommandParser provider = getRawProvider();
|
||||||
|
if (enabled != (provider.getResourceScope() == AbstractBuildCommandParser.ResourceScope.PROJECT)) {
|
||||||
|
AbstractBuildCommandParser selectedProvider = getWorkingCopy(providerId);
|
||||||
|
selectedProvider.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT);
|
||||||
providerTab.refreshItem(selectedProvider);
|
providerTab.refreshItem(selectedProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue