diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/AllLanguageSettingsProvidersCoreTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/AllLanguageSettingsProvidersCoreTests.java index 624bd1f146f..f6542d6d709 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/AllLanguageSettingsProvidersCoreTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/AllLanguageSettingsProvidersCoreTests.java @@ -28,6 +28,8 @@ public class AllLanguageSettingsProvidersCoreTests { suite.addTest(LanguageSettingsManagerTests.suite()); suite.addTest(LanguageSettingsSerializableProviderTests.suite()); suite.addTest(LanguageSettingsPersistenceProjectTests.suite()); + suite.addTest(LanguageSettingsListenersTests.suite()); + suite.addTest(LanguageSettingsScannerInfoProviderTests.suite()); return suite; } } diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsExtensionsTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsExtensionsTests.java index 3aa46779c0e..9f3f1fa7eab 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsExtensionsTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsExtensionsTests.java @@ -55,7 +55,6 @@ public class LanguageSettingsExtensionsTests extends BaseTestCase { /*package*/ static final ICLanguageSettingEntry EXTENSION_SERIALIZABLE_PROVIDER_ENTRY = new CMacroEntry("MACRO", "value", 0); /*package*/ static final ICLanguageSettingEntry EXTENSION_EDITABLE_PROVIDER_ENTRY = new CMacroEntry("MACRO", "value", 0); /*package*/ static final String EXTENSION_REGISTERER_PROVIDER_ID = "org.eclipse.cdt.core.tests.language.settings.listener.registerer.provider"; - /*package*/ static final String EXTENSION_USER_PROVIDER_ID = "org.eclipse.cdt.ui.UserLanguageSettingsProvider"; // Arbitrary sample parameters used by the test private static final String PROVIDER_0 = "test.provider.0.id"; diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsListenersTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsListenersTests.java new file mode 100644 index 00000000000..7f39b254a1c --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsListenersTests.java @@ -0,0 +1,556 @@ +/******************************************************************************* + * Copyright (c) 2011, 2012 Andrew Gvozdev and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andrew Gvozdev - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.core.language.settings.providers; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.settings.model.CMacroEntry; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; +import org.eclipse.cdt.core.testplugin.ResourceHelper; +import org.eclipse.cdt.core.testplugin.util.BaseTestCase; +import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager; +import org.eclipse.core.resources.IProject; + +/** + * Test cases to cover {@link ILanguageSettingsChangeListener} capabilities. + */ +public class LanguageSettingsListenersTests extends BaseTestCase { + // These should match corresponding entries defined in plugin.xml + private static final String EXTENSION_REGISTERER_PROVIDER_ID = LanguageSettingsExtensionsTests.EXTENSION_REGISTERER_PROVIDER_ID; + private static final String EXTENSION_EDITABLE_PROVIDER_ID = LanguageSettingsExtensionsTests.EXTENSION_EDITABLE_PROVIDER_ID; + + private static final String PROVIDER_1 = "test.provider.1.id"; + private static final String PROVIDER_NAME_1 = "test.provider.1.name"; + private static final String PROVIDER_CUSTOM_GLOBAL = "test.provider.custom.global.id"; + private static final String PROVIDER_CUSTOM_GLOBAL_NAME = "test.provider.custom.global.name"; + + private static final CMacroEntry SAMPLE_LSE = new CMacroEntry("MACRO", "value",0); + + /** + * Mock {@link ILanguageSettingsChangeListener}. + */ + private class MockLanguageSettingsChangeListener implements ILanguageSettingsChangeListener { + private int count = 0; + private ILanguageSettingsChangeEvent lastEvent = null; + @Override + public void handleEvent(ILanguageSettingsChangeEvent event) { + count++; + lastEvent = event; + } + public int getCount() { + return count; + } + public void resetCount() { + count = 0; + lastEvent = null; + } + public ILanguageSettingsChangeEvent getLastEvent() { + return lastEvent; + } + } + private MockLanguageSettingsChangeListener mockLseListener = new MockLanguageSettingsChangeListener(); + + /** + * Constructor. + * @param name - name of the test. + */ + public LanguageSettingsListenersTests(String name) { + super(name); + + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + LanguageSettingsManager.unregisterLanguageSettingsChangeListener(mockLseListener); + LanguageSettingsManager.setWorkspaceProviders(null); + super.tearDown(); // includes ResourceHelper cleanup + } + + /** + * @return - new TestSuite. + */ + public static TestSuite suite() { + return new TestSuite(LanguageSettingsListenersTests.class); + } + + /** + * main function of the class. + * + * @param args - arguments + */ + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + /** + * Check that global provider does not get unnecessarily registered on start. + */ + public void testListenerRegisterer_CheckExtensionProvider() throws Exception { + // check if extension provider exists + ILanguageSettingsProvider workspaceProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_REGISTERER_PROVIDER_ID); + ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(workspaceProvider); + assertNotNull(rawProvider); + // global listeners providers get registered only lazily + assertEquals(0, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + + /** + * Test events triggered for shared global providers not included in any configuration. + */ + public void testListenerRegisterer_GlobalProviderNotInUse() throws Exception { + // create project + ILanguageSettingsProvider workspaceProvider = LanguageSettingsManager.getWorkspaceProvider(PROVIDER_CUSTOM_GLOBAL); + + // the global custom provider has not been added yet + ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(workspaceProvider); + assertNull(rawProvider); + assertEquals(0, MockListenerRegisterer.getCount(PROVIDER_CUSTOM_GLOBAL)); + + List workspaceProvidersOriginal = LanguageSettingsManager.getWorkspaceProviders(); + { + // add global provider which is not engaged + ILanguageSettingsProvider provider = new MockListenerRegisterer(PROVIDER_CUSTOM_GLOBAL, PROVIDER_CUSTOM_GLOBAL_NAME); + List providers = new ArrayList(workspaceProvidersOriginal); + providers.add(provider); + LanguageSettingsManager.setWorkspaceProviders(providers); + assertEquals(0, MockListenerRegisterer.getCount(PROVIDER_CUSTOM_GLOBAL)); + } + { + // remove global provider and restore original list + List providers = new ArrayList(workspaceProvidersOriginal); + LanguageSettingsManager.setWorkspaceProviders(providers); + assertEquals(0, MockListenerRegisterer.getCount(PROVIDER_CUSTOM_GLOBAL)); + } + } + + /** + * Test events triggered when empty provider added and the resulting list of entries does not change. + */ + public void testNotification_cfgProvider_AddEmptyProvider() throws Exception { + // create project + IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName()); + // First clear default providers + { + // get project descriptions + ICProjectDescription prjDescriptionWritable = CProjectDescriptionManager.getInstance().getProjectDescription(project, true); + assertNotNull(prjDescriptionWritable); + ICConfigurationDescription[] cfgDescriptions = prjDescriptionWritable.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // clear providers + List providers = new ArrayList(); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + List storedProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + assertEquals(0, storedProviders.size()); + + // write to project description + CoreModel.getDefault().setProjectDescription(project, prjDescriptionWritable); + } + + // register mock listener to inspect the notifications + LanguageSettingsManager.registerLanguageSettingsChangeListener(mockLseListener); + assertEquals(0, mockLseListener.getCount()); + assertEquals(null, mockLseListener.getLastEvent()); + + // Add empty provider + { + // get project descriptions + ICProjectDescription prjDescriptionWritable = CProjectDescriptionManager.getInstance().getProjectDescription(project, true); + assertNotNull(prjDescriptionWritable); + ICConfigurationDescription[] cfgDescriptions = prjDescriptionWritable.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // create a provider and add to cfgDescription + ILanguageSettingsProvider mockProvider = new MockLanguageSettingsEditableProvider(PROVIDER_1, PROVIDER_NAME_1); + List providers = new ArrayList(); + providers.add(mockProvider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + List storedProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + + // write to project description + CoreModel.getDefault().setProjectDescription(project, prjDescriptionWritable); + } + + // No notifications expected + assertEquals(0, mockLseListener.getCount()); + assertEquals(null, mockLseListener.getLastEvent()); + } + + /** + * Test events triggered during serialization. + */ + public void testNotification_cfgProvider_SerializeEntries() throws Exception { + // create project + IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName()); + + // add the mock provider + { + // get project descriptions + ICProjectDescription prjDescriptionWritable = CProjectDescriptionManager.getInstance().getProjectDescription(project, true); + assertNotNull(prjDescriptionWritable); + ICConfigurationDescription[] cfgDescriptions = prjDescriptionWritable.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // create a provider and add to cfgDescription + List providers = new ArrayList(); + providers.add(new MockLanguageSettingsEditableProvider(PROVIDER_1, PROVIDER_NAME_1)); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + List storedProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + + // write to project description + CoreModel.getDefault().setProjectDescription(project, prjDescriptionWritable); + } + + // register mock listener to inspect the notifications + LanguageSettingsManager.registerLanguageSettingsChangeListener(mockLseListener); + assertEquals(0, mockLseListener.getCount()); + assertEquals(null, mockLseListener.getLastEvent()); + + // Change the provider's entries + { + // get project descriptions + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, false); + assertNotNull(prjDescription); + ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + String cfgDescriptionId = cfgDescription.getId(); + + // Add entries + List entries = new ArrayList(); + entries.add(SAMPLE_LSE); + List providers = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + assertEquals(1, providers.size()); + assertTrue(providers.get(0) instanceof MockLanguageSettingsEditableProvider); + MockLanguageSettingsEditableProvider mockProvider = (MockLanguageSettingsEditableProvider) providers.get(0); + mockProvider.setSettingEntries(cfgDescription, project, null, entries); + assertEquals(0, mockLseListener.getCount()); + assertEquals(null, mockLseListener.getLastEvent()); + + // Serialize settings + LanguageSettingsManager.serializeLanguageSettings(prjDescription); + // inspect event + assertEquals(1, mockLseListener.getCount()); + ILanguageSettingsChangeEvent event = mockLseListener.getLastEvent(); + assertNotNull(event); + + assertEquals(project.getName(), event.getProjectName()); + assertEquals(1, event.getConfigurationDescriptionIds().length); + assertEquals(cfgDescriptionId, event.getConfigurationDescriptionIds()[0]); + } + } + + /** + * Test events triggered when providers are being added by 2 independent parties in parallel. + */ + public void testNotification_cfgProvider_SerializeEntriesConcurrent() throws Exception { + // create project + IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName()); + + // add the mock provider + { + // get project descriptions + ICProjectDescription prjDescriptionWritable = CProjectDescriptionManager.getInstance().getProjectDescription(project, true); + assertNotNull(prjDescriptionWritable); + ICConfigurationDescription[] cfgDescriptions = prjDescriptionWritable.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // create a provider and add to cfgDescription + List providers = new ArrayList(); + providers.add(new MockLanguageSettingsEditableProvider(PROVIDER_1, PROVIDER_NAME_1)); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + List storedProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + + // write to project description + CoreModel.getDefault().setProjectDescription(project, prjDescriptionWritable); + } + + // register mock listener to inspect the notifications + LanguageSettingsManager.registerLanguageSettingsChangeListener(mockLseListener); + assertEquals(0, mockLseListener.getCount()); + assertEquals(null, mockLseListener.getLastEvent()); + + // Change the provider's entries concurrently + + // get project descriptions + ICProjectDescription prjDescription_1 = CProjectDescriptionManager.getInstance().getProjectDescription(project, false); + assertNotNull(prjDescription_1); + ICProjectDescription prjDescription_2 = CProjectDescriptionManager.getInstance().getProjectDescription(project, false); + assertNotNull(prjDescription_2); + { + ICConfigurationDescription[] cfgDescriptions = prjDescription_1.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + String cfgDescriptionId = cfgDescription.getId(); + + // Add entries + List entries = new ArrayList(); + entries.add(SAMPLE_LSE); + List providers = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + assertEquals(1, providers.size()); + assertTrue(providers.get(0) instanceof MockLanguageSettingsEditableProvider); + MockLanguageSettingsEditableProvider mockProvider = (MockLanguageSettingsEditableProvider) providers.get(0); + mockProvider.setSettingEntries(cfgDescription, project, null, entries); + + // reset count + mockLseListener.resetCount(); + assertEquals(0, mockLseListener.getCount()); + assertNull(mockLseListener.getLastEvent()); + + // Serialize settings + LanguageSettingsManager.serializeLanguageSettings(prjDescription_1); + // inspect event + assertEquals(1, mockLseListener.getCount()); + ILanguageSettingsChangeEvent event = mockLseListener.getLastEvent(); + assertNotNull(event); + + assertEquals(project.getName(), event.getProjectName()); + assertEquals(1, event.getConfigurationDescriptionIds().length); + assertEquals(cfgDescriptionId, event.getConfigurationDescriptionIds()[0]); + } + { + ICConfigurationDescription[] cfgDescriptions = prjDescription_2.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + String cfgDescriptionId = cfgDescription.getId(); + + // Add same entries + List entries = new ArrayList(); + entries.add(SAMPLE_LSE); + List providers = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + assertEquals(1, providers.size()); + assertTrue(providers.get(0) instanceof MockLanguageSettingsEditableProvider); + MockLanguageSettingsEditableProvider mockProvider = (MockLanguageSettingsEditableProvider) providers.get(0); + mockProvider.setSettingEntries(cfgDescription, project, null, entries); + + // reset count + mockLseListener.resetCount(); + assertEquals(0, mockLseListener.getCount()); + assertNull(mockLseListener.getLastEvent()); + + // Serialize settings + LanguageSettingsManager.serializeLanguageSettings(prjDescription_2); + // inspect event + assertEquals(0, mockLseListener.getCount()); + ILanguageSettingsChangeEvent event = mockLseListener.getLastEvent(); + assertNull(event); + } + } + + /** + * Test events triggered during adding global empty provider. + */ + public void testNotification_globalProvider_AddEmptyProvider() throws Exception { + // create project + IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName()); + // First clear default providers + { + // get project descriptions + ICProjectDescription prjDescriptionWritable = CProjectDescriptionManager.getInstance().getProjectDescription(project, true); + assertNotNull(prjDescriptionWritable); + ICConfigurationDescription[] cfgDescriptions = prjDescriptionWritable.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // clear providers + List providers = new ArrayList(); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + List storedProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + assertEquals(0, storedProviders.size()); + + // write to project description + CoreModel.getDefault().setProjectDescription(project, prjDescriptionWritable); + } + + // register mock listener to inspect the notifications + LanguageSettingsManager.registerLanguageSettingsChangeListener(mockLseListener); + assertEquals(0, mockLseListener.getCount()); + assertEquals(null, mockLseListener.getLastEvent()); + + // Add empty global provider + { + // get project descriptions + ICProjectDescription prjDescriptionWritable = CProjectDescriptionManager.getInstance().getProjectDescription(project, true); + assertNotNull(prjDescriptionWritable); + ICConfigurationDescription[] cfgDescriptions = prjDescriptionWritable.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // retrieve a global provider + ILanguageSettingsProvider wspProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_EDITABLE_PROVIDER_ID); + assertNotNull(wspProvider); + ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(wspProvider); + assertTrue(rawProvider instanceof MockLanguageSettingsEditableProvider); + // clear it + ((MockLanguageSettingsEditableProvider) rawProvider).clear(); + assertEquals(null, wspProvider.getSettingEntries(cfgDescription, project, null)); + // add the provider to cfgDescription + List providers = new ArrayList(); + providers.add(wspProvider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + List storedProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + + // write to project description + CoreModel.getDefault().setProjectDescription(project, prjDescriptionWritable); + } + + // No notifications expected + assertEquals(0, mockLseListener.getCount()); + assertEquals(null, mockLseListener.getLastEvent()); + } + + /** + * Test events triggered during serialization of global shared providers. + */ + public void testNotification_globalProvider_SerializeEntries() throws Exception { + // create project + IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName()); + + // register mock listener to inspect the notifications + LanguageSettingsManager.registerLanguageSettingsChangeListener(mockLseListener); + + // Add empty global provider + { + // get project descriptions + ICProjectDescription prjDescriptionWritable = CProjectDescriptionManager.getInstance().getProjectDescription(project, true); + assertNotNull(prjDescriptionWritable); + ICConfigurationDescription[] cfgDescriptions = prjDescriptionWritable.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // retrieve a global provider + ILanguageSettingsProvider wspProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_EDITABLE_PROVIDER_ID); + assertNotNull(wspProvider); + ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(wspProvider); + assertTrue(rawProvider instanceof MockLanguageSettingsEditableProvider); + // clear it + ((MockLanguageSettingsEditableProvider) rawProvider).clear(); + assertEquals(null, wspProvider.getSettingEntries(cfgDescription, project, null)); + // add the provider to cfgDescription + List providers = new ArrayList(); + providers.add(wspProvider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + List storedProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + + // write to project description + CoreModel.getDefault().setProjectDescription(project, prjDescriptionWritable); + } + + // Change the provider's entries + { + // retrieve a global provider + ILanguageSettingsProvider wspProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_EDITABLE_PROVIDER_ID); + assertNotNull(wspProvider); + ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(wspProvider); + assertTrue(rawProvider instanceof MockLanguageSettingsEditableProvider); + ((MockLanguageSettingsEditableProvider) rawProvider).clear(); + // add entries + List entries = new ArrayList(); + entries.add(SAMPLE_LSE); + ((MockLanguageSettingsEditableProvider) rawProvider).setSettingEntries(null, project, null, entries); + assertEquals(SAMPLE_LSE, wspProvider.getSettingEntries(null, project, null).get(0)); + + // reset count + mockLseListener.resetCount(); + assertEquals(0, mockLseListener.getCount()); + assertEquals(null, mockLseListener.getLastEvent()); + + // Serialize settings + LanguageSettingsManager.serializeLanguageSettingsWorkspace(); + + // get cfgDescriptionId + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, false); + assertNotNull(prjDescription); + ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + String cfgDescriptionId = cfgDescription.getId(); + + // inspect event + assertEquals(1, mockLseListener.getCount()); + ILanguageSettingsChangeEvent event = mockLseListener.getLastEvent(); + assertNotNull(event); + + assertEquals(project.getName(), event.getProjectName()); + assertEquals(1, event.getConfigurationDescriptionIds().length); + assertEquals(cfgDescriptionId, event.getConfigurationDescriptionIds()[0]); + } + // Change the provider's entries back (bug was found for this case) + { + // retrieve a global provider + ILanguageSettingsProvider wspProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_EDITABLE_PROVIDER_ID); + assertNotNull(wspProvider); + ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(wspProvider); + assertTrue(rawProvider instanceof MockLanguageSettingsEditableProvider); + // clear the provider again + ((MockLanguageSettingsEditableProvider) rawProvider).clear(); + + // reset count + mockLseListener.resetCount(); + assertEquals(0, mockLseListener.getCount()); + assertEquals(null, mockLseListener.getLastEvent()); + + // Serialize settings + LanguageSettingsManager.serializeLanguageSettingsWorkspace(); + + // get cfgDescriptionId + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, false); + assertNotNull(prjDescription); + ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + String cfgDescriptionId = cfgDescription.getId(); + + // inspect event + assertEquals(1, mockLseListener.getCount()); + ILanguageSettingsChangeEvent event = mockLseListener.getLastEvent(); + assertNotNull(event); + + assertEquals(project.getName(), event.getProjectName()); + assertEquals(1, event.getConfigurationDescriptionIds().length); + assertEquals(cfgDescriptionId, event.getConfigurationDescriptionIds()[0]); + } + } +} + 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 de2482c87ba..9015db91e7e 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 @@ -21,11 +21,17 @@ import org.eclipse.cdt.core.settings.model.CIncludePathEntry; import org.eclipse.cdt.core.settings.model.CMacroEntry; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.settings.model.ICSettingEntry; import org.eclipse.cdt.core.testplugin.CModelMock; +import org.eclipse.cdt.core.testplugin.ResourceHelper; import org.eclipse.cdt.core.testplugin.util.BaseTestCase; import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer; +import org.eclipse.cdt.internal.core.settings.model.CConfigurationDescription; +import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Path; @@ -35,6 +41,7 @@ import org.eclipse.core.runtime.Path; */ public class LanguageSettingsManagerTests extends BaseTestCase { // Those should match ids of plugin extensions defined in plugin.xml + private static final String EXTENSION_BASE_PROVIDER_ID = LanguageSettingsExtensionsTests.EXTENSION_BASE_PROVIDER_ID; private static final String EXTENSION_SERIALIZABLE_PROVIDER_ID = LanguageSettingsExtensionsTests.EXTENSION_SERIALIZABLE_PROVIDER_ID; private static final String EXTENSION_SERIALIZABLE_PROVIDER_NAME = LanguageSettingsExtensionsTests.EXTENSION_SERIALIZABLE_PROVIDER_NAME; private static final String EXTENSION_EDITABLE_PROVIDER_ID = LanguageSettingsExtensionsTests.EXTENSION_EDITABLE_PROVIDER_ID; @@ -158,6 +165,35 @@ public class LanguageSettingsManagerTests extends BaseTestCase { assertEquals(defaultProviders, cfgDescription.getDefaultLanguageSettingsProvidersIds()); } + /** + * Test to ensure uniqueness of ids for providers kept in configuration description. + */ + public void testConfigurationDescription_ProvidersUniqueId() throws Exception { + // Create model project and accompanied descriptions + String projectName = getName(); + IProject project = ResourceHelper.createCDTProjectWithConfig(projectName); + ICProjectDescription prjDescriptionWritable = CProjectDescriptionManager.getInstance().getProjectDescription(project, true); + + ICConfigurationDescription[] cfgDescriptions = prjDescriptionWritable.getConfigurations(); + ICConfigurationDescription cfgDescriptionWritable = cfgDescriptions[0]; + assertTrue(cfgDescriptionWritable instanceof CConfigurationDescription); + + // attempt to add duplicate providers + MockProvider dupe1 = new MockProvider(PROVIDER_0, PROVIDER_NAME_1, null); + MockProvider dupe2 = new MockProvider(PROVIDER_0, PROVIDER_NAME_2, null); + + List providers = new ArrayList(); + providers.add(dupe1); + providers.add(dupe2); + + try { + ((ILanguageSettingsProvidersKeeper) cfgDescriptionWritable).setLanguageSettingProviders(providers); + fail("cfgDescription.setLanguageSettingProviders() should not accept duplicate providers"); + } catch (Exception e) { + // Exception is welcome here + } + } + /** * Test various cases of ill-defined providers. */ @@ -338,6 +374,117 @@ public class LanguageSettingsManagerTests extends BaseTestCase { } } + /** + * Test getting entries from resource hierarchy. + */ + public void testProvider_ParentFolder() throws Exception { + // Create model project and accompanied descriptions + String projectName = getName(); + IProject project = ResourceHelper.createCDTProjectWithConfig(projectName); + ICProjectDescription prjDescriptionWritable = CProjectDescriptionManager.getInstance().getProjectDescription(project, true); + ICConfigurationDescription[] cfgDescriptions = prjDescriptionWritable.getConfigurations(); + + ICConfigurationDescription cfgDescriptionWritable = cfgDescriptions[0]; + assertTrue(cfgDescriptionWritable instanceof CConfigurationDescription); + + final IFolder parentFolder = ResourceHelper.createFolder(project, "/ParentFolder/"); + assertNotNull(parentFolder); + final IFile emptySettingsPath = ResourceHelper.createFile(project, "/ParentFolder/Subfolder/empty"); + assertNotNull(emptySettingsPath); + + // store the entries in parent folder + final List entries = new ArrayList(); + entries.add(new CIncludePathEntry("path0", 0)); + List providers = new ArrayList(); + ILanguageSettingsProvider provider = new MockProvider(PROVIDER_0, PROVIDER_NAME_0, null) { + @Override + public List getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) { + if (rc!=null && rc.equals(parentFolder)) { + return entries; + } + if (rc!=null && rc.equals(emptySettingsPath)) { + return new ArrayList(0); + } + return null; + } + + }; + providers.add(provider); + ((ILanguageSettingsProvidersKeeper) cfgDescriptionWritable).setLanguageSettingProviders(providers); + + { + // retrieve entries for a derived resource (in a subfolder) + IFile derived = ResourceHelper.createFile(project, "/ParentFolder/Subfolder/resource"); + List actual = LanguageSettingsManager + .getSettingEntriesUpResourceTree(provider, cfgDescriptionWritable, derived, LANG_ID); + // taken from parent folder + assertEquals(entries.get(0),actual.get(0)); + assertEquals(entries.size(), actual.size()); + } + + { + // retrieve entries for not related resource + IFile notRelated = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("/AnotherFolder/Subfolder/resource")); + List actual = LanguageSettingsManager + .getSettingEntriesUpResourceTree(provider, cfgDescriptionWritable, notRelated, LANG_ID); + assertEquals(0, actual.size()); + } + + { + // test distinction between no settings and empty settings + List actual = LanguageSettingsManager + .getSettingEntriesUpResourceTree(provider, cfgDescriptionWritable, emptySettingsPath, LANG_ID); + // NOT taken from parent folder + assertEquals(0, actual.size()); + } + } + + /** + * Test getting entries from resource hierarchy up to default entries. + */ + public void testProvider_DefaultEntries() throws Exception { + // Create model project and accompanied descriptions + String projectName = getName(); + IProject project = ResourceHelper.createCDTProjectWithConfig(projectName); + ICProjectDescription prjDescriptionWritable = CProjectDescriptionManager.getInstance().getProjectDescription(project, true); + ICConfigurationDescription[] cfgDescriptions = prjDescriptionWritable.getConfigurations(); + + ICConfigurationDescription cfgDescriptionWritable = cfgDescriptions[0]; + assertTrue(cfgDescriptionWritable instanceof CConfigurationDescription); + + final IFolder parentFolder = ResourceHelper.createFolder(project, "/ParentFolder/"); + assertNotNull(parentFolder); + final IFile emptySettingsPath = ResourceHelper.createFile(project, "/ParentFolder/Subfolder/empty"); + assertNotNull(emptySettingsPath); + + // store the entries as default entries + final List entries = new ArrayList(); + entries.add(new CIncludePathEntry("path0", 0)); + List providers = new ArrayList(); + ILanguageSettingsProvider provider = new MockProvider(PROVIDER_0, PROVIDER_NAME_0, null) { + @Override + public List getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) { + if (cfgDescription==null && rc==null) { + return entries; + } + return null; + } + + }; + providers.add(provider); + ((ILanguageSettingsProvidersKeeper) cfgDescriptionWritable).setLanguageSettingProviders(providers); + + { + // retrieve entries for a resource + IFile derived = ResourceHelper.createFile(project, "/ParentFolder/Subfolder/resource"); + List actual = LanguageSettingsManager + .getSettingEntriesUpResourceTree(provider, cfgDescriptionWritable, derived, LANG_ID); + // default entries given + assertEquals(entries.get(0),actual.get(0)); + assertEquals(entries.size(), actual.size()); + } + } + /** * Test ability to get entries by kind. */ diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsPersistenceProjectTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsPersistenceProjectTests.java index f2439a48162..5a7b0820715 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsPersistenceProjectTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsPersistenceProjectTests.java @@ -12,6 +12,7 @@ package org.eclipse.cdt.core.language.settings.providers; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import junit.framework.TestSuite; @@ -20,11 +21,14 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.settings.model.CIncludePathEntry; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; +import org.eclipse.cdt.core.settings.model.WriteAccessException; import org.eclipse.cdt.core.testplugin.CModelMock; import org.eclipse.cdt.core.testplugin.ResourceHelper; import org.eclipse.cdt.core.testplugin.util.BaseTestCase; import org.eclipse.cdt.internal.core.XmlUtil; import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer; +import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IPath; @@ -50,8 +54,10 @@ public class LanguageSettingsPersistenceProjectTests extends BaseTestCase { private static final String CFG_ID = "test.configuration.id.0"; private static final String CFG_ID_2 = "test.configuration.id.2"; private static final String PROVIDER_0 = "test.provider.0.id"; + private static final String PROVIDER_1 = "test.provider.1.id"; private static final String PROVIDER_2 = "test.provider.2.id"; private static final String PROVIDER_NAME_0 = "test.provider.0.name"; + private static final String PROVIDER_NAME_1 = "test.provider.1.name"; private static final String PROVIDER_NAME_2 = "test.provider.2.name"; private static final String ATTR_PARAMETER = "parameter"; private static final String CUSTOM_PARAMETER = "custom parameter"; @@ -145,6 +151,32 @@ public class LanguageSettingsPersistenceProjectTests extends BaseTestCase { junit.textui.TestRunner.run(suite()); } + /** + * Get read-only configuration descriptions. + */ + private ICConfigurationDescription[] getConfigurationDescriptions(IProject project) { + // project description + ICProjectDescription projectDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, false); + assertNotNull(projectDescription); + assertEquals(1, projectDescription.getConfigurations().length); + // configuration description + ICConfigurationDescription[] cfgDescriptions = projectDescription.getConfigurations(); + assertNotNull(cfgDescriptions); + return cfgDescriptions; + } + + /** + * Get first read-only configuration description. + */ + private ICConfigurationDescription getFirstConfigurationDescription(IProject project) { + ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project); + + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + assertNotNull(cfgDescription); + + return cfgDescription; + } + /** * Persist and reload when no customized providers are defined in the workspace. */ @@ -156,6 +188,152 @@ public class LanguageSettingsPersistenceProjectTests extends BaseTestCase { // test passes if no exception was thrown } + /** + * Make sure providers in configuration cannot be modified accidentally outside of API. + */ + public void testProjectDescription_PreventBackDoorAccess() throws Exception { + // create a project + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + + // get project descriptions + ICProjectDescription prjDescriptionWritable = CProjectDescriptionManager.getInstance().getProjectDescription(project, true); + assertNotNull(prjDescriptionWritable); + ICConfigurationDescription[] cfgDescriptions = prjDescriptionWritable.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescriptionWritable = cfgDescriptions[0]; + assertNotNull(cfgDescriptionWritable); + assertTrue(cfgDescriptionWritable instanceof ILanguageSettingsProvidersKeeper); + + List originalProviders = ((ILanguageSettingsProvidersKeeper) cfgDescriptionWritable).getLanguageSettingProviders(); + int originalSize = originalProviders.size(); + + // create new provider list + LanguageSettingsSerializableProvider mockProvider = new MockLanguageSettingsEditableProvider(PROVIDER_0, PROVIDER_NAME_0); + List providers = new ArrayList(originalProviders); + providers.add(mockProvider); + assertTrue(originalSize != providers.size()); + + // changing providers shouldn't affect the original list + ((ILanguageSettingsProvidersKeeper) cfgDescriptionWritable).setLanguageSettingProviders(providers); + assertEquals(originalSize, originalProviders.size()); + } + + /** + * Test assigning providers to read-only vs. writable configuration descriptions. + */ + public void testProjectDescription_ReadWriteDescription() throws Exception { + // create a project + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + + { + // get read-only description + ICProjectDescription prjDescriptionReadOnly = CProjectDescriptionManager.getInstance().getProjectDescription(project, false); + assertNotNull(prjDescriptionReadOnly); + ICConfigurationDescription cfgDescriptionReadOnly = prjDescriptionReadOnly.getDefaultSettingConfiguration(); + assertNotNull(cfgDescriptionReadOnly); + assertTrue(cfgDescriptionReadOnly instanceof ILanguageSettingsProvidersKeeper); + + // try to write to it providers + try { + List providers = new ArrayList(); + ((ILanguageSettingsProvidersKeeper) cfgDescriptionReadOnly).setLanguageSettingProviders(providers); + fail("WriteAccessException was expected but it was not throw."); + } catch (WriteAccessException e) { + // exception is expected + } + + // try to write to it default providers ids + try { + ((ILanguageSettingsProvidersKeeper) cfgDescriptionReadOnly).setDefaultLanguageSettingsProvidersIds(new String[] { PROVIDER_0 }); + fail("WriteAccessException was expected but it was not throw."); + } catch (WriteAccessException e) { + // exception is expected + } + } + + List entries = new ArrayList(); + entries.add(new CIncludePathEntry("path0", 0)); + + { + // get project descriptions + ICProjectDescription prjDescriptionWritable = CProjectDescriptionManager.getInstance().getProjectDescription(project, true); + assertNotNull(prjDescriptionWritable); + ICConfigurationDescription[] cfgDescriptions = prjDescriptionWritable.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescriptionWritable = cfgDescriptions[0]; + assertNotNull(cfgDescriptionWritable); + assertTrue(cfgDescriptionWritable instanceof ILanguageSettingsProvidersKeeper); + + // create a provider and write to cfgDescription + LanguageSettingsSerializableProvider mockProvider = new MockLanguageSettingsEditableProvider(PROVIDER_1, PROVIDER_NAME_1); + LanguageSettingsManager.setStoringEntriesInProjectArea(mockProvider, true); + mockProvider.setSettingEntries(cfgDescriptionWritable, null, null, entries); + List providers = new ArrayList(); + providers.add(mockProvider); + ((ILanguageSettingsProvidersKeeper) cfgDescriptionWritable).setLanguageSettingProviders(providers); + List storedProviders = ((ILanguageSettingsProvidersKeeper) cfgDescriptionWritable).getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + + // write to cfgDescription default providers ids + ((ILanguageSettingsProvidersKeeper) cfgDescriptionWritable).setDefaultLanguageSettingsProvidersIds(new String[] { PROVIDER_0 }); + + // apply new project description to the project model + CProjectDescriptionManager.getInstance().setProjectDescription(project, prjDescriptionWritable); + } + { + // get read-only project descriptions + ICProjectDescription prjDescriptionReadOnly = CProjectDescriptionManager.getInstance().getProjectDescription(project, false); + assertNotNull(prjDescriptionReadOnly); + ICConfigurationDescription[] cfgDescriptions = prjDescriptionReadOnly.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescriptionReadOnly = cfgDescriptions[0]; + assertNotNull(cfgDescriptionReadOnly); + assertTrue(cfgDescriptionReadOnly instanceof ILanguageSettingsProvidersKeeper); + + // double-check providers + List providers = ((ILanguageSettingsProvidersKeeper) cfgDescriptionReadOnly).getLanguageSettingProviders(); + assertEquals(1, providers.size()); + ILanguageSettingsProvider loadedProvider = providers.get(0); + assertTrue(loadedProvider instanceof MockLanguageSettingsEditableProvider); + assertEquals(PROVIDER_1, loadedProvider.getId()); + assertEquals(PROVIDER_NAME_1, loadedProvider.getName()); + // double-check provider's setting entries + List actual = loadedProvider.getSettingEntries(cfgDescriptionReadOnly, null, null); + assertEquals(entries.get(0), actual.get(0)); + assertEquals(entries.size(), actual.size()); + + // double-check default providers ids + String[] actualDefaultProvidersIds = ((ILanguageSettingsProvidersKeeper) cfgDescriptionReadOnly).getDefaultLanguageSettingsProvidersIds(); + assertTrue(Arrays.equals(new String[] { PROVIDER_0 }, actualDefaultProvidersIds)); + } + { + // get writable project descriptions + ICProjectDescription prjDescriptionWritable = CProjectDescriptionManager.getInstance().getProjectDescription(project, true); + assertNotNull(prjDescriptionWritable); + ICConfigurationDescription[] cfgDescriptions = prjDescriptionWritable.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescriptionWritable = cfgDescriptions[0]; + assertNotNull(cfgDescriptionWritable); + assertTrue(cfgDescriptionWritable instanceof ILanguageSettingsProvidersKeeper); + + // check providers + List providers = ((ILanguageSettingsProvidersKeeper) cfgDescriptionWritable).getLanguageSettingProviders(); + assertEquals(1, providers.size()); + ILanguageSettingsProvider loadedProvider = providers.get(0); + assertTrue(loadedProvider instanceof MockLanguageSettingsEditableProvider); + assertEquals(PROVIDER_1, loadedProvider.getId()); + assertEquals(PROVIDER_NAME_1, loadedProvider.getName()); + // check provider's setting entries + List actual = loadedProvider.getSettingEntries(cfgDescriptionWritable, null, null); + assertEquals(entries.get(0), actual.get(0)); + assertEquals(entries.size(), actual.size()); + + // check default providers ids + String[] actualDefaultProvidersIds = ((ILanguageSettingsProvidersKeeper) cfgDescriptionWritable).getDefaultLanguageSettingsProvidersIds(); + assertTrue(Arrays.equals(new String[] { PROVIDER_0 }, actualDefaultProvidersIds)); + } + } + /** * Persist and reload a customized provider defined in the workspace. */ @@ -397,6 +575,65 @@ public class LanguageSettingsPersistenceProjectTests extends BaseTestCase { } } + /** + * Test User language settings provider defined as extension in cdt.ui. + */ + public void testProjectPersistence_UserProviderDOM() throws Exception { + Element rootElement = null; + + List entries = new ArrayList(); + entries.add(new CIncludePathEntry("path0", 0)); + + { + // create a provider + MockProjectDescription mockPrjDescription = new MockProjectDescription(new MockConfigurationDescription(CFG_ID)); + ICConfigurationDescription[] cfgDescriptions = mockPrjDescription.getConfigurations(); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + ILanguageSettingsProvider provider = LanguageSettingsManager.getExtensionProviderCopy(EXTENSION_EDITABLE_PROVIDER_ID, false); + assertTrue(provider instanceof MockLanguageSettingsEditableProvider); + MockLanguageSettingsEditableProvider serializableProvider = (MockLanguageSettingsEditableProvider) provider; + serializableProvider.setSettingEntries(null, null, null, entries); + LanguageSettingsManager.setStoringEntriesInProjectArea(serializableProvider, true); + + ArrayList providers = new ArrayList(); + providers.add(serializableProvider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + + // prepare DOM storage + Document doc = XmlUtil.newDocument(); + rootElement = XmlUtil.appendElement(doc, ELEM_TEST); + // serialize language settings to the DOM + LanguageSettingsProvidersSerializer.serializeLanguageSettingsInternal(rootElement, null, mockPrjDescription); + assertTrue(XmlUtil.toString(doc).contains(EXTENSION_EDITABLE_PROVIDER_ID)); + assertTrue(XmlUtil.toString(doc).contains(MockLanguageSettingsEditableProvider.class.getName())); + } + { + // re-load and check language settings of the newly loaded provider + MockProjectDescription mockPrjDescription = new MockProjectDescription(new MockConfigurationDescription(CFG_ID)); + LanguageSettingsProvidersSerializer.loadLanguageSettingsInternal(rootElement, null, mockPrjDescription); + + ICConfigurationDescription[] cfgDescriptions = mockPrjDescription.getConfigurations(); + assertNotNull(cfgDescriptions); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + List providers = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + assertNotNull(providers); + assertEquals(1, providers.size()); + ILanguageSettingsProvider provider = providers.get(0); + assertTrue(provider instanceof MockLanguageSettingsEditableProvider); + + List actual = provider.getSettingEntries(null, null, null); + assertEquals(entries.get(0), actual.get(0)); + assertEquals(entries.size(), actual.size()); + } + } + /** * Test serialization of providers to project storage where the project has multiple configurations. */ diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsScannerInfoProviderTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsScannerInfoProviderTests.java new file mode 100644 index 00000000000..de54edc6425 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsScannerInfoProviderTests.java @@ -0,0 +1,951 @@ +/******************************************************************************* + * Copyright (c) 2009, 2012 Andrew Gvozdev and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andrew Gvozdev - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.core.language.settings.providers; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.model.ILanguage; +import org.eclipse.cdt.core.model.LanguageManager; +import org.eclipse.cdt.core.parser.ExtendedScannerInfo; +import org.eclipse.cdt.core.settings.model.CIncludeFileEntry; +import org.eclipse.cdt.core.settings.model.CIncludePathEntry; +import org.eclipse.cdt.core.settings.model.CMacroEntry; +import org.eclipse.cdt.core.settings.model.CMacroFileEntry; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICFolderDescription; +import org.eclipse.cdt.core.settings.model.ICLanguageSetting; +import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; +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.language.settings.providers.LanguageSettingsScannerInfoProvider; +import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * Test cases testing LanguageSettingsProvider functionality + */ +public class LanguageSettingsScannerInfoProviderTests extends BaseTestCase { + private static final IFile FAKE_FILE = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("/project/path0")); + private static final String PROVIDER_ID = "test.provider.id"; + private static final String PROVIDER_ID_2 = "test.provider.id.2"; + private static final String PROVIDER_NAME = "test.provider.name"; + + // constants for getProjectDescription() + private static final boolean READ_ONLY = false; + private static final boolean WRITEABLE = true; + + private class MockProvider extends LanguageSettingsBaseProvider implements ILanguageSettingsProvider { + private final List entries; + + public MockProvider(String id, String name, List entries) { + super(id, name); + this.entries = entries; + } + + @Override + public List getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) { + return entries; + } + } + + /** + * Constructor. + * @param name - name of the test. + */ + public LanguageSettingsScannerInfoProviderTests(String name) { + super(name); + + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); // includes ResourceHelper cleanup + } + + /** + * @return - new TestSuite. + */ + public static TestSuite suite() { + return new TestSuite(LanguageSettingsScannerInfoProviderTests.class); + } + + /** + * main function of the class. + * + * @param args - arguments + */ + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + /** + * Sets build working directory for DefaultSettingConfiguration being tested. + */ + private void setBuilderCWD(IProject project, IPath buildCWD) throws CoreException { + CProjectDescriptionManager manager = CProjectDescriptionManager.getInstance(); + { + ICProjectDescription prjDescription = manager.getProjectDescription(project, WRITEABLE); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + + cfgDescription.getBuildSetting().setBuilderCWD(buildCWD); + manager.setProjectDescription(project, prjDescription); + // doublecheck builderCWD + IPath actualBuildCWD = cfgDescription.getBuildSetting().getBuilderCWD(); + assertEquals(buildCWD, actualBuildCWD); + } + { + // triplecheck builderCWD for different project/configuration descriptions + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, READ_ONLY); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + + } + } + + /** + * Test cases when some objects are null. + */ + public void testNulls() throws Exception { + { + // Handle project==null + IResource root = ResourcesPlugin.getWorkspace().getRoot(); + assertNull(root.getProject()); + + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(root); + assertEquals(0, info.getIncludePaths().length); + assertEquals(0, info.getDefinedSymbols().size()); + assertEquals(0, info.getIncludeFiles().length); + assertEquals(0, info.getMacroFiles().length); + assertEquals(0, info.getLocalIncludePath().length); + } + + { + // Handle prjDescription==null + IProject project = FAKE_FILE.getProject(); + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, READ_ONLY); + assertNull(prjDescription); + + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(FAKE_FILE); + assertEquals(0, info.getIncludePaths().length); + assertEquals(0, info.getDefinedSymbols().size()); + assertEquals(0, info.getIncludeFiles().length); + assertEquals(0, info.getMacroFiles().length); + assertEquals(0, info.getLocalIncludePath().length); + } + + { + // Handle language==null + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + IFile file = ResourceHelper.createFile(project, "file"); + + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, READ_ONLY); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + ILanguage language = LanguageManager.getInstance().getLanguageForFile(file, cfgDescription); + assertNull(language); + + // AG FIXME - temporarily ignore the entry in the log + setExpectedNumberOfLoggedNonOKStatusObjects(1); + + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(file); + assertEquals(0, info.getIncludePaths().length); + assertEquals(0, info.getDefinedSymbols().size()); + assertEquals(0, info.getIncludeFiles().length); + assertEquals(0, info.getMacroFiles().length); + assertEquals(0, info.getLocalIncludePath().length); + } + } + + /** + * Test empty scanner info. + */ + public void testEmpty() throws Exception { + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + IFile file = ResourceHelper.createFile(project, "file.c"); + + // confirm that language==null + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, READ_ONLY); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + ILanguage language = LanguageManager.getInstance().getLanguageForFile(file, cfgDescription); + assertNotNull(language); + + // test that the info is empty + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(file); + assertEquals(0, info.getIncludePaths().length); + assertEquals(0, info.getDefinedSymbols().size()); + assertEquals(0, info.getIncludeFiles().length); + assertEquals(0, info.getMacroFiles().length); + assertEquals(0, info.getLocalIncludePath().length); + } + + /** + * Test regular cases. + */ + public void testRegular() throws Exception { + // create a project + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, WRITEABLE); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // sample file + IFile file = ResourceHelper.createFile(project, "file.c"); + + // sanity test of language + ILanguage language = LanguageManager.getInstance().getLanguageForFile(file, cfgDescription); + assertNotNull(language); + + // contribute the entries + IFolder includeFolder = ResourceHelper.createFolder(project, "/include-path"); + IFolder includeLocalFolder = ResourceHelper.createFolder(project, "/local-include-path"); + IFile macroFile = ResourceHelper.createFile(project, "macro-file"); + IFile includeFile = ResourceHelper.createFile(project, "include-file"); + + CIncludePathEntry includePathEntry = new CIncludePathEntry(includeFolder, 0); + CIncludePathEntry includeLocalPathEntry = new CIncludePathEntry(includeLocalFolder, ICSettingEntry.LOCAL); // #include "..." + CMacroEntry macroEntry = new CMacroEntry("MACRO", "value",0); + CIncludeFileEntry includeFileEntry = new CIncludeFileEntry(includeFile, 0); + CMacroFileEntry macroFileEntry = new CMacroFileEntry(macroFile, 0); + + List entries = new ArrayList(); + entries.add(includePathEntry); + entries.add(includeLocalPathEntry); + entries.add(macroEntry); + entries.add(includeFileEntry); + entries.add(macroFileEntry); + + // add provider to the configuration + ILanguageSettingsProvider provider = new MockProvider(PROVIDER_ID, PROVIDER_NAME, entries); + List providers = new ArrayList(); + providers.add(provider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + + // set project description + CProjectDescriptionManager.getInstance().setProjectDescription(project, prjDescription); + + // test that the scannerInfoProvider gets the entries + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(file); + String[] actualIncludePaths = info.getIncludePaths(); + Map actualDefinedSymbols = info.getDefinedSymbols(); + String[] actualIncludeFiles = info.getIncludeFiles(); + String[] actualMacroFiles = info.getMacroFiles(); + String[] actualLocalIncludePath = info.getLocalIncludePath(); + // include paths + assertEquals(includeFolder.getLocation(), new Path(actualIncludePaths[0])); + assertEquals(1, actualIncludePaths.length); + // macros + assertEquals(macroEntry.getValue(), actualDefinedSymbols.get(macroEntry.getName())); + assertEquals(1, actualDefinedSymbols.size()); + // include file + assertEquals(includeFile.getLocation(), new Path(actualIncludeFiles[0])); + assertEquals(1, actualIncludeFiles.length); + // macro file + assertEquals(macroFile.getLocation(), new Path(actualMacroFiles[0])); + assertEquals(1, actualMacroFiles.length); + // local include files + assertEquals(includeLocalFolder.getLocation(), new Path(actualLocalIncludePath[0])); + assertEquals(1, actualLocalIncludePath.length); + } + + /** + * Test "local" flag (#include "..."). + */ + public void testLocal() throws Exception { + // create a project + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, WRITEABLE); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // sample file + IFile file = ResourceHelper.createFile(project, "file.c"); + + // contribute the entries + IFolder incFolder = ResourceHelper.createFolder(project, "include"); + IFolder incFolder2 = ResourceHelper.createFolder(project, "include2"); + CIncludePathEntry includePathEntry = new CIncludePathEntry(incFolder, 0); + CIncludePathEntry includeLocalPathEntry = new CIncludePathEntry(incFolder, ICSettingEntry.LOCAL); // #include "..." + CIncludePathEntry includeLocalPathEntry2 = new CIncludePathEntry(incFolder2, ICSettingEntry.LOCAL); // #include "..." + CIncludePathEntry includePathEntry2 = new CIncludePathEntry(incFolder2, 0); + + List entries = new ArrayList(); + entries.add(includePathEntry); + entries.add(includeLocalPathEntry); + // reverse order for incPath2 + entries.add(includeLocalPathEntry2); + entries.add(includePathEntry2); + + // add provider to the configuration + ILanguageSettingsProvider provider = new MockProvider(PROVIDER_ID, PROVIDER_NAME, entries); + List providers = new ArrayList(); + providers.add(provider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + + // set project description + CProjectDescriptionManager.getInstance().setProjectDescription(project, prjDescription); + + // test that the scannerInfoProvider gets the entries + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(file); + String[] actualIncludePaths = info.getIncludePaths(); + String[] actualLocalIncludePath = info.getLocalIncludePath(); + // include paths + assertEquals(incFolder.getLocation(), new Path(actualIncludePaths[0])); + assertEquals(incFolder2.getLocation(), new Path(actualIncludePaths[1])); + assertEquals(2, actualIncludePaths.length); + // local include files + assertEquals(incFolder.getLocation(), new Path(actualLocalIncludePath[0])); + assertEquals(incFolder2.getLocation(), new Path(actualLocalIncludePath[1])); + assertEquals(2, actualLocalIncludePath.length); + } + + /** + * Test Mac frameworks. + */ + public void testFramework() throws Exception { + // create a project + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, WRITEABLE); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // sample file + IFile file = ResourceHelper.createFile(project, "file.c"); + + // contribute the entries + IFolder frameworkFolder = ResourceHelper.createFolder(project, "Fmwk"); + CIncludePathEntry frameworkPathEntry = new CIncludePathEntry(frameworkFolder, ICSettingEntry.FRAMEWORKS_MAC); + + List entries = new ArrayList(); + entries.add(frameworkPathEntry); + + // add provider to the configuration + ILanguageSettingsProvider provider = new MockProvider(PROVIDER_ID, PROVIDER_NAME, entries); + List providers = new ArrayList(); + providers.add(provider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + + // set project description + CProjectDescriptionManager.getInstance().setProjectDescription(project, prjDescription); + + // test that the scannerInfoProvider gets the entries + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(file); + String[] actualIncludePaths = info.getIncludePaths(); + // include paths + assertEquals(frameworkFolder.getLocation().append("/__framework__.framework/Headers/__header__"), + new Path(actualIncludePaths[0])); + assertEquals(frameworkFolder.getLocation().append("/__framework__.framework/PrivateHeaders/__header__"), + new Path(actualIncludePaths[1])); + assertEquals(2, actualIncludePaths.length); + } + + /** + * Test duplicate entries. + */ + public void testDuplicate() throws Exception { + // create a project + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, WRITEABLE); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // sample file + IFile file = ResourceHelper.createFile(project, "file.c"); + + // contribute the entries + IFolder incFolder = ResourceHelper.createFolder(project, "include"); + CIncludePathEntry includePathEntry = new CIncludePathEntry(incFolder, 0); + CIncludePathEntry includeLocalPathEntry = new CIncludePathEntry(incFolder, ICSettingEntry.LOCAL); // #include "..." + CIncludePathEntry includePathEntry2 = new CIncludePathEntry(incFolder, 0); + CIncludePathEntry includeLocalPathEntry2 = new CIncludePathEntry(incFolder, ICSettingEntry.LOCAL); // #include "..." + + List entries = new ArrayList(); + entries.add(includePathEntry); + entries.add(includeLocalPathEntry); + entries.add(includePathEntry2); + entries.add(includeLocalPathEntry2); + + // add provider to the configuration + ILanguageSettingsProvider provider = new MockProvider(PROVIDER_ID, PROVIDER_NAME, entries); + List providers = new ArrayList(); + providers.add(provider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + + // set project description + CProjectDescriptionManager.getInstance().setProjectDescription(project, prjDescription); + + // test that the scannerInfoProvider gets the entries + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(file); + String[] actualIncludePaths = info.getIncludePaths(); + String[] actualLocalIncludePath = info.getLocalIncludePath(); + // include paths + assertEquals(incFolder.getLocation(), new Path(actualIncludePaths[0])); + assertEquals(1, actualIncludePaths.length); + // local include files + assertEquals(incFolder.getLocation(), new Path(actualLocalIncludePath[0])); + assertEquals(1, actualLocalIncludePath.length); + } + + /** + * Test include path managed by eclipse as a workspace path. + */ + public void testWorkspacePath() throws Exception { + // create a project + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, WRITEABLE); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // create sample file + IFile file = ResourceHelper.createFile(project, "file.c"); + // eclipse-managed folder in workspace + IFolder incWorkspace_1 = ResourceHelper.createFolder(project, "include_1"); + IPath incWorkspaceLocation_1 = incWorkspace_1.getLocation(); + IFolder incWorkspace_2 = ResourceHelper.createFolder(project, "include_2"); + IPath incWorkspacePath_2 = incWorkspace_2.getFullPath(); + IPath incWorkspaceLocation_2 = incWorkspace_2.getLocation(); + IFolder incWorkspace_3 = ResourceHelper.createFolder(project, "include_3"); + // "relative" should make no difference for VALUE_WORKSPACE_PATH + IPath incWorkspaceRelativePath_3 = incWorkspace_3.getFullPath().makeRelative(); + IPath incWorkspaceLocation_3 = incWorkspace_3.getLocation(); + // folder defined by absolute path on the filesystem + IPath incFilesystem = ResourceHelper.createWorkspaceFolder("includeFilesystem"); + + // contribute the entries + CIncludePathEntry incWorkspaceEntry_1 = new CIncludePathEntry(incWorkspace_1, 0); + CIncludePathEntry incWorkspaceEntry_2 = new CIncludePathEntry(incWorkspacePath_2, ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED); + CIncludePathEntry incWorkspaceEntry_3 = new CIncludePathEntry(incWorkspaceRelativePath_3, ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED); + CIncludePathEntry incFilesystemEntry = new CIncludePathEntry(incFilesystem, 0); + + List entries = new ArrayList(); + entries.add(incWorkspaceEntry_1); + entries.add(incWorkspaceEntry_2); + entries.add(incWorkspaceEntry_3); + entries.add(incFilesystemEntry); + + // add provider to the configuration + ILanguageSettingsProvider provider = new MockProvider(PROVIDER_ID, PROVIDER_NAME, entries); + List providers = new ArrayList(); + providers.add(provider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + + // set project description + CProjectDescriptionManager.getInstance().setProjectDescription(project, prjDescription); + + // test the entries received from the scannerInfoProvider + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(file); + String[] actualIncludePaths = info.getIncludePaths(); + + assertEquals(incWorkspaceLocation_1, new Path(actualIncludePaths[0])); + assertEquals(incWorkspaceLocation_2, new Path(actualIncludePaths[1])); + assertEquals(incWorkspaceLocation_3, new Path(actualIncludePaths[2])); + assertEquals(incFilesystem, new Path(actualIncludePaths[3])); + assertEquals(4, actualIncludePaths.length); + + } + + /** + * Confirm that device letter is prepended on filesystems that support that. + */ + public void testFilesystemPathNoDriveLetter() throws Exception { + // create a project + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + // change drive on build working directory + String buildCwdDevice = project.getLocation().getDevice(); + +// // Test manually with a device which is different from project location device (path should exist) +// IPath buildCWD = new Path("D:/build/path"); +// String buildCwdDevice = buildCWD.getDevice(); + + // get project/configuration descriptions + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, WRITEABLE); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // create sample file + IFile file = ResourceHelper.createFile(project, "file.c"); + + // contribute the entries + // no-drive-letter folder defined by absolute path on the filesystem + IPath incFilesystem = ResourceHelper.createWorkspaceFolder("includeFilesystem").setDevice(null); + CIncludePathEntry incFilesystemEntry = new CIncludePathEntry(incFilesystem, 0); + List entries = new ArrayList(); + entries.add(incFilesystemEntry); + + // add provider to the configuration + ILanguageSettingsProvider provider = new MockProvider(PROVIDER_ID, PROVIDER_NAME, entries); + List providers = new ArrayList(); + providers.add(provider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + + // set project description + CProjectDescriptionManager.getInstance().setProjectDescription(project, prjDescription); + + // test the entries received from the scannerInfoProvider + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(file); + String[] actualIncludePaths = info.getIncludePaths(); + + IPath expectedInclude = incFilesystem.setDevice(buildCwdDevice); + assertEquals(expectedInclude, new Path(actualIncludePaths[0])); + assertEquals(1, actualIncludePaths.length); + } + + /** + * Test relative paths. + */ + public void testRelativePath() throws Exception { + // create a project + String prjName = getName(); + IProject project = ResourceHelper.createCDTProjectWithConfig(prjName); + String relativePath = "include"; + IFolder buildFolder = ResourceHelper.createFolder(project, "buildDir"); + IFolder relativeFolder = ResourceHelper.createFolder(project, "buildDir/"+relativePath); + IFolder relativeFolderProjName = ResourceHelper.createFolder(project, "buildDir/"+prjName); + String markedResolved = "-MarkedResolved"; + IFolder relativeFolderProjNameResolved = ResourceHelper.createFolder(project, "buildDir/" + prjName+markedResolved); + IPath buildCWD=buildFolder.getLocation(); + setBuilderCWD(project, buildCWD); + + // get project/configuration descriptions + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, WRITEABLE); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // create sample file + IFile file = ResourceHelper.createFile(project, "file.c"); + + // contribute the entries + CIncludePathEntry incRelativeEntry = new CIncludePathEntry(new Path(relativePath), 0); + CIncludePathEntry incProjNameEntry = new CIncludePathEntry(new Path("${ProjName}"), 0); + CIncludePathEntry incProjNameMarkedResolvedEntry = new CIncludePathEntry(new Path("${ProjName}"+markedResolved), ICSettingEntry.RESOLVED); + List entries = new ArrayList(); + entries.add(incRelativeEntry); + entries.add(incProjNameEntry); + entries.add(incProjNameMarkedResolvedEntry); + + // add provider to the configuration + ILanguageSettingsProvider provider = new MockProvider(PROVIDER_ID, PROVIDER_NAME, entries); + List providers = new ArrayList(); + providers.add(provider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + + // set project description + CProjectDescriptionManager.getInstance().setProjectDescription(project, prjDescription); + + // test the entries received from the scannerInfoProvider + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(file); + String[] actualIncludePaths = info.getIncludePaths(); + + // pair of entries, one from build dir another relative path + assertEquals(relativeFolder.getLocation(), new Path(actualIncludePaths[0])); + assertEquals(new Path(relativePath), new Path(actualIncludePaths[1])); + + // pair of entries, one resolved from build dir another expanded relative path + assertEquals(relativeFolderProjName.getLocation(), new Path(actualIncludePaths[2])); + assertEquals(new Path(prjName), new Path(actualIncludePaths[3])); + + // if marked RESOLVED only that path stays + assertEquals(new Path("${ProjName}"+markedResolved), new Path(actualIncludePaths[4])); + + assertEquals(5, actualIncludePaths.length); + } + + /** + * Test relative paths - some combinations of dot paths. + */ + public void testRelativePathWithDots() throws Exception { + // create a project + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + // set build CWD + IFolder buildFolder = ResourceHelper.createFolder(project, "buildDir"); + IPath buildCWD=buildFolder.getLocation(); + setBuilderCWD(project, buildCWD); + + // define a few variations of paths + String relativePath_dot = "."; + String relativePath_dot_slash = "./"; + String relativePath_dot_slash_path = "./include"; + IFolder relativeFolder_dot_slash_path = ResourceHelper.createFolder(project, "buildDir/include"); + String relativePath_dotdot = ".."; + String relativePath_dotdot_slash = "../"; + String relativePath_dotdot_slash_path = "../include"; + IFolder relativeFolder_dotdot_slash_path = ResourceHelper.createFolder(project, "include"); + String locationPath_dotdot_path = buildCWD.toString()+"/../include2"; + IFolder incFolder_dotdot_slash_path = ResourceHelper.createFolder(project, "include2"); // "/ProjPath/buildDir/../include2" + + // get project/configuration descriptions + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, WRITEABLE); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // create sample file + IFile file = ResourceHelper.createFile(project, "file.c"); + + // contribute the entries + CIncludePathEntry incRelativeEntry_dot = new CIncludePathEntry(new Path(relativePath_dot), 0); + CIncludePathEntry incRelativeEntry_dot_slash_path = new CIncludePathEntry(new Path(relativePath_dot_slash_path), 0); + CIncludePathEntry incRelativeEntry_dotdot = new CIncludePathEntry(new Path(relativePath_dotdot), 0); + CIncludePathEntry incRelativeEntry_dotdot_slash_path = new CIncludePathEntry(new Path(relativePath_dotdot_slash_path), 0); + CIncludePathEntry incEntry_dotdot_path = new CIncludePathEntry(locationPath_dotdot_path, 0); + // use LOCAL flag not to clash with plain dot entries + CIncludePathEntry incRelativeEntry_dotdot_slash = new CIncludePathEntry(new Path(relativePath_dotdot_slash), ICSettingEntry.LOCAL); + CIncludePathEntry incRelativeEntry_dot_slash = new CIncludePathEntry(new Path(relativePath_dot_slash), ICSettingEntry.LOCAL); + + List entries = new ArrayList(); + entries.add(incRelativeEntry_dot); + entries.add(incRelativeEntry_dot_slash); + entries.add(incRelativeEntry_dot_slash_path); + entries.add(incRelativeEntry_dotdot); + entries.add(incRelativeEntry_dotdot_slash); + entries.add(incRelativeEntry_dotdot_slash_path); + entries.add(incEntry_dotdot_path); + + // add provider to the configuration + ILanguageSettingsProvider provider = new MockProvider(PROVIDER_ID, PROVIDER_NAME, entries); + List providers = new ArrayList(); + providers.add(provider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + + // set project description + CProjectDescriptionManager.getInstance().setProjectDescription(project, prjDescription); + + // test the entries received from the scannerInfoProvider + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(file); + String[] actualIncludePaths = info.getIncludePaths(); + String[] actualLocalIncludePaths = info.getLocalIncludePath(); + + IPath expectedLocation_dot = buildFolder.getLocation(); + IPath expectedLocation_dot_slash = buildFolder.getLocation(); + IPath expectedLocation_dot_slash_path = relativeFolder_dot_slash_path.getLocation(); + IPath expectedLocation_dotdot = project.getLocation(); + IPath expectedLocation_dotdot_slash = project.getLocation(); + IPath expectedLocation_dotdot_slash_path = relativeFolder_dotdot_slash_path.getLocation(); + + assertEquals(expectedLocation_dot, new Path(actualIncludePaths[0])); + assertEquals(".", actualIncludePaths[1]); + assertEquals(expectedLocation_dot_slash_path, new Path(actualIncludePaths[2])); + assertEquals(new Path(relativePath_dot_slash_path), new Path(actualIncludePaths[3])); + + assertEquals(expectedLocation_dotdot, new Path(actualIncludePaths[4])); + assertEquals("..", actualIncludePaths[5]); + assertEquals(expectedLocation_dotdot_slash_path, new Path(actualIncludePaths[6])); + assertEquals(new Path(relativePath_dotdot_slash_path), new Path(actualIncludePaths[7])); + assertTrue(actualIncludePaths[7].startsWith("..")); + assertEquals(new Path(locationPath_dotdot_path), new Path(actualIncludePaths[8])); + assertTrue(actualIncludePaths[8].contains("..")); + assertEquals(9, actualIncludePaths.length); + + assertEquals(expectedLocation_dot_slash, new Path(actualLocalIncludePaths[0])); + assertEquals(new Path(relativePath_dot_slash), new Path(actualLocalIncludePaths[1])); + assertTrue(actualLocalIncludePaths[1].startsWith(".")); + assertEquals(expectedLocation_dotdot_slash, new Path(actualLocalIncludePaths[2])); + assertEquals(new Path(relativePath_dotdot_slash), new Path(actualLocalIncludePaths[3])); + assertTrue(actualLocalIncludePaths[3].startsWith("..")); + assertEquals(4, actualLocalIncludePaths.length); + } + + /** + * Test if build/environment variables are expanded + */ + public void testEnvironmentVars() throws Exception { + // create a project + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + IFolder folder = ResourceHelper.createFolder(project, "Folder"); + String envPathStr = "${ProjDirPath}/Folder"; + + // get project/configuration descriptions + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, WRITEABLE); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // create sample file + IFile file = ResourceHelper.createFile(project, "file.c"); + + // contribute the entries + CIncludePathEntry incRelativeEntry = new CIncludePathEntry(envPathStr, 0); + List entries = new ArrayList(); + entries.add(incRelativeEntry); + + // add provider to the configuration + ILanguageSettingsProvider provider = new MockProvider(PROVIDER_ID, PROVIDER_NAME, entries); + List providers = new ArrayList(); + providers.add(provider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + + // set project description + CProjectDescriptionManager.getInstance().setProjectDescription(project, prjDescription); + + // test the entries received from the scannerInfoProvider + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(file); + String[] actualIncludePaths = info.getIncludePaths(); + + IPath expectedLocation = folder.getLocation(); + assertEquals(expectedLocation, new Path(actualIncludePaths[0])); + assertEquals(1, actualIncludePaths.length); + } + + /** + * Test from parent folder's entries. + */ + public void testParentFolder() throws Exception { + class MockProviderForResource extends LanguageSettingsBaseProvider implements ILanguageSettingsProvider { + private IResource rc; + private final List entries; + + public MockProviderForResource(IResource rc, List entries) { + this.rc = rc; + this.entries = entries; + } + + @Override + public List getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) { + if (this.rc.equals(rc)) + return entries; + return null; + } + } + + // create a project + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, WRITEABLE); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // sample file + IFolder parentFolder = ResourceHelper.createFolder(project, "ParentFolder"); + IFile file = ResourceHelper.createFile(project, "ParentFolder/file.c"); + + // contribute the entries + IFolder incFolder = ResourceHelper.createFolder(project, "include"); + CIncludePathEntry includePathEntry = new CIncludePathEntry(incFolder, 0); + + List entries = new ArrayList(); + entries.add(includePathEntry); + + // add provider for parent folder + ILanguageSettingsProvider provider = new MockProviderForResource(parentFolder, entries); + assertNull(provider.getSettingEntries(cfgDescription, file, null)); + assertEquals(includePathEntry, provider.getSettingEntries(cfgDescription, parentFolder, null).get(0)); + + List providers = new ArrayList(); + providers.add(provider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + + // set project description + CProjectDescriptionManager.getInstance().setProjectDescription(project, prjDescription); + + // test that the scannerInfoProvider gets the entries for + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(file); + String[] actualIncludePaths = info.getIncludePaths(); + // include paths + assertEquals(incFolder.getLocation(), new Path(actualIncludePaths[0])); + assertEquals(1, actualIncludePaths.length); + } + + /** + * Test resolved paths. + */ + public void testResolvedPath() throws Exception { + // create a project + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + IFolder folder = ResourceHelper.createFolder(project, "Folder"); + String envPathStr = "${ProjDirPath}/Folder"; + + // get project/configuration descriptions + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, WRITEABLE); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // create sample file + IFile file = ResourceHelper.createFile(project, "file.c"); + + // contribute the entries + CIncludePathEntry incRelativeEntry = new CIncludePathEntry(envPathStr, ICSettingEntry.RESOLVED); + List entries = new ArrayList(); + entries.add(incRelativeEntry); + + // add provider to the configuration + ILanguageSettingsProvider provider = new MockProvider(PROVIDER_ID, PROVIDER_NAME, entries); + List providers = new ArrayList(); + providers.add(provider); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + + // set project description + CProjectDescriptionManager.getInstance().setProjectDescription(project, prjDescription); + + // test the entries received from the scannerInfoProvider + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(file); + String[] actualIncludePaths = info.getIncludePaths(); + + // test that RESOLVED entries are not modified + IPath expectedLocation = new Path(envPathStr); + assertEquals(expectedLocation, new Path(actualIncludePaths[0])); + assertEquals(1, actualIncludePaths.length); + } + + /** + * Get languages for the folder. + */ + private List getLanguages(IFolder folder, ICConfigurationDescription cfgDescription) { + IPath rcPath = folder.getProjectRelativePath(); + ICFolderDescription rcDes = (ICFolderDescription) cfgDescription.getResourceDescription(rcPath, false); + ICLanguageSetting[] langSettings = rcDes.getLanguageSettings(); + assertNotNull(langSettings); + + List languageIds = new ArrayList(); + for (ICLanguageSetting ls : langSettings) { + String langId = ls.getLanguageId(); + if (langId!=null && !languageIds.contains(langId)) { + languageIds.add(langId); + } + } + return languageIds; + } + + /** + * Test composition of 2 languages. + */ + public void testResourceLanguages() throws Exception { + class MockProviderLang extends LanguageSettingsBaseProvider implements ILanguageSettingsProvider { + private final String langId; + private final List entries; + + public MockProviderLang(String id, String name, String langId, List entries) { + super(id, name); + this.langId = langId; + this.entries = entries; + } + + @Override + public List getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) { + if (langId==null || langId.equals(languageId)) + return entries; + return new ArrayList(); + } + } + + // create a project + IProject project = ResourceHelper.createCDTProjectWithConfig(getName()); + IFolder folder = ResourceHelper.createFolder(project, "Folder"); + + IFolder incFolderA = ResourceHelper.createFolder(project, "includeA"); + IFolder incFolderB = ResourceHelper.createFolder(project, "includeB"); + IFolder incFolderC = ResourceHelper.createFolder(project, "includeC"); + + // get project/configuration descriptions + ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, WRITEABLE); + assertNotNull(prjDescription); + ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration(); + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + // find 2 languages applicable to the folder + List languageIds = getLanguages(folder, cfgDescription); + assertTrue(languageIds.size() >= 2); + String langId1 = languageIds.get(0); + String langId2 = languageIds.get(1); + + // define overlapping entries + CIncludePathEntry incEntryA = new CIncludePathEntry(incFolderA, 0); + CIncludePathEntry incEntryB = new CIncludePathEntry(incFolderB, 0); + CIncludePathEntry incEntryC = new CIncludePathEntry(incFolderC, 0); + List entries1 = new ArrayList(); + entries1.add(incEntryA); + entries1.add(incEntryB); + List entries2 = new ArrayList(); + entries2.add(incEntryC); + entries2.add(incEntryB); + + // add providers to the configuration + ILanguageSettingsProvider provider1 = new MockProviderLang(PROVIDER_ID, PROVIDER_NAME, langId1, entries1); + ILanguageSettingsProvider provider2 = new MockProviderLang(PROVIDER_ID_2, PROVIDER_NAME, langId2, entries2); + List providers = new ArrayList(); + providers.add(provider1); + providers.add(provider2); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + + // set project description + CProjectDescriptionManager.getInstance().setProjectDescription(project, prjDescription); + + // test the entries received from the scannerInfoProvider + LanguageSettingsScannerInfoProvider scannerInfoProvider = new LanguageSettingsScannerInfoProvider(); + ExtendedScannerInfo info = scannerInfoProvider.getScannerInformation(folder); + String[] actualIncludePaths = info.getIncludePaths(); + + // Test that the result is the union of entries + assertEquals(incFolderA.getLocation(), new Path(actualIncludePaths[0])); + assertEquals(incFolderB.getLocation(), new Path(actualIncludePaths[1])); + assertEquals(incFolderC.getLocation(), new Path(actualIncludePaths[2])); + assertEquals(3, actualIncludePaths.length); + } + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationDescription.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationDescription.java index 3c74980e662..2754c91e3d2 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationDescription.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationDescription.java @@ -18,6 +18,8 @@ import java.util.Map; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.cdtvariables.ICdtVariablesContributor; +import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider; +import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvidersKeeper; import org.eclipse.cdt.core.settings.model.CConfigurationStatus; import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent; import org.eclipse.cdt.core.settings.model.ICBuildSetting; @@ -58,7 +60,8 @@ import org.eclipse.core.runtime.QualifiedName; * @see CConfigurationDescriptionCache * @see CProjectDescriptionEvent */ -public class CConfigurationDescription extends CDataProxyContainer implements ICConfigurationDescription, IProxyFactory, IInternalCCfgInfo { +public class CConfigurationDescription extends CDataProxyContainer + implements ICConfigurationDescription, IProxyFactory, IInternalCCfgInfo, ILanguageSettingsProvidersKeeper { private CfgProxyCache fCache; // private ProxyProvider fFileProxyProvider; // private ProxyProvider fFolderProxyProvider; @@ -825,4 +828,42 @@ public class CConfigurationDescription extends CDataProxyContainer implements IC CConfigurationStatus status = data.getStatus(); return status != null ? status : CConfigurationStatus.CFG_STATUS_OK; } + + @Override + public void setLanguageSettingProviders(List providers) { + try { + getSpecSettings().setLanguageSettingProviders(providers); + } catch (CoreException e) { + CCorePlugin.log(e); + } +} + + @Override + public List getLanguageSettingProviders() { + try { + return getSpecSettings().getLanguageSettingProviders(); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + + @Override + public void setDefaultLanguageSettingsProvidersIds(String[] ids) { + try { + getSpecSettings().setDefaultLanguageSettingsProvidersIds(ids); + } catch (CoreException e) { + CCorePlugin.log(e); + } + } + + @Override + public String[] getDefaultLanguageSettingsProvidersIds() { + try { + return getSpecSettings().getDefaultLanguageSettingsProvidersIds(); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationDescriptionCache.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationDescriptionCache.java index f1285d887c3..5ae75641361 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationDescriptionCache.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationDescriptionCache.java @@ -16,6 +16,8 @@ import java.util.Map; import org.eclipse.cdt.core.cdtvariables.ICdtVariable; import org.eclipse.cdt.core.cdtvariables.ICdtVariablesContributor; +import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider; +import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvidersKeeper; import org.eclipse.cdt.core.settings.model.CConfigurationStatus; import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent; import org.eclipse.cdt.core.settings.model.ICBuildSetting; @@ -88,7 +90,7 @@ import org.eclipse.core.runtime.QualifiedName; * @see CProjectDescriptionEvent */ public class CConfigurationDescriptionCache extends CDefaultConfigurationData - implements ICConfigurationDescription, IInternalCCfgInfo, ICachedData { + implements ICConfigurationDescription, IInternalCCfgInfo, ILanguageSettingsProvidersKeeper, ICachedData { private CProjectDescription fParent; private PathSettingsContainer fPathSettingContainer = PathSettingsContainer.createRootContainer(); private ResourceDescriptionHolder fRcHolder = new ResourceDescriptionHolder(fPathSettingContainer, true); @@ -602,4 +604,27 @@ public class CConfigurationDescriptionCache extends CDefaultConfigurationData return status != null ? status : CConfigurationStatus.CFG_STATUS_OK; } + @Override + public void setLanguageSettingProviders(List providers) { + if(!fInitializing) + throw ExceptionFactory.createIsReadOnlyException(); + fSpecSettings.setLanguageSettingProviders(providers); + } + + @Override + public List getLanguageSettingProviders() { + return fSpecSettings.getLanguageSettingProviders(); + } + + @Override + public void setDefaultLanguageSettingsProvidersIds(String[] ids) { + if(!fInitializing) + throw ExceptionFactory.createIsReadOnlyException(); + fSpecSettings.setDefaultLanguageSettingsProvidersIds(ids); + } + + @Override + public String[] getDefaultLanguageSettingsProvidersIds() { + return fSpecSettings.getDefaultLanguageSettingsProvidersIds(); + } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationSpecSettings.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationSpecSettings.java index 33cc04432cc..d932e819661 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationSpecSettings.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CConfigurationSpecSettings.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.settings.model; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -24,6 +25,7 @@ import java.util.Set; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsBroadcastingProvider; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider; +import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvidersKeeper; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsStorage; import org.eclipse.cdt.core.settings.model.CExternalSetting; @@ -44,6 +46,7 @@ import org.eclipse.cdt.internal.core.COwnerConfiguration; import org.eclipse.cdt.internal.core.cdtvariables.StorableCdtVariables; import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager; import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsDelta; +import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer; import org.eclipse.cdt.utils.envvar.StorableEnvironment; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.QualifiedName; @@ -55,7 +58,7 @@ import org.eclipse.core.runtime.QualifiedName; * This corresponds to the fLanguageSettingsProviders = new ArrayList(0); private LinkedHashMap lspPersistedState = new LinkedHashMap(); + private String[] defaultLanguageSettingsProvidersIds = null; private class DeltaSet { @@ -190,6 +194,21 @@ public class CConfigurationSpecSettings implements ICSettingsStorage{ fOwner = base.fOwner; copyExtensionInfo(base); + + fLanguageSettingsProviders = LanguageSettingsProvidersSerializer.cloneProviders(base.getLanguageSettingProviders()); + for (String providerId : base.lspPersistedState.keySet()) { + try { + LanguageSettingsStorage clone = base.lspPersistedState.get(providerId).clone(); + lspPersistedState.put(providerId, clone); + } catch (CloneNotSupportedException e) { + CCorePlugin.log("Not able to clone language settings storage:" + e); //$NON-NLS-1$ + } + } + if (base.defaultLanguageSettingsProvidersIds != null) { + defaultLanguageSettingsProvidersIds = base.defaultLanguageSettingsProvidersIds.clone(); + } else { + defaultLanguageSettingsProvidersIds = null; + } } // private void copyRefInfos(Map infosMap){ @@ -989,6 +1008,46 @@ public class CConfigurationSpecSettings implements ICSettingsStorage{ ExtensionContainerFactory.updateReferencedProviderIds(fCfg, ids); } + /** + * Adds list of {@link ILanguageSettingsProvider} to the specs. + * Note that only unique IDs are accepted. + * + * @param providers - list of providers to keep in the specs. + */ + @Override + public void setLanguageSettingProviders(List providers) { + fLanguageSettingsProviders = new ArrayList(0); + Set ids = new HashSet(); + for (ILanguageSettingsProvider provider : providers) { + String id = provider.getId(); + if (provider==LanguageSettingsProvidersSerializer.getRawWorkspaceProvider(id)) { + throw new IllegalArgumentException("Error: Attempt to add to the configuration raw global provider " + id); //$NON-NLS-1$ + } + if (!ids.contains(id)) { + fLanguageSettingsProviders.add(provider); + ids.add(id); + } else { + throw new IllegalArgumentException("Language Settings Providers must have unique ID. Duplicate ID=" + id); //$NON-NLS-1$ + } + } + fIsModified = true; + } + + @Override + public List getLanguageSettingProviders() { + return Collections.unmodifiableList(fLanguageSettingsProviders); + } + + @Override + public void setDefaultLanguageSettingsProvidersIds(String[] ids) { + defaultLanguageSettingsProvidersIds = ids; + } + + @Override + public String[] getDefaultLanguageSettingsProvidersIds() { + return defaultLanguageSettingsProvidersIds; + } + /** * Returns delta and updates last persisted state to the new state. * That implies that the delta needs to be used to fire an event of it will