diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuildCommandParserTest.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuildCommandParserTest.java
index f18c4eb9b0d..a5b7670a4f6 100644
--- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuildCommandParserTest.java
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuildCommandParserTest.java
@@ -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();
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuildCommandParser.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuildCommandParser.java
index efaf4829f8c..4c4f52c1729 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuildCommandParser.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuildCommandParser.java
@@ -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:
+ *
- {@code AbstractBuildCommandParser.ResourceScope.FILE} - apply entries to the file being parsed.
+ *
- {@code AbstractBuildCommandParser.ResourceScope.FOLDER} - apply entries to the enclosing folder.
+ *
- {@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:
+ *
- {@code AbstractBuildCommandParser.ResourceScope.FILE} - apply entries to the file being parsed.
+ *
- {@code AbstractBuildCommandParser.ResourceScope.FOLDER} - apply entries to the enclosing folder.
+ *
- {@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 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()}.
*/
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/GCCBuildCommandParserOptionPage.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/GCCBuildCommandParserOptionPage.java
index b3e7a70615a..c438cb93082 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/GCCBuildCommandParserOptionPage.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/GCCBuildCommandParserOptionPage.java
@@ -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);
}
}