mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 08:55:25 +02:00
bug 416628: Handle case when projects reference each other recursively
This commit is contained in:
parent
6791f19c41
commit
f49338fed1
2 changed files with 125 additions and 14 deletions
|
@ -141,12 +141,12 @@ public class LanguageSettingsProviderReferencedProjectsTests extends BaseTestCas
|
|||
IProject referencedProject = ResourceHelper.createCDTProjectWithConfig(projectName+"-referenced");
|
||||
setReference(project, referencedProject);
|
||||
|
||||
// get cfgDescription and language to work with
|
||||
// get cfgDescription
|
||||
ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
|
||||
{
|
||||
// doublecheck that provider for referenced projects is set in the configuration
|
||||
// double-check that provider for referenced projects is set in the configuration
|
||||
ILanguageSettingsProvider refProjectsProvider = LanguageSettingsManager.getWorkspaceProvider(ReferencedProjectsLanguageSettingsProvider.ID);
|
||||
assertNotNull(refProjectsProvider);
|
||||
List<ILanguageSettingsProvider> providers = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
|
||||
|
@ -207,4 +207,96 @@ public class LanguageSettingsProviderReferencedProjectsTests extends BaseTestCas
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test case when projects reference each other recursively.
|
||||
*/
|
||||
public void testRecursiveReferences() throws Exception {
|
||||
// Create model projects that reference each other
|
||||
String projectName = getName();
|
||||
IProject projectA = ResourceHelper.createCDTProjectWithConfig(projectName + "-A");
|
||||
IProject projectB = ResourceHelper.createCDTProjectWithConfig(projectName + "-B");
|
||||
setReference(projectA, projectB);
|
||||
setReference(projectB, projectA);
|
||||
|
||||
{
|
||||
// get cfgDescriptions to work with
|
||||
ICConfigurationDescription[] cfgDescriptionsA = getConfigurationDescriptions(projectA);
|
||||
ICConfigurationDescription cfgDescriptionA = cfgDescriptionsA[0];
|
||||
ICConfigurationDescription[] cfgDescriptionsB = getConfigurationDescriptions(projectB);
|
||||
ICConfigurationDescription cfgDescriptionB = cfgDescriptionsB[0];
|
||||
// double-check that provider for referenced projects is set in the configurations
|
||||
ILanguageSettingsProvider refProjectsProvider = LanguageSettingsManager.getWorkspaceProvider(ReferencedProjectsLanguageSettingsProvider.ID);
|
||||
assertNotNull(refProjectsProvider);
|
||||
List<ILanguageSettingsProvider> providersA = ((ILanguageSettingsProvidersKeeper) cfgDescriptionA).getLanguageSettingProviders();
|
||||
assertTrue(providersA.contains(refProjectsProvider));
|
||||
List<ILanguageSettingsProvider> providersB = ((ILanguageSettingsProvidersKeeper) cfgDescriptionB).getLanguageSettingProviders();
|
||||
assertTrue(providersB.contains(refProjectsProvider));
|
||||
|
||||
// Check that no setting entries are set initially
|
||||
List<ICLanguageSettingEntry> entriesA = LanguageSettingsManager.getSettingEntriesByKind(cfgDescriptionA, projectA, null, ICSettingEntry.ALL);
|
||||
assertEquals(0, entriesA.size());
|
||||
List<ICLanguageSettingEntry> entriesB = LanguageSettingsManager.getSettingEntriesByKind(cfgDescriptionA, projectB, null, ICSettingEntry.ALL);
|
||||
assertEquals(0, entriesB.size());
|
||||
}
|
||||
|
||||
CIncludePathEntry entryExportedA = CDataUtil.createCIncludePathEntry("referenced-exported-A", ICSettingEntry.EXPORTED);
|
||||
CIncludePathEntry entryNotExportedA = CDataUtil.createCIncludePathEntry("referenced-not-exported-A", 0);
|
||||
// Add entries into a project A
|
||||
{
|
||||
ICConfigurationDescription[] refCfgDescriptions = getConfigurationDescriptions(projectA);
|
||||
ICConfigurationDescription refCfgDescription = refCfgDescriptions[0];
|
||||
List<ILanguageSettingsProvider> providersRef = ((ILanguageSettingsProvidersKeeper) refCfgDescription).getLanguageSettingProviders();
|
||||
// get user provider which is the first one
|
||||
ILanguageSettingsProvider userProviderRef = providersRef.get(0);
|
||||
assertEquals(ScannerDiscoveryLegacySupport.USER_LANGUAGE_SETTINGS_PROVIDER_ID, userProviderRef.getId());
|
||||
assertTrue(userProviderRef instanceof LanguageSettingsGenericProvider);
|
||||
// add sample entries
|
||||
ArrayList<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(entryExportedA);
|
||||
entries.add(entryNotExportedA);
|
||||
((LanguageSettingsGenericProvider) userProviderRef).setSettingEntries(null, null, null, entries);
|
||||
}
|
||||
|
||||
CIncludePathEntry entryExportedB = CDataUtil.createCIncludePathEntry("referenced-exported-B", ICSettingEntry.EXPORTED);
|
||||
CIncludePathEntry entryNotExportedB = CDataUtil.createCIncludePathEntry("referenced-not-exported-B", 0);
|
||||
// Add entries into a project B
|
||||
{
|
||||
ICConfigurationDescription[] refCfgDescriptions = getConfigurationDescriptions(projectB);
|
||||
ICConfigurationDescription refCfgDescription = refCfgDescriptions[0];
|
||||
List<ILanguageSettingsProvider> providersRef = ((ILanguageSettingsProvidersKeeper) refCfgDescription).getLanguageSettingProviders();
|
||||
// get user provider which is the first one
|
||||
ILanguageSettingsProvider userProviderRef = providersRef.get(0);
|
||||
assertEquals(ScannerDiscoveryLegacySupport.USER_LANGUAGE_SETTINGS_PROVIDER_ID, userProviderRef.getId());
|
||||
assertTrue(userProviderRef instanceof LanguageSettingsGenericProvider);
|
||||
// add sample entries
|
||||
ArrayList<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(entryExportedB);
|
||||
entries.add(entryNotExportedB);
|
||||
((LanguageSettingsGenericProvider) userProviderRef).setSettingEntries(null, null, null, entries);
|
||||
}
|
||||
|
||||
// Check that the new entries from projectB made it to projectA
|
||||
{
|
||||
ICConfigurationDescription[] cfgDescriptionsA = getConfigurationDescriptions(projectA);
|
||||
ICConfigurationDescription cfgDescriptionA = cfgDescriptionsA[0];
|
||||
List<ICLanguageSettingEntry> entries = LanguageSettingsManager.getSettingEntriesByKind(cfgDescriptionA, projectA, null, ICSettingEntry.ALL);
|
||||
assertEquals(entryExportedA, entries.get(0));
|
||||
assertEquals(entryNotExportedA, entries.get(1));
|
||||
assertEquals(CDataUtil.createCIncludePathEntry(entryExportedB.getName(), 0), entries.get(2));
|
||||
assertEquals(3, entries.size());
|
||||
}
|
||||
// Check that the new entries from projectA made it to projectB
|
||||
{
|
||||
ICConfigurationDescription[] cfgDescriptionsB = getConfigurationDescriptions(projectB);
|
||||
ICConfigurationDescription cfgDescriptionB = cfgDescriptionsB[0];
|
||||
List<ICLanguageSettingEntry> entries = LanguageSettingsManager.getSettingEntriesByKind(cfgDescriptionB, projectB, null, ICSettingEntry.ALL);
|
||||
assertEquals(entryExportedB, entries.get(0));
|
||||
assertEquals(entryNotExportedB, entries.get(1));
|
||||
assertEquals(CDataUtil.createCIncludePathEntry(entryExportedA.getName(), 0), entries.get(2));
|
||||
assertEquals(3, entries.size());
|
||||
}
|
||||
|
||||
// Hopefully it gets here without stack overflow
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,8 +31,22 @@ public class ReferencedProjectsLanguageSettingsProvider extends LanguageSettings
|
|||
/** ID of the provider used in extension point from plugin.xml */
|
||||
public static final String ID = "org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider"; //$NON-NLS-1$
|
||||
|
||||
final private ThreadLocal<Boolean> recursiveCallIndicator = new ThreadLocal<Boolean>() {
|
||||
@Override
|
||||
protected Boolean initialValue() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public List<ICLanguageSettingEntry> getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
|
||||
if (recursiveCallIndicator.get()) {
|
||||
// Recursive call indicates that the provider of a referenced project is called.
|
||||
// Only exported entries of the original configuration should be considered,
|
||||
// entries of referenced projects are not re-exported.
|
||||
return null;
|
||||
}
|
||||
|
||||
if (cfgDescription == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -41,20 +55,25 @@ public class ReferencedProjectsLanguageSettingsProvider extends LanguageSettings
|
|||
return null;
|
||||
}
|
||||
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
ICConfigurationDescription[] refCfgDescriptions = CoreModelUtil.getReferencedConfigurationDescriptions(cfgDescription, false);
|
||||
for (ICConfigurationDescription refCfgDescription : refCfgDescriptions) {
|
||||
List<ICLanguageSettingEntry> refEntries = LanguageSettingsManager.getSettingEntriesByKind(refCfgDescription, rc, languageId, ICSettingEntry.ALL);
|
||||
for (ICLanguageSettingEntry refEntry : refEntries) {
|
||||
int flags = refEntry.getFlags();
|
||||
if ((flags & ICSettingEntry.EXPORTED) == ICSettingEntry.EXPORTED) {
|
||||
// create a new entry with EXPORTED flag cleared
|
||||
ICLanguageSettingEntry entry = CDataUtil.createEntry(refEntry, flags & ~ICSettingEntry.EXPORTED);
|
||||
entries.add(entry);
|
||||
try {
|
||||
recursiveCallIndicator.set(true);
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
ICConfigurationDescription[] refCfgDescriptions = CoreModelUtil.getReferencedConfigurationDescriptions(cfgDescription, false);
|
||||
for (ICConfigurationDescription refCfgDescription : refCfgDescriptions) {
|
||||
List<ICLanguageSettingEntry> refEntries = LanguageSettingsManager.getSettingEntriesByKind(refCfgDescription, rc, languageId, ICSettingEntry.ALL);
|
||||
for (ICLanguageSettingEntry refEntry : refEntries) {
|
||||
int flags = refEntry.getFlags();
|
||||
if ((flags & ICSettingEntry.EXPORTED) == ICSettingEntry.EXPORTED) {
|
||||
// create a new entry with EXPORTED flag cleared
|
||||
ICLanguageSettingEntry entry = CDataUtil.createEntry(refEntry, flags & ~ICSettingEntry.EXPORTED);
|
||||
entries.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LanguageSettingsStorage.getPooledList(new ArrayList<ICLanguageSettingEntry>(entries));
|
||||
return LanguageSettingsStorage.getPooledList(new ArrayList<ICLanguageSettingEntry>(entries));
|
||||
} finally {
|
||||
recursiveCallIndicator.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue