diff options
3 files changed, 234 insertions, 1 deletions
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml b/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml index a16c798d21c..4611ce2a8d0 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 5adb0f5c1ed..5124f00b814 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.IOption; 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.CoreException; 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 @@ public class ResourceBuildCoreTests extends TestCase { 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 @@ public class ResourceBuildCoreTests extends TestCase { 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 74a02ce33ff..dec68cf9b44 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.internal.core.SafeStringInterner; 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 @@ public class Option extends BuildObject implements IOption, IBuildPropertiesRest 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$ + } } } |