1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-12 02:35:37 +02:00

Bug 580009 - Resolve superclass for tc level options in rc configs

Change-Id: I03093b687bc36610ab7cf83d7e75401ac7a4fdfe
This commit is contained in:
William Riley 2022-05-26 12:01:08 +01:00
parent 1ec4ae52c1
commit 133c81e979
3 changed files with 234 additions and 1 deletions

View file

@ -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>

View file

@ -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);
}
}

View file

@ -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$
}
}
}