diff --git a/NewAndNoteworthy/CHANGELOG-API.md b/NewAndNoteworthy/CHANGELOG-API.md index adc3e2cbc30..5c13a9fc69d 100644 --- a/NewAndNoteworthy/CHANGELOG-API.md +++ b/NewAndNoteworthy/CHANGELOG-API.md @@ -31,6 +31,12 @@ Added method allowing extenders to customize the Core Build output directory nam #### org.eclipse.cdt.core.build.CBuildConfiguration +Removed field: + +* org.eclipse.cdt.core.build.ICBuildConfiguration.DEFAULT_NAME + +This constant was removed because the name "default" is no longer used to name Core Build configurations. Naming now follows the pattern in getCBuildConfigName, described above. + Removed method: * org.eclipse.cdt.core.build.CBuildConfiguration.setLaunchMode(String) diff --git a/build/org.eclipse.cdt.core.autotools.core/src/org/eclipse/cdt/core/autotools/core/AutotoolsBuildConfigurationProvider.java b/build/org.eclipse.cdt.core.autotools.core/src/org/eclipse/cdt/core/autotools/core/AutotoolsBuildConfigurationProvider.java index 2d157d5f71e..6bb1028fd12 100644 --- a/build/org.eclipse.cdt.core.autotools.core/src/org/eclipse/cdt/core/autotools/core/AutotoolsBuildConfigurationProvider.java +++ b/build/org.eclipse.cdt.core.autotools.core/src/org/eclipse/cdt/core/autotools/core/AutotoolsBuildConfigurationProvider.java @@ -14,30 +14,21 @@ package org.eclipse.cdt.core.autotools.core; -import java.util.HashMap; -import java.util.Map; - import org.eclipse.cdt.core.autotools.core.internal.Activator; import org.eclipse.cdt.core.build.CBuildConfigUtils; import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.build.ICBuildConfigurationManager; import org.eclipse.cdt.core.build.ICBuildConfigurationProvider; import org.eclipse.cdt.core.build.IToolChain; -import org.eclipse.cdt.core.build.IToolChainManager; import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Platform; import org.eclipse.launchbar.core.target.ILaunchTarget; -import org.eclipse.launchbar.core.target.ILaunchTargetManager; public class AutotoolsBuildConfigurationProvider implements ICBuildConfigurationProvider { - public static final String ID = Activator.PLUGIN_ID + ".provider"; //$NON-NLS-1$ - private final ILaunchTargetManager launchTargetManager = Activator.getService(ILaunchTargetManager.class); - @Override public String getId() { return ID; @@ -46,31 +37,10 @@ public class AutotoolsBuildConfigurationProvider implements ICBuildConfiguration @Override public ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config, String name) throws CoreException { if (config.getName().equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) { - IToolChain toolChain = null; - - // try the toolchain for the local target - Map properties = new HashMap<>(); - properties.put(IToolChain.ATTR_OS, Platform.getOS()); - properties.put(IToolChain.ATTR_ARCH, Platform.getOSArch()); - IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); - for (IToolChain tc : toolChainManager.getToolChainsMatching(properties)) { - toolChain = tc; - break; - } - - // local didn't work, try and find one that does - if (toolChain == null) { - for (IToolChain tc : toolChainManager.getToolChainsMatching(new HashMap<>())) { - toolChain = tc; - break; - } - } - - if (toolChain != null) { - return new AutotoolsBuildConfiguration(config, name, toolChain, "run", //$NON-NLS-1$ - launchTargetManager.getLocalLaunchTarget()); - } - // No valid combinations + /* + * IBuildConfiguration configs with name IBuildConfiguration.DEFAULT_CONFIG_NAME + * are not supported to avoid build output directory being named "default". + */ return null; } AutotoolsBuildConfiguration autotoolsConfig = new AutotoolsBuildConfiguration(config, name); diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakefileBuildConfigurationProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakefileBuildConfigurationProvider.java index a05fbf7f107..9a5c79e3874 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakefileBuildConfigurationProvider.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakefileBuildConfigurationProvider.java @@ -10,31 +10,23 @@ *******************************************************************************/ package org.eclipse.cdt.make.core; -import java.util.HashMap; -import java.util.Map; - import org.eclipse.cdt.core.build.CBuildConfigUtils; import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.build.ICBuildConfigurationManager; import org.eclipse.cdt.core.build.ICBuildConfigurationProvider; import org.eclipse.cdt.core.build.IToolChain; -import org.eclipse.cdt.core.build.IToolChainManager; import org.eclipse.cdt.core.build.StandardBuildConfiguration; import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Platform; import org.eclipse.launchbar.core.target.ILaunchTarget; -import org.eclipse.launchbar.core.target.ILaunchTargetManager; /** * @since 7.4 */ public class MakefileBuildConfigurationProvider implements ICBuildConfigurationProvider { - public static final String ID = "org.eclipse.cdt.make.core.provider"; //$NON-NLS-1$ - private final ILaunchTargetManager launchTargetManager = MakeCorePlugin.getService(ILaunchTargetManager.class); @Override public String getId() { @@ -44,33 +36,11 @@ public class MakefileBuildConfigurationProvider implements ICBuildConfigurationP @Override public ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config, String name) throws CoreException { if (config.getName().equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) { - IToolChain toolChain = null; - - // try the toolchain for the local target - Map properties = new HashMap<>(); - properties.put(IToolChain.ATTR_OS, Platform.getOS()); - properties.put(IToolChain.ATTR_ARCH, Platform.getOSArch()); - IToolChainManager toolChainManager = MakeCorePlugin.getService(IToolChainManager.class); - for (IToolChain tc : toolChainManager.getToolChainsMatching(properties)) { - toolChain = tc; - break; - } - - // local didn't work, try and find one that does - if (toolChain == null) { - for (IToolChain tc : toolChainManager.getToolChainsMatching(new HashMap<>())) { - toolChain = tc; - break; - } - } - - if (toolChain != null) { - return new StandardBuildConfiguration(config, name, toolChain, "run", //$NON-NLS-1$ - launchTargetManager.getLocalLaunchTarget()); - } else { - // No valid combinations - return null; - } + /* + * IBuildConfiguration configs with name IBuildConfiguration.DEFAULT_CONFIG_NAME + * are not supported to avoid build output directory being named "default". + */ + return null; } return new StandardBuildConfiguration(config, name); } diff --git a/build/org.eclipse.cdt.meson.core/src/org/eclipse/cdt/internal/meson/core/MesonBuildConfigurationProvider.java b/build/org.eclipse.cdt.meson.core/src/org/eclipse/cdt/internal/meson/core/MesonBuildConfigurationProvider.java index e54025f3358..92f7ea2b2b7 100644 --- a/build/org.eclipse.cdt.meson.core/src/org/eclipse/cdt/internal/meson/core/MesonBuildConfigurationProvider.java +++ b/build/org.eclipse.cdt.meson.core/src/org/eclipse/cdt/internal/meson/core/MesonBuildConfigurationProvider.java @@ -22,7 +22,6 @@ import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.build.ICBuildConfigurationManager; import org.eclipse.cdt.core.build.ICBuildConfigurationProvider; import org.eclipse.cdt.core.build.IToolChain; -import org.eclipse.cdt.core.build.IToolChainManager; import org.eclipse.cdt.meson.core.Activator; import org.eclipse.cdt.meson.core.IMesonToolChainFile; import org.eclipse.cdt.meson.core.IMesonToolChainManager; @@ -30,15 +29,12 @@ import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Platform; import org.eclipse.launchbar.core.target.ILaunchTarget; import org.eclipse.launchbar.core.target.ILaunchTargetManager; public class MesonBuildConfigurationProvider implements ICBuildConfigurationProvider { public static final String ID = "org.eclipse.cdt.meson.core.provider"; //$NON-NLS-1$ - private final static ILaunchTargetManager launchTargetManager = Activator.getService(ILaunchTargetManager.class); - private IMesonToolChainManager manager = Activator.getService(IMesonToolChainManager.class); @Override public String getId() { @@ -49,31 +45,10 @@ public class MesonBuildConfigurationProvider implements ICBuildConfigurationProv public synchronized ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config, String name) throws CoreException { if (config.getName().equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) { - IToolChain toolChain = null; - - // try the toolchain for the local target - Map properties = new HashMap<>(); - properties.put(IToolChain.ATTR_OS, Platform.getOS()); - properties.put(IToolChain.ATTR_ARCH, Platform.getOSArch()); - IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); - for (IToolChain tc : toolChainManager.getToolChainsMatching(properties)) { - toolChain = tc; - break; - } - - // local didn't work, try and find one that does - if (toolChain == null) { - for (IToolChain tc : toolChainManager.getToolChainsMatching(new HashMap<>())) { - toolChain = tc; - break; - } - } - - if (toolChain != null) { - return new MesonBuildConfiguration(config, name, toolChain, "run", //$NON-NLS-1$ - launchTargetManager.getLocalLaunchTarget()); - } - // No valid combinations + /* + * IBuildConfiguration configs with name IBuildConfiguration.DEFAULT_CONFIG_NAME + * are not supported to avoid build output directory being named "default". + */ return null; } MesonBuildConfiguration mesonConfig = new MesonBuildConfiguration(config, name); @@ -85,6 +60,7 @@ public class MesonBuildConfigurationProvider implements ICBuildConfigurationProv } if (tcFile != null && !toolChain.equals(tcFile.getToolChain())) { // toolchain changed + ILaunchTargetManager launchTargetManager = Activator.getService(ILaunchTargetManager.class); return new MesonBuildConfiguration(config, name, tcFile.getToolChain(), tcFile, mesonConfig.getLaunchMode(), launchTargetManager.getLocalLaunchTarget()); } @@ -95,6 +71,7 @@ public class MesonBuildConfigurationProvider implements ICBuildConfigurationProv public ICBuildConfiguration createCBuildConfiguration(IProject project, IToolChain toolChain, String launchMode, ILaunchTarget launchTarget, IProgressMonitor monitor) throws CoreException { // get matching toolchain file if any + IMesonToolChainManager manager = Activator.getService(IMesonToolChainManager.class); IMesonToolChainFile file = manager.getToolChainFileFor(toolChain); if (file == null) { Map properties = new HashMap<>(); diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/CMakeBuildConfigurationProvider.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/CMakeBuildConfigurationProvider.java index afcac256b9a..e03ee20c9aa 100644 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/CMakeBuildConfigurationProvider.java +++ b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/CMakeBuildConfigurationProvider.java @@ -21,12 +21,10 @@ import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.build.ICBuildConfigurationManager; import org.eclipse.cdt.core.build.ICBuildConfigurationProvider; import org.eclipse.cdt.core.build.IToolChain; -import org.eclipse.cdt.core.build.IToolChainManager; import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Platform; import org.eclipse.launchbar.core.target.ILaunchTarget; import org.eclipse.launchbar.core.target.ILaunchTargetManager; @@ -76,35 +74,12 @@ public class CMakeBuildConfigurationProvider implements ICBuildConfigurationProv @Override public synchronized ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config, String name) throws CoreException { - ILaunchTargetManager launchTargetManager = Activator.getService(ILaunchTargetManager.class); if (config.getName().equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) { - IToolChain toolChain = null; - - // try the toolchain for the local target - Map properties = new HashMap<>(); - properties.put(IToolChain.ATTR_OS, Platform.getOS()); - properties.put(IToolChain.ATTR_ARCH, Platform.getOSArch()); - IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); - for (IToolChain tc : toolChainManager.getToolChainsMatching(properties)) { - toolChain = tc; - break; - } - - // local didn't work, try and find one that does - if (toolChain == null) { - for (IToolChain tc : toolChainManager.getToolChainsMatching(new HashMap<>())) { - toolChain = tc; - break; - } - } - - if (toolChain != null) { - return createCMakeBuildConfiguration(config, name, toolChain, null, "run", //$NON-NLS-1$ - launchTargetManager.getLocalLaunchTarget()); - } else { - // No valid combinations - return null; - } + /* + * IBuildConfiguration configs with name IBuildConfiguration.DEFAULT_CONFIG_NAME + * are not supported to avoid build output directory being named "default". + */ + return null; } CMakeBuildConfiguration cmakeConfig = createCMakeBuildConfiguration(config, name); ICMakeToolChainFile tcFile = cmakeConfig.getToolChainFile(); @@ -115,6 +90,7 @@ public class CMakeBuildConfigurationProvider implements ICBuildConfigurationProv } if (tcFile != null && !toolChain.equals(tcFile.getToolChain())) { // toolchain changed + ILaunchTargetManager launchTargetManager = Activator.getService(ILaunchTargetManager.class); return createCMakeBuildConfiguration(config, name, tcFile.getToolChain(), tcFile, cmakeConfig.getLaunchMode(), launchTargetManager.getLocalLaunchTarget()); } else { diff --git a/core/org.eclipse.cdt.core.tests/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core.tests/META-INF/MANIFEST.MF index 60c05e1e01b..6472bc7bf54 100644 --- a/core/org.eclipse.cdt.core.tests/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.core.tests/META-INF/MANIFEST.MF @@ -47,7 +47,11 @@ Require-Bundle: org.eclipse.core.resources, org.eclipse.cdt.debug.core, org.eclipse.cdt.cmake.core, org.eclipse.debug.core, - org.eclipse.launchbar.core;bundle-version="[3.0.0,4.0.0)" + org.eclipse.launchbar.core;bundle-version="[3.0.0,4.0.0)", + org.eclipse.cdt.make.core, + org.eclipse.cdt.meson.core, + org.eclipse.cdt.core.autotools.core, + org.mockito.mockito-core Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName Bundle-RequiredExecutionEnvironment: JavaSE-17 diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/build/DefaultBuildConfigurationNameTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/build/DefaultBuildConfigurationNameTests.java new file mode 100644 index 00000000000..dc303eb4bc7 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/build/DefaultBuildConfigurationNameTests.java @@ -0,0 +1,375 @@ +/******************************************************************************* + * Copyright (c) 2025 Renesas Electronics Europe. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.cdt.core.build; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.anyMap; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.cdt.cmake.core.CMakeBuildConfigurationProvider; +import org.eclipse.cdt.cmake.core.CMakeNature; +import org.eclipse.cdt.core.CCProjectNature; +import org.eclipse.cdt.core.CProjectNature; +import org.eclipse.cdt.core.autotools.core.AutotoolsBuildConfigurationProvider; +import org.eclipse.cdt.core.testplugin.ResourceHelper; +import org.eclipse.cdt.core.testplugin.util.BaseTestCase5; +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.launch.CoreBuildLaunchBarTracker; +import org.eclipse.cdt.internal.core.build.CBuildConfigurationManager; +import org.eclipse.cdt.internal.meson.core.MesonBuildConfigurationProvider; +import org.eclipse.cdt.make.core.MakefileBuildConfigurationProvider; +import org.eclipse.core.resources.IBuildConfiguration; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.launchbar.core.ILaunchBarManager; +import org.eclipse.launchbar.core.internal.LaunchBarManager; +import org.eclipse.launchbar.core.target.ILaunchTargetManager; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +/** + * Test for IDE-82683-REQ-024 #1084 part of #1000 in CDT 12.0.0. Test Part 1. + * + * Tests that a ICBuildConfiguration is never created with the default name. + * + * @see {@link DefaultBuildConfigurationNameTestsNoToolchains} + * + */ +public class DefaultBuildConfigurationNameTests extends BaseTestCase5 { + private static final String TC_BUILD_CONFIG_NAME_FRAGMENT = "MockToolchainBuildConfigName"; + private IProject project; + private IToolChain mockToolchain; + private ICBuildConfigurationManager configManager = CDebugCorePlugin.getService(ICBuildConfigurationManager.class); + private ILaunchTargetManager launchTargetManager = CDebugCorePlugin.getService(ILaunchTargetManager.class); + private IToolChainManager toolchainManager = CDebugCorePlugin.getService(IToolChainManager.class); + private ILaunchBarManager launchBarManager = CDebugCorePlugin.getService(ILaunchBarManager.class); + + @BeforeEach + public void setup() throws Exception { + /* + * Remove any discovered toolchains that happen to be installed on the host. This is because + * some test hosts may have a gcc installed and others not. So if we remove that gcc and do not + * rely on it and instead setup our mocked toolchain instead, the test conditions are easier to control. + */ + removeDiscoveredToolchains(); + + CBuildConfigurationManager cbm = (CBuildConfigurationManager) configManager; + cbm.reset(); + + /* + * Copied from LaunchBarManagerTest.startupTest() + * Make sure the manager starts up and defaults everything to null + */ + LaunchBarManager manager = new LaunchBarManager(false); + manager.init(); + assertThat(manager.getActiveLaunchDescriptor(), is(nullValue())); + assertThat(manager.getActiveLaunchMode(), is(nullValue())); + assertThat(manager.getActiveLaunchTarget(), is(nullValue())); + + /* + * Key to repeatedly running tests with the same initial conditions is to reset the + * CoreBuildLaunchBarTracker, so the launchbar controls are as they would be in a new + * workspace. + */ + CDebugCorePlugin.getDefault().resetCoreBuildLaunchBarTracker(); + + // Add a mocked toolchain, which acts like a gcc toolchain and has Platform related OS ans ARCH. + addMockToolchain(); + // Create a CMake project + project = createCMakeProject(); + waitForLaunchBarTracker(); + } + + /** + * This test describes the behaviour BEFORE IDE-82683-REQ-024 was fixed, hence why it is disabled. + * + * Project creation lifecycle: + * + * Project created: + * The project's active IBuildConfiguration defaults to DEFAULT_CONFIG_NAME. + * CModelManager.create(IFile, ICProject) where file==.project + * CModelManager.getBinaryParser(IProject) calls + * config.getAdapter(ICBuildConfiguration.class); + * CBuildConfigAdapterFactory.getAdapter(Object, Class) + * CBuildConfigurationManager.getBuildConfiguration(IBuildConfiguration) with IBuildConfiguration==DEFAULT_CONFIG_NAME + * + * When IToolChainManager contains a valid toolchain: + * When CBuildConfigurationManager.getBuildConfiguration(IBuildConfiguration buildConfig) is called, + * the IBuildConfiguration.DEFAULT_CONFIG_NAME buildConfig is used to get the project's ICBuildConfigurationProvider. + * + * The provider.getCBuildConfiguration(buildConfig, configName) with configName="default" is called which creates + * a new ICBuildConfiguration. This is how the "first" config is often named "default". + * + * This test is disabled and retained for historical and documentation purposes to show the previous behaviour prior to + * fixing IDE-82683-REQ-024. + */ + @Test + @Disabled("This test is permanently disabled and retained for historical and documentation purposes to show" + + " the previous behaviour prior to fixing IDE-82683-REQ-024.") + public void getBuildConfigurationDefaultName() throws Exception { + IBuildConfiguration buildConfig = project.getActiveBuildConfig(); + assertThat(buildConfig.getName(), is(IBuildConfiguration.DEFAULT_CONFIG_NAME)); + + // This calls CBuildConfigurationManager.getBuildConfiguration(IBuildConfiguration) + ICBuildConfiguration iCBuildConfig = buildConfig.getAdapter(ICBuildConfiguration.class); + // Expected: the ICBuildConfiguration is associated with the default IBuildConfiguration + assertThat(iCBuildConfig.getBuildConfiguration(), is(buildConfig)); + // Expected: the CBuildConfiguration has name "default". + CBuildConfiguration cBuildConfig = (CBuildConfiguration) iCBuildConfig; + assertThat(cBuildConfig.getName(), is("default")); // ICBuildConfiguration.DEFAULT_NAME + } + + /** + * This test describes the behaviour AFTER IDE-82683-REQ-024 was fixed. + * + * Project creation and CoreBuildLaunchBarTracker lifecycle: + * + * When the project is being created and the .project file is created, the getBinaryParser(), using + * the projects IBuildConfiguration which defaults to DEFAULT_CONFIG_NAME, makes the getAdapter call: + * + * ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class); + * + * This eventually calls into: + * + * CBuildConfigurationManager.getBuildConfiguration(IBuildConfiguration) + * + * The first time into getBuildConfiguration, with the default IBuildConfiguration, execution falls through without + * creating an ICBuildConfiguration. When this happens, the default IBuildConfiguration is "quarantined" into the + * noConfigs "bin" so the default IBuildConfiguration is not used on subsequent calls. + * + * Callstack: + * CModelManager.create(IFile, ICProject) line: 364 + * CModelManager.createBinaryFile(IFile) line: 679 + * CModelManager.getBinaryParser(IProject) line: 619 + * BuildConfiguration.getAdapter(Class) line: 109 + * ... + * CBuildConfigurationManager.getBuildConfiguration(IBuildConfiguration) line: 249 + * + * Project creation continues in IProject.setDescription(...), eventually calling + * ILaunchBarManager.launchObjectChanged(Object) when the launchbar controls are updated + * with the new project contents; active launch descriptor, launch target and mode.This + * triggers CoreBuildLaunchBarTracker.setActiveBuildConfig(...) to fire. + * + * CoreBuildLaunchBarTracker is pivotal in creating new ICBuildConfiguration configs, according + * to the active launchbar controls. + * + * The CoreBuildLaunchBarTracker runs as a workspace Job and gets the project's IBuildConfiguration configs. + * At this point there is only the default IBuildConfiguration. + * + * The CoreBuildLaunchBarTracker calls into the CBuildConfigurationManager.getBuildConfiguration(IBuildConfiguration) + * to get the ICBuildConfiguration for this IBuildConfiguration. Because it's already been quarantined, it returns + * null. + * + * So the CoreBuildLaunchBarTracker requests the CBuildConfigurationManager to create a new ICBuildConfiguration + * by calling: + * CBuildConfigurationManager.getBuildConfiguration(IProject, IToolChain, String, ILaunchTarget, IProgressMonitor) + * This calls the project's ICBuildConfigurationProvider to create a new IBuildConfiguration/ICBuildConfiguration + * combination using: + * + * ICBuildConfigurationProvider.createCBuildConfiguration(IProject, IToolChain, String, ILaunchTarget, IProgressMonitor) + * + * The CoreBuildLaunchBarTracker finally sets the new ICBuildConfiguration as the active configuration. + * + * Callstack: + * Project.setDescription(IProjectDescription, IProgressMonitor) line: 1378 + * ... + * LaunchBarManager.launchObjectChanged(Object) line: 398 + * ... + * CoreBuildLaunchBarTracker.setActiveBuildConfig(ILaunchMode, ILaunchDescriptor, ILaunchTarget) line: 99 + */ + @Test + public void getBuildConfigurationOneToolchainsActiveBuildConfig() throws Exception { + // Expected: the CoreBuildLaunchBarTracker has run and already set the correct active build config + IBuildConfiguration activeBuildConfig = project.getActiveBuildConfig(); + assertThat(activeBuildConfig.getName(), is(not(IBuildConfiguration.DEFAULT_CONFIG_NAME))); + + // Expected: cBuildConfigName=cmake.run.MockToolchainBuildConfigName.Local + final String expectedCBuildConfigName = "cmake." + ILaunchManager.RUN_MODE + // + "." + TC_BUILD_CONFIG_NAME_FRAGMENT + // + "." + ILaunchTargetManager.localLaunchTargetId; + // Expected: buildConfig name=org.eclipse.cdt.cmake.core.provider/cmake.run.MockToolchainBuildConfigName.Local + final String expectedBuildConfigName = CMakeBuildConfigurationProvider.ID + // + "/" + expectedCBuildConfigName; + assertThat(activeBuildConfig.getName(), is(expectedBuildConfigName)); + + // This calls CBuildConfigurationManager.getBuildConfiguration(IBuildConfiguration) + ICBuildConfiguration iCBuildConfig = activeBuildConfig.getAdapter(ICBuildConfiguration.class); + // Expected: the ICBuildConfiguration is associated with the active IBuildConfiguration + assertThat(iCBuildConfig.getBuildConfiguration(), is(activeBuildConfig)); + + CBuildConfiguration cBuildConfig = (CBuildConfiguration) iCBuildConfig; + assertThat(cBuildConfig.getName(), is(expectedCBuildConfigName)); + } + + /** + * Tests that ICBuildConfiguration configuration is never created with the default name when using + * CBuildConfigAdapterFactory.getAdapter(Object, Class) + * + * Expect: returned ICBuildConfiguration is null. + */ + @Test + public void getBuildConfigurationOneToolchainsNonDefaultBuildConfig() throws Exception { + // Get the default build config from the project (it always has one) + IBuildConfiguration buildConfig = project.getBuildConfig(IBuildConfiguration.DEFAULT_CONFIG_NAME); + + // This calls CBuildConfigurationManager.getBuildConfiguration(IBuildConfiguration) + ICBuildConfiguration cBuildConfig = buildConfig.getAdapter(ICBuildConfiguration.class); + assertThat(cBuildConfig, is(nullValue())); + } + + /** + * Tests that ICBuildConfiguration configuration is never created with the default name when using + * ICBuildConfigurationManager.getBuildConfiguration(IBuildConfiguration) + * + * Expect: returned ICBuildConfiguration is null. + **/ + @Test + public void getBuildConfiguration() throws Exception { + // Get the default build config from the project (it always has one) + IBuildConfiguration buildConfig = project.getBuildConfig(IBuildConfiguration.DEFAULT_CONFIG_NAME); + + ICBuildConfiguration cBuildConfig = configManager.getBuildConfiguration(buildConfig); + assertThat(cBuildConfig, is(nullValue())); + } + + /** + * Tests that CMake build configurations are never created with the default name. + * + *

