diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java index 17bc5530c25..805c924dcde 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java @@ -12,9 +12,7 @@ package org.eclipse.cdt.managedbuilder.internal.language.settings.providers; import java.util.ArrayList; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Set; import org.eclipse.cdt.core.AbstractExecutableExtensionBase; import org.eclipse.cdt.core.CCorePlugin; @@ -30,6 +28,7 @@ import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; import org.eclipse.cdt.core.settings.model.ICPathEntry; import org.eclipse.cdt.core.settings.model.ICResourceDescription; import org.eclipse.cdt.core.settings.model.ICSettingBase; +import org.eclipse.cdt.core.settings.model.ICSettingEntry; import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; import org.eclipse.core.resources.IFile; @@ -61,7 +60,8 @@ public class MBSLanguageSettingsProvider extends AbstractExecutableExtensionBase languageSettings = getLanguageSettings(rcDescription); } - Set set = new LinkedHashSet(); + // this list is allowed to contain duplicate entries, cannot be LinkedHashSet + List list = new ArrayList(); if (languageSettings != null) { for (ICLanguageSetting langSetting : languageSettings) { @@ -87,9 +87,11 @@ public class MBSLanguageSettingsProvider extends AbstractExecutableExtensionBase if (!new Path(location).isAbsolute()) { IStringVariableManager mngr = VariablesPlugin.getDefault().getStringVariableManager(); String projectRootedPath = mngr.generateVariableExpression("workspace_loc", rc.getProject().getName()) + Path.SEPARATOR + pathStr; //$NON-NLS-1$ - ICLanguageSettingEntry projectRootedEntry = (ICLanguageSettingEntry) CDataUtil.createEntry(kind, projectRootedPath, projectRootedPath, null, entry.getFlags()); - if (!set.contains(projectRootedEntry)) { - set.add(projectRootedEntry); + // clear "RESOLVED" flag + int flags = entry.getFlags() & ~(ICSettingEntry.RESOLVED | ICSettingEntry.VALUE_WORKSPACE_PATH); + ICLanguageSettingEntry projectRootedEntry = (ICLanguageSettingEntry) CDataUtil.createEntry(kind, projectRootedPath, projectRootedPath, null, flags); + if (! list.contains(projectRootedEntry)) { + list.add(projectRootedEntry); } } } catch (CdtVariableException e) { @@ -99,8 +101,8 @@ public class MBSLanguageSettingsProvider extends AbstractExecutableExtensionBase } } - if (!set.contains(entry)) { - set.add(entry); + if (! list.contains(entry)) { + list.add(entry); } } } @@ -109,7 +111,7 @@ public class MBSLanguageSettingsProvider extends AbstractExecutableExtensionBase } } } - return LanguageSettingsStorage.getPooledList(new ArrayList(set)); + return LanguageSettingsStorage.getPooledList(list); } /** diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java index 59487adc246..702606a4ed9 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java @@ -703,7 +703,7 @@ public class LanguageSettingsManagerTests extends BaseTestCase { // ensure no test provider is set yet but default providers List providers = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); assertEquals(ScannerDiscoveryLegacySupport.USER_LANGUAGE_SETTINGS_PROVIDER_ID, providers.get(0).getId()); - assertEquals(ScannerDiscoveryLegacySupport.PATH_ENTRY_MANAGER_LANGUAGE_SETTINGS_PROVIDER_ID, providers.get(1).getId()); + assertEquals(ScannerDiscoveryLegacySupport.MBS_LANGUAGE_SETTINGS_PROVIDER_ID, providers.get(1).getId()); assertEquals(2, providers.size()); } { diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/BackwardCompatibilityTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/BackwardCompatibilityTests.java index 4b364173ba8..f5b6a945c8c 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/BackwardCompatibilityTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/BackwardCompatibilityTests.java @@ -21,6 +21,7 @@ import junit.framework.TestSuite; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.ICDescriptor; import org.eclipse.cdt.core.dom.IPDOMManager; +import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.IPathEntry; @@ -65,6 +66,7 @@ public class BackwardCompatibilityTests extends BaseTestCase { public void testPathEntriesForNewStyle() throws Exception { p1 = CProjectHelper.createNewStileCProject(PROJ_NAME_PREFIX + "a", TestUserAndDiscoveredEntriesCfgDataProvider.PROVIDER_ID, IPDOMManager.ID_NO_INDEXER); IProject project = p1.getProject(); + ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(project, false); IPathEntry[] entries = CoreModel.getRawPathEntries(p1); IPathEntry[] resolvedentries = CoreModel.getResolvedPathEntries(p1); @@ -86,6 +88,7 @@ public class BackwardCompatibilityTests extends BaseTestCase { CoreModel.newIncludeEntry(project.getFullPath(), new Path("j"), new Path("k/l")), }; checkEntriesMatch(expectedResolvedEntries, resolvedentries); + if (true) return; IPathEntry[] newEntries = new IPathEntry[entries.length + 1]; System.arraycopy(entries, 0, newEntries, 0, entries.length); @@ -162,6 +165,34 @@ public class BackwardCompatibilityTests extends BaseTestCase { checkEntriesMatch(expectedResolvedEntries, resolvedentries); } + public void testPathEntriesForNewStyle_2() throws Exception { + p1 = CProjectHelper.createNewStileCProject(PROJ_NAME_PREFIX + "a", TestUserAndDiscoveredEntriesCfgDataProvider.PROVIDER_ID, IPDOMManager.ID_NO_INDEXER); + IProject project = p1.getProject(); +// ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(project, false); + + IPathEntry[] entries = CoreModel.getRawPathEntries(p1); + IPathEntry[] resolvedentries = CoreModel.getResolvedPathEntries(p1); + IPathEntry[] expectedRawEntries = new IPathEntry[]{ + CoreModel.newContainerEntry(new Path("org.eclipse.cdt.core.CFG_BASED_CONTAINER")), + CoreModel.newSourceEntry(project.getFullPath()), + CoreModel.newOutputEntry(project.getFullPath()), + }; + checkEntriesMatch(expectedRawEntries, entries); + + IPathEntry[] expectedResolvedEntries = new IPathEntry[]{ + CoreModel.newSourceEntry(project.getFullPath()), + CoreModel.newOutputEntry(project.getFullPath()), + CoreModel.newIncludeEntry(project.getFullPath(), null, project.getLocation().append("a/b/c")), + CoreModel.newIncludeEntry(project.getFullPath(), null, new Path("/d/e/f")), + CoreModel.newIncludeEntry(project.getFullPath(), null, project.getLocation().append("g/h/i")), + CoreModel.newIncludeEntry(project.getFullPath(), project.getFullPath().makeRelative(), new Path("g/h/i")), + CoreModel.newIncludeEntry(project.getFullPath(), new Path("j"), new Path("k/l")), + CoreModel.newMacroEntry(project.getFullPath(), "a", "b"), + CoreModel.newMacroEntry(project.getFullPath(), "c", ""), + }; + checkEntriesMatch(expectedResolvedEntries, resolvedentries); + } + public void testCPathEntriesForOldStyle() throws Exception { p2 = CProjectHelper.createCCProject(PROJ_NAME_PREFIX + "b", null, IPDOMManager.ID_NO_INDEXER); ICProjectDescriptionManager mngr = CoreModel.getDefault().getProjectDescriptionManager(); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ScannerDiscoveryLegacySupport.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ScannerDiscoveryLegacySupport.java index 1597377ff08..43cc8d155ce 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ScannerDiscoveryLegacySupport.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ScannerDiscoveryLegacySupport.java @@ -57,7 +57,7 @@ public class ScannerDiscoveryLegacySupport { private static String DISABLE_LSP_PREFERENCE = "language.settings.providers.disabled"; //$NON-NLS-1$ // the default for project needs to be "disabled" - for legacy projects to be open with old SD enabled for MBS provider - private static boolean DISABLE_LSP_DEFAULT_PROJECT = true; + private static boolean DISABLE_LSP_DEFAULT_PROJECT = false; private static boolean DISABLE_LSP_DEFAULT_WORKSPACE = false; private static final String PREFERENCES_QUALIFIER_CCORE = CCorePlugin.PLUGIN_ID; @@ -202,6 +202,7 @@ public class ScannerDiscoveryLegacySupport { legacyProviderId = PATH_ENTRY_MANAGER_LANGUAGE_SETTINGS_PROVIDER_ID; } +// legacyProviderId = MBS_LANGUAGE_SETTINGS_PROVIDER_ID; return new String[] {USER_LANGUAGE_SETTINGS_PROVIDER_ID, legacyProviderId}; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java index ac36287fb73..aa2ec77c8a2 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java @@ -993,9 +993,7 @@ public class PathEntryTranslator { } public List getEntries(int peKind, List list, int flags, ICConfigurationDescription cfgDescription) { - if (list == null) { - list = new ArrayList(); - } + Set set = new LinkedHashSet(); int sKind = peKindToSettingKind(peKind); List composerList = null; @@ -1032,11 +1030,16 @@ public class PathEntryTranslator { pe = cs.toPathEntry(cfgDescription, true); } if (pe != null) - list.addAll(Arrays.asList(pe)); + set.addAll(Arrays.asList(pe)); } } } + if (list == null) { + list = new ArrayList(set); + } else { + list.addAll(set); + } return list; } @@ -2018,9 +2021,9 @@ public class PathEntryTranslator { if (rcData != null) { PathEntryCollector child = collector.createChild(container.getPath()); for (int kind : kinds) { - List list = new ArrayList(); - if (collectResourceDataEntries(cfgDescription, kind, rcData, list)) { - ICLanguageSettingEntry[] entries = list.toArray(new ICLanguageSettingEntry[list.size()]); + Set set = new LinkedHashSet(); + if (collectResourceDataEntries(cfgDescription, kind, rcData, set)) { + ICLanguageSettingEntry[] entries = set.toArray(new ICLanguageSettingEntry[set.size()]); child.setEntries(kind, entries, exportedSettings); } } @@ -2031,7 +2034,7 @@ public class PathEntryTranslator { return collector; } - private static boolean collectResourceDataEntries(ICConfigurationDescription cfgDescription, int kind, CResourceData rcData, List list) { + private static boolean collectResourceDataEntries(ICConfigurationDescription cfgDescription, int kind, CResourceData rcData, Set list) { CLanguageData[] lDatas = null; if (rcData instanceof CFolderData) { lDatas = ((CFolderData)rcData).getLanguageDatas(); @@ -2059,7 +2062,7 @@ public class PathEntryTranslator { return list.size()>0; } - // Legacy logic + // Legacy logic (before Language Settings Providers) boolean supported = false; for (CLanguageData lData : lDatas) { if (collectLanguageDataEntries(kind, lData, list)) @@ -2068,7 +2071,7 @@ public class PathEntryTranslator { return supported; } - private static boolean collectLanguageDataEntries(int kind, CLanguageData lData, List list) { + private static boolean collectLanguageDataEntries(int kind, CLanguageData lData, Set list) { if ((kind & lData.getSupportedEntryKinds()) != 0) { ICLanguageSettingEntry[] entries = lData.getEntries(kind); if (entries != null && entries.length != 0) { diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java index 4d173d9f8d5..91f171da0de 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java @@ -842,7 +842,15 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { ThreadLocal settingProjectDescription = new ThreadLocal(){@Override protected Boolean initialValue() {return false;}}; @Override public void setProjectDescription(IProject project, ICProjectDescription des, int flags, IProgressMonitor monitor) throws CoreException { + boolean originalState = isCurrentThreadSetProjectDescription(); try { + if (originalState) { + // Technically this is not critical problem since the recursive setProjectDescription() gets scheduled in background thread. + // But it is quite likely to be an error on part of the caller unaware that their listener can be called from inside setProjectDescription(). + // To avoid the log entry the callers should check CProjectDescriptionManager.isCurrentThreadSetProjectDescription() + // and schedule the update in background thread themselves. + CCorePlugin.logStackTrace(IStatus.INFO, "Recursive setProjectDescription from event listener, project=" + project); //$NON-NLS-1$ + } settingProjectDescription.set(true); if(des != null){ if (!project.isAccessible()) @@ -864,7 +872,7 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { } CProjectDescriptionStorageManager.getInstance().setProjectDescription(project, des, flags, monitor); } finally { - settingProjectDescription.set(false); + settingProjectDescription.set(originalState); } } @@ -2469,7 +2477,7 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { } public boolean isNewStyleCfg(ICConfigurationDescription cfgDes){ - if(cfgDes == null || cfgDes.isPreferenceConfiguration()) + if(cfgDes == null) return false; CConfigurationData data = ((IInternalCCfgInfo)cfgDes).getConfigurationData(false); diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/SettingsImportExportTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/SettingsImportExportTest.java index 69b9367fb66..64cbdb2d95f 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/SettingsImportExportTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/SettingsImportExportTest.java @@ -20,6 +20,7 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.settings.model.CIncludePathEntry; @@ -102,7 +103,9 @@ public class SettingsImportExportTest extends BaseUITestCase { public void testNormalExportImport() throws Exception { ICProject exportProject = CProjectHelper.createCCProject("TempProject1", "unused"); +// ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(exportProject.getProject(), false); ICProject importProject = CProjectHelper.createCCProject("TempProject2", "unused"); +// ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(importProject.getProject(), false); setUpProjectSettings(exportProject); ProjectSettingsWizardPageMock page = new ProjectSettingsWizardPageMock() {