Bug 580009 - Resolve superclass for tc level options in rc configs
Change-Id: I03093b687bc36610ab7cf83d7e75401ac7a4fdfe
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml b/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml
index a16c798..4611ce2 100644
--- a/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml
@@ -9779,5 +9779,69 @@
</configuration>
</projectType>
</extension>
+ <extension
+ point="org.eclipse.cdt.managedbuilder.core.buildDefinitions">
+ <tool
+ id="bug580009.tests.tool"
+ isAbstract="true"
+ isSystem="true"
+ outputs="o"
+ sources="c">
+ <option
+ category="bug580009.tests.tool.optionsCategory"
+ defaultValue="UNSET"
+ id="bug580009.tests.option.string"
+ isAbstract="false"
+ name="Test"
+ resourceFilter="all"
+ value="UNSET"
+ valueType="string">
+ </option>
+ <optionCategory
+ id="bug580009.tests.tool.optionsCategory"
+ name="name1">
+ </optionCategory>
+ </tool>
+ <projectType
+ id="bug580009.tests.ptype"
+ isAbstract="false"
+ isTest="true">
+ <configuration
+ id="bug580009.tests.cfg1"
+ name="cfg1">
+ <toolChain
+ id="bug580009.tests.cfg1.tc2"
+ isAbstract="false"
+ isSystem="false"
+ superClass="bug580009.tests.cfg1.tc">
+ </toolChain>
+ </configuration>
+ </projectType>
+ <toolChain
+ id="bug580009.tests.cfg1.tc"
+ isAbstract="true"
+ isSystem="true">
+ <tool
+ id="bug580009.tests.cfg1.tc.tool"
+ isAbstract="false"
+ superClass="bug580009.tests.tool">
+ </tool>
+ <builder
+ id="bug580009.tests.cfg1.tc.builder"
+ isAbstract="false"
+ isVariableCaseSensitive="false">
+ </builder>
+ <option
+ category="bug580009.tests.cfg1.tc.optionCategory1"
+ id="bug580009.tests.cfg1.tc.option.string"
+ isAbstract="false"
+ valueType="boolean">
+ </option>
+ <optionCategory
+ id="bug580009.tests.cfg1.tc.optionCategory1"
+ name="name">
+ </optionCategory>
+ </toolChain>
+ </extension>
</plugin>
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ResourceBuildCoreTests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ResourceBuildCoreTests.java
index 5adb0f5..5124f00 100644
--- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ResourceBuildCoreTests.java
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ResourceBuildCoreTests.java
@@ -25,10 +25,12 @@
import org.eclipse.cdt.managedbuilder.core.IOptionCategory;
import org.eclipse.cdt.managedbuilder.core.IProjectType;
import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration;
+import org.eclipse.cdt.managedbuilder.core.IResourceInfo;
import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
import org.eclipse.cdt.managedbuilder.core.ManagedCProjectNature;
+import org.eclipse.cdt.managedbuilder.internal.core.ResourceInfo;
import org.eclipse.cdt.managedbuilder.internal.core.Tool;
import org.eclipse.cdt.managedbuilder.testplugin.ManagedBuildTestHelper;
import org.eclipse.core.resources.IFile;
@@ -45,6 +47,7 @@
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
+import org.junit.Assert;
import junit.framework.Test;
import junit.framework.TestCase;
@@ -68,6 +71,7 @@
TestSuite suite = new TestSuite(ResourceBuildCoreTests.class.getName());
suite.addTest(new ResourceBuildCoreTests("testResourceConfigurations"));
suite.addTest(new ResourceBuildCoreTests("testResourceConfigurationReset"));
+ suite.addTest(new ResourceBuildCoreTests("testResourceConfiguration_Bug580009"));
// suite.addTest(new ResourceBuildCoreTests("testResourceConfigurationBuildInfo"));
// suite.addTest(new ResourceBuildCoreTests("testResourceRename"));
return suite;
@@ -969,4 +973,138 @@
removeProject(renamedProjectName2);
}
+ protected IResourceInfo getResourceConfiguration(final IConfiguration config, final IResource resource) {
+
+ IResourceInfo resInfo = config.getResourceInfo(resource.getProjectRelativePath(), true); // 'true' to ensure exact path
+ if (resInfo == null) {
+ // Resource element for path may not yet exist, force-create it
+ resInfo = config.createFolderInfo(resource.getProjectRelativePath());
+ }
+ return resInfo;
+ }
+
+ /**
+ * Test that a folder level resource configuration correctly reloads from disk
+ * @throws Exception
+ */
+ public void testResourceConfiguration_Bug580009() throws Exception {
+
+ // Create a new project
+ IProject project = null;
+
+ try {
+ project = createProject(projectName);
+
+ // Now associate the builder with the project
+ ManagedBuildTestHelper.addManagedBuildNature(project);
+ IProjectDescription description = project.getDescription();
+ // Make sure it has a managed nature
+ if (description != null) {
+ assertTrue(description.hasNature(ManagedCProjectNature.MNG_NATURE_ID));
+ }
+
+ } catch (CoreException e) {
+ fail("Test failed on project creation: " + e.getLocalizedMessage());
+ }
+
+ // Find the base project type definition
+ IProjectType[] projTypes = ManagedBuildManager.getDefinedProjectTypes();
+ IProjectType projType = ManagedBuildManager.getProjectType("bug580009.tests.ptype");
+ assertNotNull(projType);
+
+ // Create the managed-project for our project
+ IManagedProject newProject = ManagedBuildManager.createManagedProject(project, projType);
+ assertEquals(newProject.getName(), projType.getName());
+ assertFalse(newProject.equals(projType));
+ ManagedBuildManager.setNewProjectVersion(project);
+
+ // Create a folder ('hello')
+ IFolder helloFolder = project.getProject().getFolder("hello");
+ if (!helloFolder.exists()) {
+ helloFolder.create(true, true, null);
+ }
+
+ // Get the configurations and make one of them as default configuration.
+ IConfiguration defaultConfig = null;
+ IConfiguration[] configs = projType.getConfigurations();
+ for (int i = 0; i < configs.length; ++i) {
+ // Make the first configuration the default
+ if (i == 0) {
+ defaultConfig = newProject.createConfiguration(configs[i], projType.getId() + "." + i);
+ } else {
+ newProject.createConfiguration(configs[i], projType.getId() + "." + i);
+ }
+ }
+ ManagedBuildManager.setDefaultConfiguration(project, defaultConfig);
+
+ //Set toolchain level option
+ IOption tcOption = defaultConfig.getToolChain().getOptionById("bug580009.tests.cfg1.tc.option.string");
+ ManagedBuildManager.setOption(defaultConfig, defaultConfig.getToolChain(), tcOption, true);
+ ManagedBuildManager.saveBuildInfo(project, true);
+ // Create Resource Configurations for hello.c
+ var resConfig = getResourceConfiguration(defaultConfig, helloFolder);
+
+ // Get the tools associated with the resource 'hello'.
+ ITool[] resTools = resConfig.getTools();
+ assertNotNull(resTools);
+ assertEquals(1, resTools.length);
+
+ // Get the build properties for the resource hello
+ ITool resTool = resTools[0];
+ String defaultResToolFlags = resTool.getToolFlags();
+
+ // Get the Test Option.
+ IOption resDebugOption = resTool.getOptionById("bug580009.tests.option.string");
+
+ // Get the default value of debug option for resource.
+ String defaultResDebugOptVal = resDebugOption.getStringValue();
+
+ // Now, override the value with "bug580009.tests.option.string"
+ IOption newResDebugOption = ManagedBuildManager.setOption(resConfig, resTool, resDebugOption, "SET");
+
+ // Get the overridden value of test option.
+ String newResDebugOptVal = newResDebugOption.getStringValue();
+ String newResToolFlags = resTool.getToolFlags();
+
+ // Make sure, default and overridden values are different.
+ assertNotSame(defaultResDebugOptVal, newResDebugOptVal);
+
+ //Check the config reports custom settings
+ Assert.assertTrue("hasCustomSettings should be true", ((ResourceInfo) resConfig).hasCustomSettings());
+
+ ManagedBuildManager.saveBuildInfo(project, true);
+
+ //Close project
+ project.close(null);
+ project.open(null);
+
+ //Reload configs
+ defaultConfig = ManagedBuildManager.getBuildInfo(project).getDefaultConfiguration();
+ var resInfo = defaultConfig.getResourceInfo(helloFolder.getProjectRelativePath(), true);
+
+ //Check the config still reports custom settings (sanity check)
+ Assert.assertTrue("hasCustomSettings should be true", ((ResourceInfo) resInfo).hasCustomSettings());
+
+ resTools = resInfo.getTools();
+ resTool = resTools[0];
+ resDebugOption = resTool.getOptionBySuperClassId("bug580009.tests.option.string");
+
+ // Set back to default value
+ IOption newResDebugOption2 = ManagedBuildManager.setOption(resInfo, resTool, resDebugOption, "UNSET");
+
+ //Check the config now reports no custom settings
+ Assert.assertFalse("hasCustomSettings should be false", ((ResourceInfo) resInfo).hasCustomSettings());
+
+ ManagedBuildManager.saveBuildInfo(project, true);
+
+ //Check the resource config no longer exists
+ resInfo = defaultConfig.getResourceInfo(helloFolder.getProjectRelativePath(), true);
+ Assert.assertNull("resInfo should be null", resInfo);
+
+ // Close and remove project.
+ ResourceHelper.joinIndexerBeforeCleanup(getName());
+ project.close(null);
+ removeProject(projectName);
+ }
+
}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java
index 74a02ce..dec68cf 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java
@@ -17,6 +17,7 @@
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.internal.core;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -29,6 +30,7 @@
import org.eclipse.cdt.managedbuilder.core.BuildException;
import org.eclipse.cdt.managedbuilder.core.IBuildObject;
import org.eclipse.cdt.managedbuilder.core.IBuildPropertiesRestriction;
+import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IHoldsOptions;
import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement;
import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler;
@@ -511,7 +513,36 @@
if (superClassId != null && superClassId.length() > 0) {
superClass = ManagedBuildManager.getExtensionOption(superClassId);
if (superClass == null) {
- // TODO: Report error
+ /*
+ * This can happen when options are set at the resource level, for a project using a toolchain definition
+ * where there are options at the toolchain level & one or more of those options is set at a
+ * non-default value.
+ *
+ * In these cases the superclass is set to the option from the parent not the extension's ID
+ * Workaround this by searching for any missing superclass IDs at on the parent configs toolchain
+ *
+ * See the "bug580009.tests.cfg1.tc" definition in org.eclipse.cdt.managedbuilder.core.tests for an example
+ */
+ IBuildObject parent = this.getParent();
+ if (parent instanceof IToolChain) {
+ IConfiguration config = ((IToolChain) parent).getParent();
+ IOption foundOption = null;
+ if (config != null) {
+ IToolChain parentToolchain = config.getToolChain();
+ if (parentToolchain != null) {
+ foundOption = parentToolchain.getOptionById(superClassId);
+ }
+ }
+ if (foundOption != null) {
+ superClass = foundOption;
+ } else {
+ ManagedBuilderCorePlugin.log(new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID,
+ MessageFormat.format("Missing superclass \"{0}\" for \"{1}\"", superClassId, getId()))); //$NON-NLS-1$
+ }
+ } else {
+ ManagedBuilderCorePlugin.log(new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID,
+ MessageFormat.format("Missing superclass \"{0}\" for \"{1}\"", superClassId, getId()))); //$NON-NLS-1$
+ }
}
}