1
0
Fork 0
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:
Andrew Gvozdev 2012-04-09 17:55:05 -04:00
parent d1e9395955
commit 0755f5870d
3 changed files with 211 additions and 13 deletions

View file

@ -195,6 +195,7 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
assertEquals(null, provider.getLanguageScope());
assertEquals(null, provider.getSettingEntries(null, null, null));
assertEquals("", provider.getCompilerPattern());
assertEquals(AbstractBuildCommandParser.ResourceScope.FILE, provider.getResourceScope());
}
{
@ -218,6 +219,8 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
// setters
provider.setCompilerPattern(CUSTOM_PARAMETER_2);
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
parser.setResolvingPaths(false);
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();
assertTrue(parser.equals(clone));
assertEquals(parser.isResolvingPaths(), clone.isResolvingPaths());
assertEquals(parser.getResourceScope(), clone.getResourceScope());
}
// check 'expand relative paths' flag
@ -251,6 +266,16 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
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()
{
MockBuildCommandParser parser2 = parser.clone();

View file

@ -21,6 +21,10 @@ import org.eclipse.cdt.core.IMarkerGenerator;
import org.eclipse.cdt.core.errorparsers.RegexErrorParser;
import org.eclipse.cdt.core.errorparsers.RegexErrorPattern;
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.
@ -29,12 +33,24 @@ import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
*/
public abstract class AbstractBuildCommandParser extends AbstractLanguageSettingsOutputScanner {
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_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 Pattern OPTIONS_PATTERN = Pattern.compile("-[^\\s\"']*(\\s*((\".*?\")|('.*?')|([^-\\s][^\\s]+)))?"); //$NON-NLS-1$
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}
*/
@ -45,6 +61,8 @@ public abstract class AbstractBuildCommandParser extends AbstractLanguageSetting
};
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.
@ -76,6 +94,85 @@ public abstract class AbstractBuildCommandParser extends AbstractLanguageSetting
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()}.
*/

View file

@ -30,6 +30,7 @@ import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
@ -46,7 +47,10 @@ public final class GCCBuildCommandParserOptionPage extends AbstractLanguageSetti
private Button runOnceRadioButton;
private Button runEveryBuildRadioButton;
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);
applyToProjectCheckBox.setText("Apply discovered settings on project level");
// resourceScopeGroup.setText("Define scope of discovered entries");
// 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);
gd.horizontalSpan = 2;
applyToProjectCheckBox.setLayoutData(gd);
resourceScopeGroup.setLayoutData(gd);
}
// applyToProjectCheckBox.setSelection(provider.isExpandRelativePaths());
// applyToProjectCheckBox.setEnabled(fEditable);
applyToProjectCheckBox.setSelection(false);
applyToProjectCheckBox.setEnabled(false);
applyToProjectCheckBox.addSelectionListener(new SelectionAdapter() {
{
scopeFileRadioButton = new Button(resourceScopeGroup, SWT.RADIO);
scopeFileRadioButton.setText("Per file, use when settings vary for different files");
// applyToResourceRadioButton.setText("File level, use when settings vary for different files");
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
public void widgetSelected(SelectionEvent e) {
boolean enabled = applyToProjectCheckBox.getSelection();
boolean enabled = scopeFileRadioButton.getSelection();
AbstractBuildCommandParser provider = getRawProvider();
if (enabled != provider.isResolvingPaths()) {
if (enabled != (provider.getResourceScope() == AbstractBuildCommandParser.ResourceScope.FILE)) {
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);
}
}