diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuiltinSpecsDetectorTest.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuiltinSpecsDetectorTest.java index 8b2899ce615..3d6bfe896f1 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuiltinSpecsDetectorTest.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuiltinSpecsDetectorTest.java @@ -8,7 +8,7 @@ * Contributors: * Andrew Gvozdev - Initial API and implementation *******************************************************************************/ - package org.eclipse.cdt.managedbuilder.language.settings.providers.tests; +package org.eclipse.cdt.managedbuilder.language.settings.providers.tests; import java.util.ArrayList; import java.util.List; @@ -16,6 +16,8 @@ import java.util.List; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager; import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage; +import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider; +import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvidersKeeper; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.settings.model.CIncludePathEntry; import org.eclipse.cdt.core.settings.model.CMacroEntry; @@ -27,8 +29,13 @@ import org.eclipse.cdt.core.settings.model.ICSettingEntry; import org.eclipse.cdt.core.testplugin.ResourceHelper; import org.eclipse.cdt.core.testplugin.util.BaseTestCase; import org.eclipse.cdt.internal.core.Cygwin; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.internal.language.settings.providers.GCCBuiltinSpecsDetectorCygwin; +import org.eclipse.cdt.managedbuilder.language.settings.providers.AbstractBuiltinSpecsDetector; import org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector; +import org.eclipse.cdt.managedbuilder.testplugin.ManagedBuildTestHelper; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; @@ -39,6 +46,8 @@ import org.eclipse.core.runtime.Path; */ public class GCCBuiltinSpecsDetectorTest extends BaseTestCase { private static final String LANGUAGE_ID_C = GCCLanguage.ID; + private static final String SAMPLE_COMMAND = "NEW_COMMAND"; + private static final String PROJECT_TYPE_EXECUTABLE_GNU = "cdt.managedbuild.target.gnu.exe"; /** * Mock GCCBuiltinSpecsDetector to gain access to protected methods. @@ -68,6 +77,13 @@ public class GCCBuiltinSpecsDetectorTest extends BaseTestCase { } } + class MockGCCBuiltinSpecsDetectorCommandResolver extends GCCBuiltinSpecsDetector { + @Override + public String resolveCommand(String languageId) throws CoreException { + return super.resolveCommand(languageId); + } + } + @Override protected void setUp() throws Exception { super.setUp(); @@ -97,15 +113,9 @@ public class GCCBuiltinSpecsDetectorTest extends BaseTestCase { * Test expansion of variables in build command. */ public void testGCCBuiltinSpecsDetector_ResolvedCommand() throws Exception { - class MockGCCBuiltinSpecsDetectorLocal extends GCCBuiltinSpecsDetector { - @Override - public String resolveCommand(String languageId) throws CoreException { - return super.resolveCommand(languageId); - } - } { // check ${COMMAND} and ${INPUTS} - MockGCCBuiltinSpecsDetectorLocal detector = new MockGCCBuiltinSpecsDetectorLocal(); + MockGCCBuiltinSpecsDetectorCommandResolver detector = new MockGCCBuiltinSpecsDetectorCommandResolver(); detector.setLanguageScope(new ArrayList() {{add(LANGUAGE_ID_C);}}); detector.setCommand("${COMMAND} -E -P -v -dD ${INPUTS}"); @@ -115,7 +125,7 @@ public class GCCBuiltinSpecsDetectorTest extends BaseTestCase { } { // check ${EXT} - MockGCCBuiltinSpecsDetectorLocal detector = new MockGCCBuiltinSpecsDetectorLocal(); + MockGCCBuiltinSpecsDetectorCommandResolver detector = new MockGCCBuiltinSpecsDetectorCommandResolver(); detector.setLanguageScope(new ArrayList() {{add(LANGUAGE_ID_C);}}); detector.setCommand("${COMMAND} -E -P -v -dD file.${EXT}"); @@ -125,12 +135,12 @@ public class GCCBuiltinSpecsDetectorTest extends BaseTestCase { } { // check expansion of environment variables - MockGCCBuiltinSpecsDetectorLocal detector = new MockGCCBuiltinSpecsDetectorLocal(); + MockGCCBuiltinSpecsDetectorCommandResolver detector = new MockGCCBuiltinSpecsDetectorCommandResolver(); detector.setLanguageScope(new ArrayList() {{add(LANGUAGE_ID_C);}}); String command = "cmd --env1=${CWD} --env2=${OS}"; detector.setCommand(command); String resolvedCommand = detector.resolveCommand(LANGUAGE_ID_C); - + ICdtVariableManager varManager = CCorePlugin.getDefault().getCdtVariableManager(); String expected = varManager.resolveValue(command, "", null, null); // confirm that "expected" expanded @@ -139,12 +149,12 @@ public class GCCBuiltinSpecsDetectorTest extends BaseTestCase { } { // check expansion of eclipse and MBS variables - MockGCCBuiltinSpecsDetectorLocal detector = new MockGCCBuiltinSpecsDetectorLocal(); + MockGCCBuiltinSpecsDetectorCommandResolver detector = new MockGCCBuiltinSpecsDetectorCommandResolver(); detector.setLanguageScope(new ArrayList() {{add(LANGUAGE_ID_C);}}); String command = "cmd --eclipse-var=${workspace_loc} --mbs-var=${WorkspaceDirPath}"; detector.setCommand(command); String resolvedCommand = detector.resolveCommand(LANGUAGE_ID_C); - + ICdtVariableManager varManager = CCorePlugin.getDefault().getCdtVariableManager(); String expected = varManager.resolveValue(command, "", null, null); // confirm that "expected" expanded @@ -404,8 +414,9 @@ public class GCCBuiltinSpecsDetectorTest extends BaseTestCase { */ public void testGCCBuiltinSpecsDetector_Includes_SymbolicLinkUp() throws Exception { // do not test on systems where symbolic links are not supported - if (!ResourceHelper.isSymbolicLinkSupported()) + if (!ResourceHelper.isSymbolicLinkSupported()) { return; + } // Create model project and folders to test String projectName = getName(); @@ -527,4 +538,63 @@ public class GCCBuiltinSpecsDetectorTest extends BaseTestCase { assertEquals(1, entries.size()); } + /** + * Test expansion of variable ${COMMAND} for case when the command was modified in tool-chain. + */ + public void test_GCCBuiltinSpecsDetector_ResolveModifiedCommand() throws Exception { + // create a new project + IProject project = ManagedBuildTestHelper.createProject(this.getName(), PROJECT_TYPE_EXECUTABLE_GNU); + + { + // create a mock specs detector + MockGCCBuiltinSpecsDetectorCommandResolver detector = new MockGCCBuiltinSpecsDetectorCommandResolver(); + detector.setCommand("${COMMAND}"); + String command = ((AbstractBuiltinSpecsDetector)detector).getCommand(); + assertEquals("${COMMAND}", command); + assertTrue(!command.equals(SAMPLE_COMMAND)); + // assign the mock specs detector to the first configuration + ICProjectDescription prjDescriptionWritable = CoreModel.getDefault().getProjectDescription(project, true); + assertNotNull(prjDescriptionWritable); + ICConfigurationDescription[] cfgDescriptions = prjDescriptionWritable.getConfigurations(); + assertTrue(cfgDescriptions.length > 0); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + List providers = new ArrayList(); + providers.add(detector); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + // change the default command in all the tools of the toolchain + IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription(cfgDescription); + assertNotNull(cfg); + ITool[] tools = cfg.getTools(); + assertTrue(tools.length > 0); + for (ITool tool : tools) { + tool.setToolCommand(SAMPLE_COMMAND); + assertEquals(SAMPLE_COMMAND, tool.getToolCommand()); + } + // save project description + CoreModel.getDefault().setProjectDescription(project, prjDescriptionWritable); + } + + { + // double-check that the new command made its way to the tools + ICProjectDescription prjDescription = CoreModel.getDefault().getProjectDescription(project, false); + assertNotNull(prjDescription); + ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations(); + assertTrue(cfgDescriptions.length > 0); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription(cfgDescription); + assertNotNull(cfg); + ITool[] tools = cfg.getTools(); + for (ITool tool : tools) { + assertEquals(SAMPLE_COMMAND, tool.getToolCommand()); + } + // verify that the new command is picked by the provider + List providers = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + assertEquals(1, providers.size()); + ILanguageSettingsProvider provider = providers.get(0); + assertTrue(provider instanceof MockGCCBuiltinSpecsDetectorCommandResolver); + String command = ((MockGCCBuiltinSpecsDetectorCommandResolver)provider).resolveCommand(LANGUAGE_ID_C); + assertEquals(SAMPLE_COMMAND, command); + } + } + } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/ToolchainBuiltinSpecsDetector.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/ToolchainBuiltinSpecsDetector.java index e66575db44c..cb4ccc7639b 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/ToolchainBuiltinSpecsDetector.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/ToolchainBuiltinSpecsDetector.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Map; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IInputType; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.IToolChain; @@ -54,20 +55,37 @@ public abstract class ToolchainBuiltinSpecsDetector extends AbstractBuiltinSpecs * This returns the first tool found. */ private ITool getTool(String languageId) { - ITool langTool = toolMap.get(languageId); - if (langTool != null) { - return langTool; + ITool tool = toolMap.get(languageId); + if (tool != null) { + return tool; } - String toolchainId = getToolchainId(); - for (IToolChain toolchain = ManagedBuildManager.getExtensionToolChain(toolchainId);toolchain != null;toolchain = toolchain.getSuperClass()) { - ITool tool = getTool(languageId, toolchain); + String toolchainId = null; + IToolChain toolchain = null; + if (currentCfgDescription != null) { + IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription(currentCfgDescription); + toolchain = cfg != null ? cfg.getToolChain() : null; + toolchainId = toolchain != null ? toolchain.getId() : null; + } + if (toolchain == null) { + toolchainId = getToolchainId(); + toolchain = ManagedBuildManager.getExtensionToolChain(toolchainId); + } + for (;toolchain != null;toolchain = toolchain.getSuperClass()) { + tool = getTool(languageId, toolchain); if (tool != null) { - return tool; + break; } } - ManagedBuilderCorePlugin.error("Unable to find tool in toolchain=" + toolchainId + " for language=" + languageId); //$NON-NLS-1$ //$NON-NLS-2$ - return null; + if (currentCfgDescription == null && tool != null) { + // cache only for global providers which use extension tool-chains that can not change + toolMap.put(languageId, tool); + } + + if (tool == null) { + ManagedBuilderCorePlugin.error("Unable to find tool in toolchain=" + toolchainId + " for language=" + languageId); //$NON-NLS-1$ //$NON-NLS-2$ + } + return tool; } /** @@ -81,7 +99,6 @@ public abstract class ToolchainBuiltinSpecsDetector extends AbstractBuiltinSpecs for (IInputType inType : inputTypes) { String lang = inType.getLanguageId(tool); if (languageId.equals(lang)) { - toolMap.put(languageId, tool); return tool; } }