mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-10 09:45:39 +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");
|
IProject referencedProject = ResourceHelper.createCDTProjectWithConfig(projectName+"-referenced");
|
||||||
setReference(project, referencedProject);
|
setReference(project, referencedProject);
|
||||||
|
|
||||||
// get cfgDescription and language to work with
|
// get cfgDescription
|
||||||
ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
|
ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
|
||||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
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);
|
ILanguageSettingsProvider refProjectsProvider = LanguageSettingsManager.getWorkspaceProvider(ReferencedProjectsLanguageSettingsProvider.ID);
|
||||||
assertNotNull(refProjectsProvider);
|
assertNotNull(refProjectsProvider);
|
||||||
List<ILanguageSettingsProvider> providers = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
|
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 */
|
/** ID of the provider used in extension point from plugin.xml */
|
||||||
public static final String ID = "org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider"; //$NON-NLS-1$
|
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
|
@Override
|
||||||
public List<ICLanguageSettingEntry> getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
|
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) {
|
if (cfgDescription == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -41,20 +55,25 @@ public class ReferencedProjectsLanguageSettingsProvider extends LanguageSettings
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
try {
|
||||||
ICConfigurationDescription[] refCfgDescriptions = CoreModelUtil.getReferencedConfigurationDescriptions(cfgDescription, false);
|
recursiveCallIndicator.set(true);
|
||||||
for (ICConfigurationDescription refCfgDescription : refCfgDescriptions) {
|
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||||
List<ICLanguageSettingEntry> refEntries = LanguageSettingsManager.getSettingEntriesByKind(refCfgDescription, rc, languageId, ICSettingEntry.ALL);
|
ICConfigurationDescription[] refCfgDescriptions = CoreModelUtil.getReferencedConfigurationDescriptions(cfgDescription, false);
|
||||||
for (ICLanguageSettingEntry refEntry : refEntries) {
|
for (ICConfigurationDescription refCfgDescription : refCfgDescriptions) {
|
||||||
int flags = refEntry.getFlags();
|
List<ICLanguageSettingEntry> refEntries = LanguageSettingsManager.getSettingEntriesByKind(refCfgDescription, rc, languageId, ICSettingEntry.ALL);
|
||||||
if ((flags & ICSettingEntry.EXPORTED) == ICSettingEntry.EXPORTED) {
|
for (ICLanguageSettingEntry refEntry : refEntries) {
|
||||||
// create a new entry with EXPORTED flag cleared
|
int flags = refEntry.getFlags();
|
||||||
ICLanguageSettingEntry entry = CDataUtil.createEntry(refEntry, flags & ~ICSettingEntry.EXPORTED);
|
if ((flags & ICSettingEntry.EXPORTED) == ICSettingEntry.EXPORTED) {
|
||||||
entries.add(entry);
|
// 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