Test summary: + * Get the project's default IBuildConfiguration. + * Use this and the name "default" as params and call the provider directly, + * ICBuildConfigurationProvider.getCBuildConfiguration(IBuildConfiguration, String). + * Expect: returned ICBuildConfiguration is null. + */ + @Test + public void cMakeBuildConfigurationProviderGetCBuildConfiguration() throws Exception { + ICBuildConfigurationProvider provider = new CMakeBuildConfigurationProvider(); + // Get the default build config from the project (it always has one) + IBuildConfiguration buildConfig = project.getBuildConfig(IBuildConfiguration.DEFAULT_CONFIG_NAME); + ICBuildConfiguration cBuildConfig = provider.getCBuildConfiguration(buildConfig, "default"); + assertThat(cBuildConfig, is(nullValue())); + } + + /** + * Tests that Makefile build configurations are never created with the default name. + * + * @see "Test summary:" {@link #cMakeBuildConfigurationProviderGetCBuildConfiguration()} + */ + @Test + public void makefileBuildConfigurationProviderGetCBuildConfiguration() throws Exception { + ICBuildConfigurationProvider provider = new MakefileBuildConfigurationProvider(); + // Get the default build config from the project (it always has one) + IBuildConfiguration buildConfig = project.getBuildConfig(IBuildConfiguration.DEFAULT_CONFIG_NAME); + ICBuildConfiguration cBuildConfig = provider.getCBuildConfiguration(buildConfig, "default"); + assertThat(cBuildConfig, is(nullValue())); + } + + /** + * Tests that Meson build configurations are never created with the default name. + * + * @see "Test summary:" {@link #cMakeBuildConfigurationProviderGetCBuildConfiguration()} + */ + @Test + public void mesonBuildConfigurationProviderGetCBuildConfiguration() throws Exception { + ICBuildConfigurationProvider provider = new MesonBuildConfigurationProvider(); + // Get the default build config from the project (it always has one) + IBuildConfiguration buildConfig = project.getBuildConfig(IBuildConfiguration.DEFAULT_CONFIG_NAME); + ICBuildConfiguration cBuildConfig = provider.getCBuildConfiguration(buildConfig, "default"); + assertThat(cBuildConfig, is(nullValue())); + } + + /** + * Tests that Autotools build configurations are never created with the default name. + * + * @see "Test summary:" {@link #cMakeBuildConfigurationProviderGetCBuildConfiguration()} + */ + @Test + public void autotoolsBuildConfigurationProviderGetCBuildConfiguration() throws Exception { + ICBuildConfigurationProvider provider = new AutotoolsBuildConfigurationProvider(); + // Get the default build config from the project (it always has one) + IBuildConfiguration buildConfig = project.getBuildConfig(IBuildConfiguration.DEFAULT_CONFIG_NAME); + ICBuildConfiguration cBuildConfig = provider.getCBuildConfiguration(buildConfig, "default"); + assertThat(cBuildConfig, is(nullValue())); + } + + // Test infrastructure... + + private void waitForLaunchBarTracker() throws OperationCanceledException, InterruptedException { + Job.getJobManager().join(CoreBuildLaunchBarTracker.JOB_FAMILY_CORE_BUILD_LAUNCH_BAR_TRACKER, null); + } + + private IProject createCMakeProject() throws Exception { + // Create a plain Eclipse project + IProject project = ResourceHelper.createProject(this.getName()); + // Add C/C++ and CMake natures to make it a CMake project + IProjectDescription description = project.getDescription(); + description.setNatureIds( + new String[] { CProjectNature.C_NATURE_ID, CCProjectNature.CC_NATURE_ID, CMakeNature.ID }); + project.setDescription(description, null); + return project; + } + + /** + * Add a mocked toolchain, which acts like a gcc toolchain and has Platform related OS ans ARCH. + */ + private void addMockToolchain() throws CoreException { + // Setup a toolchain ready to use for creating the ICBuildConfiguration + mockToolchain = mock(IToolChain.class); + when(mockToolchain.getProperty(anyString())).thenAnswer(new Answer<>() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + String key = invocation.getArgument(0); + return switch (key) { + case IToolChain.ATTR_OS -> Platform.getOS(); + case IToolChain.ATTR_ARCH -> Platform.getOSArch(); + case "name" -> null; // name=Local + default -> null; + }; + } + }); + when(mockToolchain.getTypeId()).thenReturn("tc_typeId"); + when(mockToolchain.getId()).thenReturn("tcId"); + when(mockToolchain.matches(anyMap())).thenCallRealMethod(); + when(mockToolchain.getBuildConfigNameFragment()).thenReturn(TC_BUILD_CONFIG_NAME_FRAGMENT); + when(mockToolchain.getName()).thenReturn("MockToolchainName"); + + // Add our mocked toolchain + toolchainManager.addToolChain(mockToolchain); + // Expected: there is a single toolchain now + assertThat(toolchainManager.getAllToolChains().size(), is(1)); + } + + private void removeDiscoveredToolchains() throws CoreException { + Collection allToolChains = toolchainManager.getAllToolChains(); + for (IToolChain toolchain : new ArrayList<>(allToolChains)) { + // System.out.println(String.format("Removing toolchain '%s' for test '%s'", toolchain.getName(), getName())); + toolchainManager.removeToolChain(toolchain); + } + // Expected: there are no toolchains + assertThat(toolchainManager.getAllToolChains().size(), is(0)); + } +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/build/DefaultBuildConfigurationNameTestsNoToolchains.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/build/DefaultBuildConfigurationNameTestsNoToolchains.java new file mode 100644 index 00000000000..3330507453f --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/build/DefaultBuildConfigurationNameTestsNoToolchains.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2025 Renesas Electronics Europe. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.cdt.core.build; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.cdt.cmake.core.CMakeNature; +import org.eclipse.cdt.core.CCProjectNature; +import org.eclipse.cdt.core.CProjectNature; +import org.eclipse.cdt.core.testplugin.ResourceHelper; +import org.eclipse.cdt.core.testplugin.util.BaseTestCase5; +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.launch.CoreBuildLaunchBarTracker; +import org.eclipse.cdt.internal.core.build.CBuildConfigurationManager; +import org.eclipse.core.resources.IBuildConfiguration; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.launchbar.core.ILaunchBarManager; +import org.eclipse.launchbar.core.internal.LaunchBarManager; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * Test for IDE-82683-REQ-024 #1084 part of #1000 in CDT 12.0.0. Test Part 2. + * + * Tests that a ICBuildConfiguration is never created with the default name when + * no toolchains are available. + * + * @see {@link DefaultBuildConfigurationNameTests} + * + */ +public class DefaultBuildConfigurationNameTestsNoToolchains extends BaseTestCase5 { + private IProject project; + private ICBuildConfigurationManager configManager = CDebugCorePlugin.getService(ICBuildConfigurationManager.class); + private IToolChainManager toolchainManager = CDebugCorePlugin.getService(IToolChainManager.class); + private ILaunchBarManager launchBarManager = CDebugCorePlugin.getService(ILaunchBarManager.class); + + @BeforeEach + public void setup() throws Exception { + /* + * Remove any discovered toolchains that happen to be installed on the host. This is because + * some test hosts may have a gcc installed and others not. So if we remove that gcc and do not + * rely on it and instead setup our mocked toolchain instead, the test conditions are easier to control. + */ + removeDiscoveredToolchains(); + + CBuildConfigurationManager cbm = (CBuildConfigurationManager) configManager; + cbm.reset(); + + /* + * Copied from LaunchBarManagerTest.startupTest() + * Make sure the manager starts up and defaults everything to null + */ + LaunchBarManager manager = new LaunchBarManager(false); + manager.init(); + assertThat(manager.getActiveLaunchDescriptor(), is(nullValue())); + assertThat(manager.getActiveLaunchMode(), is(nullValue())); + assertThat(manager.getActiveLaunchTarget(), is(nullValue())); + + /* + * Key to repeatedly running tests with the same initial conditions is to reset the + * CoreBuildLaunchBarTracker, so the launchbar controls are as they would be in a new + * workspace. + */ + CDebugCorePlugin.getDefault().resetCoreBuildLaunchBarTracker(); + } + + /** + * Test that when calling {@link ICBuildConfigurationManager#getBuildConfiguration(IBuildConfiguration)} + * when there are no toolchains available, the active IBuildConfiguration becomes set to "buildError/!". + * + * Test to confirm assumptions about the project's IBuildConfiguration lifecycle when no toolchains are + * installed and a project is created. + * + * Behaviour before IDE-82683-REQ-024 fixed AND after fix. + * When IToolChainManager contains no valid toolchains: + * + * After project creation, the project's active IBuildConfiguration name defaults to + * IBuildConfiguration.DEFAULT_CONFIG_NAME. + * + * After project creation, the first interaction with the Core Build system is through the call: + * config.getAdapter(ICBuildConfiguration.class), where config is a IBuildConfiguration. + * This happens when the .project file is added in CModelManager.getBinaryParser(IProject). + * getAdapter calls CBuildConfigurationManager.getBuildConfiguration(IBuildConfiguration) with + * IBuildConfiguration==DEFAULT_CONFIG_NAME. + * + * When CBuildConfigurationManager.getBuildConfiguration(IBuildConfiguration buildConfig) is called, + * the provider.getCBuildConfiguration(buildConfig, configName) returns null because it has no toolchain. + * The CBuildConfigurationManager then quarantines this default buildConfig in the noConfigs bin and returns null. + * + * Later, when CoreBuildLaunchBarTracker triggers, it detects there are no toolchains available and so creates + * a new IBuildConfiguration with name "buildError/!" and then a special error ICBuildConfiguration, ErrorBuildConfiguration, + * with the message "No Toolchain found for Target Local". + * This new IBuildConfiguration/ICBuildConfiguration combo is then added as the active config using + * ProjectDescription.setActiveBuildConfig(String). + * + * Then project.getActiveBuildConfig() returns the buildConfig with name "buildError/!". + * + * And buildConfig.getAdapter(ICBuildConfiguration.class) returns the active buildConfig's ICBuildConfiguration + * which is instanceof ErrorBuildConfiguration. + */ + @Test + public void getBuildConfigurationNoToolchainsErrorBuildConfig() throws Exception { + // Create a CMake project, without any toolchains installed. + project = createCMakeProject(); + + waitForLaunchBarTracker(); + + IBuildConfiguration buildConfig = project.getActiveBuildConfig(); + assertThat(buildConfig.getName(), is(not(IBuildConfiguration.DEFAULT_CONFIG_NAME))); + assertThat(buildConfig.getName(), is("buildError/!")); + System.out.println( + "getBuildConfigurationNoToolchainsErrorBuildConfig::buildConfig.getName()=" + buildConfig.getName()); + + // This calls CBuildConfigurationManager.getBuildConfiguration(IBuildConfiguration) + ICBuildConfiguration iCBuildConfig = buildConfig.getAdapter(ICBuildConfiguration.class); + System.out.println(); + // expected: config should be an instanceof ErrorBuildConfiguration, but no way to get the name to check. + assertThat(iCBuildConfig, is(instanceOf(ErrorBuildConfiguration.class))); + // expected: the buildConfig should be the buildError one + assertThat(iCBuildConfig.getBuildConfiguration().getName(), is("buildError/!")); + } + + /** + * Performs the same test as {@link #getBuildConfigurationNoToolchainsErrorBuildConfig()}. + * The test exists so we can prove multiple test runs function correctly and that + * initial conditions are correctly controlled and reset. + */ + @Test + public void getBuildConfigurationNoToolchainsErrorBuildConfig2() throws Exception { + getBuildConfigurationNoToolchainsErrorBuildConfig(); + } + + // Test infrastructure... + + private void waitForLaunchBarTracker() throws OperationCanceledException, InterruptedException { + Job.getJobManager().join(CoreBuildLaunchBarTracker.JOB_FAMILY_CORE_BUILD_LAUNCH_BAR_TRACKER, null); + } + + private IProject createCMakeProject() throws Exception { + // Create a plain Eclipse project + IProject project = ResourceHelper.createProject(this.getName()); + // Add C/C++ and CMake natures to make it a CMake project + IProjectDescription description = project.getDescription(); + description.setNatureIds( + new String[] { CProjectNature.C_NATURE_ID, CCProjectNature.CC_NATURE_ID, CMakeNature.ID }); + project.setDescription(description, null); + return project; + } + + private void removeDiscoveredToolchains() throws CoreException { + Collection allToolChains = toolchainManager.getAllToolChains(); + for (IToolChain toolchain : new ArrayList<>(allToolChains)) { + // System.out.println(String.format("Removing toolchain '%s' for test '%s'", toolchain.getName(), getName())); + toolchainManager.removeToolChain(toolchain); + } + // Expected: there are no toolchains + assertThat(toolchainManager.getAllToolChains().size(), is(0)); + } +} diff --git a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF index 4b5e7adaa94..5883f5c456b 100644 --- a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF @@ -66,6 +66,7 @@ Export-Package: org.eclipse.cdt.core, org.eclipse.cdt.testsrunner.boost, org.eclipse.cdt.testsrunner.qttest", org.eclipse.cdt.internal.core.browser;x-friends:="org.eclipse.cdt.ui", + org.eclipse.cdt.internal.core.build;x-friends:="org.eclipse.cdt.core.tests", org.eclipse.cdt.internal.core.cdtvariables;x-internal:=true, org.eclipse.cdt.internal.core.dom;x-internal:=true, org.eclipse.cdt.internal.core.dom.ast.tag;x-internal:=true, diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfiguration.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfiguration.java index 4c9f44ecb49..fc1cc39c679 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfiguration.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfiguration.java @@ -35,12 +35,6 @@ import org.eclipse.launchbar.core.target.ILaunchTarget; */ public interface ICBuildConfiguration extends IAdaptable, IScannerInfoProvider { - /** - * CDT doesn't like that the Platform default config name is an empty string. - * It needs a real name for the name of the build directory, for example. - */ - public static final String DEFAULT_NAME = "default"; //$NON-NLS-1$ - /** * @since 6.4 */ diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationProvider.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationProvider.java index 5d30d3f1f65..c0b3e5233a8 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationProvider.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationProvider.java @@ -37,9 +37,11 @@ public interface ICBuildConfigurationProvider { /** * Returns the Core Build configuration that owns this Platform Build configuration. * - * @param buildConfig Platform Build Configuration. Must not be null. + * @param buildConfig Platform Build Configuration. Must not be null. Configs with the name + * {@link IBuildConfiguration#DEFAULT_CONFIG_NAME} are ignored. * @param cBuildConfigName Name to give the ICBuildConfiguration. Must not be null. - * @return a Core Build configuration. + * @return a Core Build configuration or null if buildConfig has name + * {@link IBuildConfiguration#DEFAULT_CONFIG_NAME}. * @throws CoreException if this method fails. Reasons include: *

    *
  • Toolchain is missing,
  • diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java index fddb838df65..4548f78885e 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java @@ -96,6 +96,15 @@ public class CBuildConfigurationManager private Map configs = new HashMap<>(); private Set noConfigs = new HashSet<>(); + /** + * Resets configs. Used for testing only. + * @noreference This method is not intended to be referenced by clients. + */ + public void reset() { + configs = new HashMap<>(); + noConfigs = new HashSet<>(); + } + public CBuildConfigurationManager() { ResourcesPlugin.getWorkspace().addResourceChangeListener(this); } @@ -199,18 +208,13 @@ public class CBuildConfigurationManager IBuildConfiguration buildConfig = iterator.next(); String configName = null; ICBuildConfigurationProvider provider = null; - if (IBuildConfiguration.DEFAULT_CONFIG_NAME.equals(buildConfig.getName())) { - configName = ICBuildConfiguration.DEFAULT_NAME; - provider = getProvider(buildConfig.getProject()); - } else { - String[] segments = buildConfig.getName().split("/"); //$NON-NLS-1$ - if (segments.length == 2) { - String providerId = segments[0]; - configName = segments[1]; - Provider delegate = getProviderDelegate(providerId); - if (delegate != null && delegate.supports(buildConfig.getProject())) { - provider = delegate.getProvider(); - } + String[] segments = buildConfig.getName().split("/"); //$NON-NLS-1$ + if (segments.length == 2) { + String providerId = segments[0]; + configName = segments[1]; + Provider delegate = getProviderDelegate(providerId); + if (delegate != null && delegate.supports(buildConfig.getProject())) { + provider = delegate.getProvider(); } } @@ -248,18 +252,13 @@ public class CBuildConfigurationManager if (config == null) { String configName = null; ICBuildConfigurationProvider provider = null; - if (IBuildConfiguration.DEFAULT_CONFIG_NAME.equals(buildConfig.getName())) { - configName = ICBuildConfiguration.DEFAULT_NAME; - provider = getProvider(buildConfig.getProject()); - } else { - String[] segments = buildConfig.getName().split("/"); //$NON-NLS-1$ - if (segments.length == 2) { - String providerId = segments[0]; - configName = segments[1]; - Provider delegate = getProviderDelegate(providerId); - if (delegate != null && delegate.supports(buildConfig.getProject())) { - provider = delegate.getProvider(); - } + String[] segments = buildConfig.getName().split("/"); //$NON-NLS-1$ + if (segments.length == 2) { + String providerId = segments[0]; + configName = segments[1]; + Provider delegate = getProviderDelegate(providerId); + if (delegate != null && delegate.supports(buildConfig.getProject())) { + provider = delegate.getProvider(); } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java index b59a4c325cb..bafe2d60568 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java @@ -117,6 +117,14 @@ public class CDebugCorePlugin extends Plugin { return plugin; } + /** + * Resets CoreBuildLaunchBarTracker. Used for testing only. + * @noreference This method is not intended to be referenced by clients. + */ + public void resetCoreBuildLaunchBarTracker() { + coreBuildLaunchBarTracker.reset(); + } + /** * Returns the workspace instance. * diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/launch/CoreBuildLaunchBarTracker.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/launch/CoreBuildLaunchBarTracker.java index efbb295485b..841d340a4cf 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/launch/CoreBuildLaunchBarTracker.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/launch/CoreBuildLaunchBarTracker.java @@ -76,6 +76,16 @@ public class CoreBuildLaunchBarTracker implements ILaunchBarListener, ILaunchTar targetManager.addListener(this); } + /** + * Resets CoreBuildLaunchBarTracker. Used for testing only. + * @noreference This method is not intended to be referenced by clients. + */ + public void reset() { + lastMode = null; + lastDescriptor = null; + lastTarget = null; + } + /** * @since 8.4 */ diff --git a/launchbar/org.eclipse.launchbar.core/src/org/eclipse/launchbar/core/internal/LaunchBarManager.java b/launchbar/org.eclipse.launchbar.core/src/org/eclipse/launchbar/core/internal/LaunchBarManager.java index ae22cc1e739..06f185cfe62 100644 --- a/launchbar/org.eclipse.launchbar.core/src/org/eclipse/launchbar/core/internal/LaunchBarManager.java +++ b/launchbar/org.eclipse.launchbar.core/src/org/eclipse/launchbar/core/internal/LaunchBarManager.java @@ -89,7 +89,7 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene } // called from unit tests to ensure everything is inited - LaunchBarManager(boolean doInit) { + public LaunchBarManager(boolean doInit) { launchTargetManager = getLaunchTargetManager(); launchTargetManager.addListener(this); if (doInit) { @@ -122,7 +122,7 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene } // When testing, call this after setting up the mocks. - void init() throws CoreException { + public void init() throws CoreException { try { // Fetch the desc order before the init messes it up IEclipsePreferences store = getPreferenceStore(); @@ -219,7 +219,7 @@ public class LaunchBarManager implements ILaunchBarManager, ILaunchTargetListene descriptorTypes.put(typeInfo.getId(), typeInfo); if (configProviders.get(typeInfo.getId()) == null) { // Make sure we initialize the list - configProviders.put(typeInfo.getId(), new ArrayList()); + configProviders.put(typeInfo.getId(), new ArrayList<>()); } } else if (elementName.equals("configProvider")) { //$NON-NLS-1$ LaunchConfigProviderInfo info = new LaunchConfigProviderInfo(element);