From 60239b57cabe8a751393d33e0c4c7e76cc99d961 Mon Sep 17 00:00:00 2001 From: Andrew Gvozdev Date: Fri, 16 Dec 2011 12:07:36 -0500 Subject: [PATCH] Some clean-up and JavaDoc --- .../AbstractBuiltinSpecsDetector.java | 8 +- ...AbstractLanguageSettingsOutputScanner.java | 2 +- .../LanguageSettingsManagerTests.java | 25 +- ...ILanguageSettingsBroadcastingProvider.java | 3 +- .../ILanguageSettingsChangeEvent.java | 7 +- .../providers/LanguageSettingsManager.java | 72 +-- .../model/util/PathEntryTranslator.java | 8 +- .../providers/LanguageSettingsDelta.java | 2 +- .../providers/LanguageSettingsLogger.java | 2 +- .../LanguageSettingsProvidersSerializer.java | 563 +++++++++--------- .../LanguageSettingsScannerInfoProvider.java | 2 +- .../model/DescriptionScannerInfoProvider.java | 2 +- .../cdt/core/resources/ScannerProvider.java | 2 +- 13 files changed, 343 insertions(+), 355 deletions(-) diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractBuiltinSpecsDetector.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractBuiltinSpecsDetector.java index b0df7f9e374..d5106cfabdf 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractBuiltinSpecsDetector.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractBuiltinSpecsDetector.java @@ -270,7 +270,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti @Override public void registerListener(ICConfigurationDescription cfgDescription) { - // AG FIXME - temporary log to remove before CDT 9.0 release + // AG FIXME - temporary log to remove before CDT Juno release LanguageSettingsLogger.logInfo(getPrefixForLog() + "registerListener [" + System.identityHashCode(this) + "] " + this); currentCfgDescription = cfgDescription; @@ -279,7 +279,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti @Override public void unregisterListener() { - // AG FIXME - temporary log to remove before CDT 9.0 release + // AG FIXME - temporary log to remove before CDT Juno release LanguageSettingsLogger.logInfo(getPrefixForLog() + "unregisterListener [" + System.identityHashCode(this) + "] " + this); } @@ -320,7 +320,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti job.setRule(rule); job.schedule(); - // AG FIXME - temporary log to remove before CDT 9.0 release + // AG FIXME - temporary log to remove before CDT Juno release LanguageSettingsLogger.logInfo(getPrefixForLog() + "Execution scheduled [" + System.identityHashCode(this) + "] " + this); } @@ -463,7 +463,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti if (detectedSettingEntries != null && detectedSettingEntries.size() > 0) { collected = detectedSettingEntries.size(); - // AG FIXME - temporary log to remove before CDT 9.0 release + // AG FIXME - temporary log to remove before CDT Juno release LanguageSettingsLogger.logInfo(getPrefixForLog() + getClass().getSimpleName() + " collected " + detectedSettingEntries.size() + " entries" + " for language " + currentLanguageId); diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractLanguageSettingsOutputScanner.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractLanguageSettingsOutputScanner.java index 96588e50935..848f9307861 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractLanguageSettingsOutputScanner.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractLanguageSettingsOutputScanner.java @@ -320,7 +320,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett protected void setSettingEntries(List entries) { setSettingEntries(currentCfgDescription, currentResource, currentLanguageId, entries); - // AG FIXME - temporary log to remove before CDT 9.0 release + // AG FIXME - temporary log to remove before CDT Juno release LanguageSettingsLogger.logInfo(getPrefixForLog() + getClass().getSimpleName() + " collected " + (entries!=null ? ("" + entries.size()) : "null") + " entries for " + currentResource); } 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 16b286f145a..66855fae87a 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 @@ -198,7 +198,7 @@ public class LanguageSettingsManagerTests extends BaseTestCase { assertEquals(0, actual.size()); } { - List actual = LanguageSettingsManager + List actual = LanguageSettingsProvidersSerializer .getSettingEntriesByKind(cfgDescription, FILE_0, LANG_ID, 0); assertNotNull(actual); assertEquals(0, actual.size()); @@ -226,7 +226,7 @@ public class LanguageSettingsManagerTests extends BaseTestCase { assertEquals(1, actual.size()); } { - List actual = LanguageSettingsManager + List actual = LanguageSettingsProvidersSerializer .getSettingEntriesByKind(cfgDescription, FILE_0, LANG_ID, 0); assertNotNull(actual); assertEquals(0, actual.size()); @@ -486,14 +486,14 @@ public class LanguageSettingsManagerTests extends BaseTestCase { cfgDescription.setLanguageSettingProviders(providers); // retrieve entries by kind - List includes = LanguageSettingsManager + List includes = LanguageSettingsProvidersSerializer .getSettingEntriesByKind(cfgDescription, FILE_0, LANG_ID, ICSettingEntry.INCLUDE_PATH); assertEquals(new CIncludePathEntry("path0", 0),includes.get(0)); assertEquals(new CIncludePathEntry("path1", 0),includes.get(1)); assertEquals(new CIncludePathEntry("path2", 0),includes.get(2)); assertEquals(3, includes.size()); - List macros = LanguageSettingsManager + List macros = LanguageSettingsProvidersSerializer .getSettingEntriesByKind(cfgDescription, FILE_0, LANG_ID, ICSettingEntry.MACRO); assertEquals(new CMacroEntry("MACRO0", "value0",0), macros.get(0)); assertEquals(new CMacroEntry("MACRO1", "value1",0), macros.get(1)); @@ -518,8 +518,7 @@ public class LanguageSettingsManagerTests extends BaseTestCase { cfgDescription.setLanguageSettingProviders(providers); // retrieve entries by kind, only first entry should be returned - List includes = LanguageSettingsManager - .getSettingEntriesByKind(cfgDescription, FILE_0, LANG_ID, ICSettingEntry.INCLUDE_PATH); + List includes = LanguageSettingsProvidersSerializer.getSettingEntriesByKind(cfgDescription, FILE_0, LANG_ID, ICSettingEntry.INCLUDE_PATH); assertEquals(1, includes.size()); assertEquals(entries.get(0),includes.get(0)); } @@ -541,7 +540,7 @@ public class LanguageSettingsManagerTests extends BaseTestCase { cfgDescription.setLanguageSettingProviders(providers); // retrieve entries by kind, no entries should be returned - List includes = LanguageSettingsManager + List includes = LanguageSettingsProvidersSerializer .getSettingEntriesByKind(cfgDescription, FILE_0, LANG_ID, ICSettingEntry.INCLUDE_PATH); assertEquals(0, includes.size()); } @@ -619,7 +618,7 @@ public class LanguageSettingsManagerTests extends BaseTestCase { cfgDescription.setLanguageSettingProviders(providers); // retrieve entries by kind - List includes = LanguageSettingsManager + List includes = LanguageSettingsProvidersSerializer .getSettingEntriesByKind(cfgDescription, FILE_0, LANG_ID, ICSettingEntry.INCLUDE_PATH); // path0 is taken from higher priority provider assertEquals(entriesHigh.get(0),includes.get(0)); @@ -828,7 +827,7 @@ public class LanguageSettingsManagerTests extends BaseTestCase { LanguageSettingsSerializableProvider provider = new LanguageSettingsSerializableProvider(PROVIDER_1, PROVIDER_NAME_1); provider.setSettingEntries(null, file, null, entries); // build the hierarchy - LanguageSettingsManager.buildResourceTree(provider, null, null, project); + LanguageSettingsProvidersSerializer.buildResourceTree(provider, null, null, project); // check that entries go to highest possible level assertEquals(entries, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file, null)); @@ -857,7 +856,7 @@ public class LanguageSettingsManagerTests extends BaseTestCase { provider.setSettingEntries(null, file1, null, entries1); provider.setSettingEntries(null, file2, null, entries2); // build the hierarchy - LanguageSettingsManager.buildResourceTree(provider, null, null, project); + LanguageSettingsProvidersSerializer.buildResourceTree(provider, null, null, project); // check that entries go to highest possible level assertEquals(entries1, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file1, null)); @@ -891,7 +890,7 @@ public class LanguageSettingsManagerTests extends BaseTestCase { provider.setSettingEntries(null, file1, null, entries1); provider.setSettingEntries(null, file2, null, entries1); // build the hierarchy - LanguageSettingsManager.buildResourceTree(provider, null, null, project); + LanguageSettingsProvidersSerializer.buildResourceTree(provider, null, null, project); // double-check where the entries go assertEquals(entries1, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file1, null)); assertEquals(entries1, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file2, null)); @@ -901,7 +900,7 @@ public class LanguageSettingsManagerTests extends BaseTestCase { provider.setSettingEntries(null, file2, null, entries2); provider.setSettingEntries(null, file3, null, entries2); // build the hierarchy - LanguageSettingsManager.buildResourceTree(provider, null, null, project); + LanguageSettingsProvidersSerializer.buildResourceTree(provider, null, null, project); // check where the entries go, it should not lose entries for the first file assertEquals(entries1, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file1, null)); assertEquals(entries2, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file2, null)); @@ -926,7 +925,7 @@ public class LanguageSettingsManagerTests extends BaseTestCase { LanguageSettingsSerializableProvider provider = new LanguageSettingsSerializableProvider(PROVIDER_1, PROVIDER_NAME_1); provider.setSettingEntries(null, file, LANG_CPP, entries); // build the hierarchy - LanguageSettingsManager.buildResourceTree(provider, null, LANG_CPP, project); + LanguageSettingsProvidersSerializer.buildResourceTree(provider, null, LANG_CPP, project); // check that entries go to highest possible level assertEquals(entries, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file, LANG_CPP)); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ILanguageSettingsBroadcastingProvider.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ILanguageSettingsBroadcastingProvider.java index 5ab3297eab3..68a1b95da54 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ILanguageSettingsBroadcastingProvider.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ILanguageSettingsBroadcastingProvider.java @@ -14,12 +14,11 @@ import java.util.List; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; -import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer; import org.eclipse.core.resources.IResource; /** * This interface is to be implemented by providers which want to broadcast the changes in their setting entries - * by {@link LanguageSettingsProvidersSerializer#notifyLanguageSettingsChangeListeners(ILanguageSettingsChangeEvent)} + * with {@link ILanguageSettingsChangeEvent}. */ public interface ILanguageSettingsBroadcastingProvider extends ILanguageSettingsProvider { @Override diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ILanguageSettingsChangeEvent.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ILanguageSettingsChangeEvent.java index 15099441d9b..fca6b4a60ef 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ILanguageSettingsChangeEvent.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ILanguageSettingsChangeEvent.java @@ -14,13 +14,14 @@ import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; /** * Contains the details of changes that occurred as a result of modifying - * language settings entries {@link ICLanguageSettingEntry}. The event is - * associated with a project. + * language settings entries {@link ICLanguageSettingEntry}. This event is + * intended to be fired for changes in entries, not necessarily providers. + * The event is associated with a project. * *

* EXPERIMENTAL. This class interface is not stable yet as * it is not currently clear how it may need to be used in future. Only bare - * minimum is provided here at this point (CDT 9.0). + * minimum is provided here at this point (CDT 9.0, Juno). * There is no guarantee that this API will work or that it will remain the same. * Please do not use this API without consulting with the CDT team. *

diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManager.java index c51c0eab544..4aa43ae7290 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManager.java @@ -24,11 +24,9 @@ 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.ICResourceDescription; -import org.eclipse.cdt.core.settings.model.ICSettingEntry; import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsExtensionManager; import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer; import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; @@ -42,7 +40,7 @@ public class LanguageSettingsManager { * Returns the list of setting entries of the given provider * for the given configuration description, resource and language. * This method reaches to the parent folder of the resource recursively - * in case the resource does not define the entries for the given provider. + * if the resource does not define the entries for the given provider. * * @param provider - language settings provider. * @param cfgDescription - configuration description. @@ -56,52 +54,9 @@ public class LanguageSettingsManager { return LanguageSettingsProvidersSerializer.getSettingEntriesUpResourceTree(provider, cfgDescription, rc, languageId); } - /** - * Builds for the provider a nice looking resource tree to present hierarchical view to the user. - * - * TODO - Note that after using this method for a while for BOP parsers it appears that disadvantages - * outweigh benefits. In particular, it doesn't result in saving memory as the language settings - * (and the lists itself) are not duplicated in memory anyway but optimized with using WeakHashSet - * and SafeStringInterner. - * - * @param provider - language settings provider to build the tree for. - * @param cfgDescription - configuration description. - * @param languageId - language ID. - * @param project - the project which is considered the root of the resource tree. - */ - public static void buildResourceTree(LanguageSettingsSerializableProvider provider, - ICConfigurationDescription cfgDescription, String languageId, IProject project) { - LanguageSettingsProvidersSerializer.buildResourceTree(provider, cfgDescription, languageId, project); - } - - - /** - * Returns the list of setting entries of a certain kind (such as include paths) - * for the given configuration description, resource and language. This is a - * combined list for all providers taking into account settings of parent folder - * if settings for the given resource are not defined. - * - * @param cfgDescription - configuration description. - * @param rc - resource such as file or folder. - * @param languageId - language id. - * @param kind - kind of language settings entries, such as - * {@link ICSettingEntry#INCLUDE_PATH} etc. This is a binary flag - * and it is possible to specify composite kind. - * Use {@link ICSettingEntry#ALL} to get all kinds. - * - * @return the list of setting entries. - */ - // FIXME: get rid of callers PathEntryTranslator and DescriptionScannerInfoProvider - public static List getSettingEntriesByKind(ICConfigurationDescription cfgDescription, IResource rc, String languageId, int kind) { - return LanguageSettingsProvidersSerializer.getSettingEntriesByKind(cfgDescription, rc, languageId, kind); - } - - /** - * Get Language Settings Provider defined in the workspace. That includes user-defined - * providers and after that providers defined as extensions via - * {@code org.eclipse.cdt.core.LanguageSettingsProvider} extension point. - * That returns actual object, any modifications will affect any configuration - * referring to the provider. +/** + * Get Language Settings Provider from the list of workspace providers, + * see {@link #getWorkspaceProviders()}. * * @param id - id of provider to find. * @return the provider or {@code null} if provider is not defined. @@ -111,10 +66,14 @@ public class LanguageSettingsManager { } /** - * @return a list of language settings providers defined on workspace level. - * That includes user-defined providers and after that providers defined as - * extensions via {@code org.eclipse.cdt.core.LanguageSettingsProvider} - * extension point. + * Get Language Settings Providers defined in the workspace. That includes + * user-defined providers and after that providers defined as extensions via + * {@code org.eclipse.cdt.core.LanguageSettingsProvider} extension point. + * Note that this returns wrappers around workspace provider so underlying + * provider could be replaced internally without need to change configuration. + * See also {@link #getRawProvider(ILanguageSettingsProvider)}. + * + * @return list of workspace providers. */ public static List getWorkspaceProviders() { return LanguageSettingsProvidersSerializer.getWorkspaceProviders(); @@ -137,7 +96,7 @@ public class LanguageSettingsManager { * Helper method to get to real underlying provider collecting entries as opposed to wrapper * which is normally used for workspace provider. * @see LanguageSettingsProvidersSerializer#isWorkspaceProvider(ILanguageSettingsProvider) - * + * * @param provider - the provider to get raw provider for. Can be either workspace provider * or regular one. * @return raw underlying provider for workspace provider or provider itself if no wrapper is used. @@ -168,7 +127,7 @@ public class LanguageSettingsManager { * Copy language settings provider. It is different from clone() methods in that * it does not throw {@code CloneNotSupportedException} but returns {@code null} * instead. - * + * * @param provider - language settings provider to copy. * @param deep - {@code true} to request deep copy including copying settings entries * or {@code false} to return shallow copy with no settings entries. @@ -197,7 +156,7 @@ public class LanguageSettingsManager { /** * Test if the provider is equal to the one defined via extension point * {@code org.eclipse.cdt.core.LanguageSettingsProvider}. - * + * * @param provider - the provider to test. * @param deep - {@code true} to check for deep equality testing also settings entries * or {@code false} to test shallow copy with no settings entries. @@ -344,5 +303,4 @@ public class LanguageSettingsManager { public static void serializeLanguageSettingsWorkspace() throws CoreException { LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspace(); } - } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java index 8a29a9ab166..b347ac81b3a 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java @@ -26,7 +26,6 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.cdtvariables.CdtVariableException; import org.eclipse.cdt.core.cdtvariables.ICdtVariable; import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager; -import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager; import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CoreModel; @@ -71,6 +70,7 @@ import org.eclipse.cdt.internal.core.cdtvariables.CoreVariableSubstitutor; import org.eclipse.cdt.internal.core.cdtvariables.DefaultVariableContextInfo; import org.eclipse.cdt.internal.core.cdtvariables.ICoreVariableContextInfo; import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsLogger; +import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer; import org.eclipse.cdt.internal.core.model.APathEntry; import org.eclipse.cdt.internal.core.model.CModelStatus; import org.eclipse.cdt.internal.core.model.PathEntry; @@ -2041,7 +2041,7 @@ public class PathEntryTranslator { public boolean visit(PathSettingsContainer container) { CResourceData data = (CResourceData)container.getValue(); if (data != null) { - // AG FIXME - temporary log to remove before CDT 9.0 release + // AG FIXME - temporary log to remove before CDT Juno release temporaryLog(des, kinds, data); PathEntryCollector child = cr.createChild(container.getPath()); @@ -2056,7 +2056,7 @@ public class PathEntryTranslator { return true; } - // AG FIXME - temporary log to remove before CDT 9.0 release + // AG FIXME - temporary log to remove before CDT Juno release @Deprecated private void temporaryLog(final ICConfigurationDescription des, final int[] kinds, CResourceData data) { String kindsStr=""; @@ -2099,7 +2099,7 @@ public class PathEntryTranslator { if (ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityEnabled(project)) { IResource rc = getResource(project, data.getPath()); for (CLanguageData lData : lDatas) { - list.addAll(LanguageSettingsManager.getSettingEntriesByKind(des, rc, lData.getLanguageId(), kind)); + list.addAll(LanguageSettingsProvidersSerializer.getSettingEntriesByKind(des, rc, lData.getLanguageId(), kind)); } return list.size()>0; diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsDelta.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsDelta.java index 994597b69fb..ab21380266d 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsDelta.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsDelta.java @@ -24,7 +24,7 @@ import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; *

* EXPERIMENTAL. This class interface is not stable yet as * it is not currently clear how it may need to be used in future. Only bare - * minimum is provided here at this point (CDT 9.0). + * minimum is provided here at this point (CDT 9.0, Juno). * There is no guarantee that this API will work or that it will remain the same. * Please do not use this API without consulting with the CDT team. *

diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsLogger.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsLogger.java index 8babc9e1605..d5b0d6aebd6 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsLogger.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsLogger.java @@ -9,7 +9,7 @@ import org.eclipse.core.runtime.Status; /** * AG FIXME -Temporary class for logging language settings providers development. - * To remove before CDT 9.0 release + * To remove before CDT Juno release * */ @Deprecated diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java index 55082c1fb3a..3dcbf5713fc 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java @@ -71,7 +71,7 @@ public class LanguageSettingsProvidersSerializer { public static final String ELEM_PROVIDER = LanguageSettingsExtensionManager.ELEM_PROVIDER; public static final String ELEM_LANGUAGE_SCOPE = LanguageSettingsExtensionManager.ELEM_LANGUAGE_SCOPE; - private static final String PREFERENCE_WORSPACE_PROVIDERS_SET = "language.settings.providers.set.for.workspace"; //$NON-NLS-1$ + private static final String PREFERENCE_WORSPACE_PROVIDERS_SET = "language.settings.providers.workspace.prefs.toggle"; //$NON-NLS-1$ private static final String STORAGE_WORKSPACE_LANGUAGE_SETTINGS = "language.settings.xml"; //$NON-NLS-1$ private static final String SETTINGS_FOLDER_NAME = ".settings/"; //$NON-NLS-1$ private static final String STORAGE_PROJECT_LANGUAGE_SETTINGS = "language.settings.xml"; //$NON-NLS-1$ @@ -87,13 +87,13 @@ public class LanguageSettingsProvidersSerializer { private static final String VALUE_WORKSPACE = "workspace"; //$NON-NLS-1$ private static final String VALUE_PROJECT = "project"; //$NON-NLS-1$ - private static ILock serializingLock = Job.getJobManager().newLock(); - - /** Cache of globally available providers to be consumed by calling clients */ + /** Cache of true (raw) workspace providers */ private static Map rawGlobalWorkspaceProviders = new HashMap(); + /** Cache of workspace providers wrappers */ private static Map globalWorkspaceProviders = new HashMap(); private static ListenerList fLanguageSettingsChangeListeners = new ListenerList(ListenerList.IDENTITY); + private static ILock serializingLock = Job.getJobManager().newLock(); /** * language settings provider listener-cfgDescription association @@ -269,11 +269,35 @@ public class LanguageSettingsProvidersSerializer { try { loadLanguageSettingsWorkspace(); } catch (Throwable e) { - // log and swallow any exception + // log but swallow any exception CCorePlugin.log("Error loading workspace language settings providers", e); //$NON-NLS-1$ } } + /** + * Tells if language settings entries of the provider are persisted with the project + * (under .settings/ folder) or in workspace area. Persistence in the project area lets + * the entries migrate with the project. + * + * @param provider - provider to check the persistence mode. + * @return {@code true} if LSE persisted with the project or {@code false} if in the workspace. + */ + public static boolean isStoringEntriesInProjectArea(LanguageSettingsSerializableProvider provider) { + String value = provider.getProperty(ATTR_STORE_ENTRIES); + return VALUE_PROJECT.equals(value); + } + + /** + * Define where language settings are persisted for the provider. + * + * @param provider - provider to set the persistence mode. + * @param storeEntriesWithProject - {@code true} if with the project, + * {@code false} if in workspace area. + */ + public static void setStoringEntriesInProjectArea(LanguageSettingsSerializableProvider provider, boolean storeEntriesWithProject) { + provider.setProperty(ATTR_STORE_ENTRIES, storeEntriesWithProject ? VALUE_PROJECT : VALUE_WORKSPACE); + } + /** * Determine location of the project store of language settings providers in the plug-in state area. * @@ -309,7 +333,7 @@ public class LanguageSettingsProvidersSerializer { public static void setWorkspaceProviders(List providers) throws CoreException { setWorkspaceProvidersInternal(providers); serializeLanguageSettingsWorkspace(); - // generate preference change event + // generate preference change event for preference change listeners (value is not intended to be used) IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(CCorePlugin.PLUGIN_ID); prefs.putBoolean(PREFERENCE_WORSPACE_PROVIDERS_SET, ! prefs.getBoolean(PREFERENCE_WORSPACE_PROVIDERS_SET, false)); } @@ -437,7 +461,7 @@ public class LanguageSettingsProvidersSerializer { * @throws CoreException */ public static void serializeLanguageSettingsWorkspace() throws CoreException { - // AG FIXME - temporary log to remove before CDT 9.0 release + // AG FIXME - temporary log to remove before CDT Juno release LanguageSettingsLogger.logWarning("LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspace()"); URI uriStoreWsp = getStoreInWorkspaceArea(STORAGE_WORKSPACE_LANGUAGE_SETTINGS); @@ -540,8 +564,7 @@ public class LanguageSettingsProvidersSerializer { * @noreference This method is not intended to be referenced by clients. * It is public solely for benefit of JUnit testing. */ - public static void serializeLanguageSettingsInternal(Element projectElementPrjStore, Element projectElementWspStore, ICProjectDescription prjDescription) throws CoreException { - + public static void serializeLanguageSettingsInternal(Element projectElementPrjStore, Element projectElementWspStore, ICProjectDescription prjDescription) { ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations(); for (ICConfigurationDescription cfgDescription : cfgDescriptions) { if (!(cfgDescription instanceof ILanguageSettingsProvidersKeeper)) @@ -552,11 +575,13 @@ public class LanguageSettingsProvidersSerializer { ATTR_NAME, cfgDescription.getName(), }); Element elementConfigurationWsp = null; + List providers = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); if (providers.size()>0) { Element elementExtension = XmlUtil.appendElement(elementConfiguration, ELEM_EXTENSION, new String[] { ATTR_EXTENSION_POINT, PROVIDER_EXTENSION_POINT_ID}); Element elementExtensionWsp = null; + for (ILanguageSettingsProvider provider : providers) { if (isWorkspaceProvider(provider)) { // Element elementProviderReference = @@ -565,28 +590,34 @@ public class LanguageSettingsProvidersSerializer { continue; } if (provider instanceof LanguageSettingsSerializableProvider) { - LanguageSettingsSerializableProvider lss = (LanguageSettingsSerializableProvider) provider; + try { + LanguageSettingsSerializableProvider lss = (LanguageSettingsSerializableProvider) provider; - boolean useWsp = projectElementWspStore!=null && projectElementPrjStore!=projectElementWspStore; - if (isStoringEntriesInProjectArea(lss) || !useWsp) { - lss.serialize(elementExtension); - } else { - lss.serializeAttributes(elementExtension); - - // lazy initialization of elements - to avoid serialization of no-data file - if (elementExtensionWsp==null) { - if (elementConfigurationWsp==null) { - elementConfigurationWsp = XmlUtil.appendElement(projectElementWspStore, ELEM_CONFIGURATION, new String[] { - ATTR_ID, cfgDescription.getId(), - ATTR_NAME, cfgDescription.getName(), - }); + boolean isWspStorageAvailable = (projectElementWspStore != null) && (projectElementPrjStore != projectElementWspStore); + if (isStoringEntriesInProjectArea(lss) || !isWspStorageAvailable) { + lss.serialize(elementExtension); + } else { + // lazy initialization of wsp storage elements - to avoid serialization of no-data file + if (elementExtensionWsp == null) { + if (elementConfigurationWsp == null) { + elementConfigurationWsp = XmlUtil.appendElement(projectElementWspStore, ELEM_CONFIGURATION, new String[] { + ATTR_ID, cfgDescription.getId(), + ATTR_NAME, cfgDescription.getName(), + }); + } + elementExtensionWsp = XmlUtil.appendElement(elementConfigurationWsp, ELEM_EXTENSION, new String[] { + ATTR_EXTENSION_POINT, PROVIDER_EXTENSION_POINT_ID}); } - elementExtensionWsp = XmlUtil.appendElement(elementConfigurationWsp, ELEM_EXTENSION, new String[] { - ATTR_EXTENSION_POINT, PROVIDER_EXTENSION_POINT_ID}); + Element elementProviderWsp = XmlUtil.appendElement(elementExtensionWsp, ELEM_PROVIDER, new String[] { + ATTR_ID, provider.getId()}); + + // split storage + lss.serializeAttributes(elementExtension); + lss.serializeEntries(elementProviderWsp); } - Element elementProviderWsp = XmlUtil.appendElement(elementExtensionWsp, ELEM_PROVIDER, new String[] { - ATTR_ID, provider.getId()}); - lss.serializeEntries(elementProviderWsp); + } catch (Throwable e) { + // protect from any exceptions from implementers + CCorePlugin.log("Exception trying serialize provider "+provider.getId(), e); //$NON-NLS-1$ } } else { // Element elementProvider = @@ -609,10 +640,13 @@ public class LanguageSettingsProvidersSerializer { */ public static void serializeLanguageSettings(ICProjectDescription prjDescription) throws CoreException { IProject project = prjDescription.getProject(); - // AG FIXME - temporary log to remove before CDT 9.0 release + // AG FIXME - temporary log to remove before CDT Juno release LanguageSettingsLogger.logWarning("LanguageSettingsProvidersSerializer.serializeLanguageSettings() for " + project); try { + // The storage could be split in two, one for provider properties, another one for entries, + // depending on provider flag + // Document to store in project area Document docStorePrj = XmlUtil.newDocument(); Element projectElementStorePrj = XmlUtil.appendElement(docStorePrj, ELEM_PROJECT); @@ -620,7 +654,7 @@ public class LanguageSettingsProvidersSerializer { Document docStoreWsp = XmlUtil.newDocument(); Element projectElementStoreWsp = XmlUtil.appendElement(docStoreWsp, ELEM_PROJECT); - // The project store should not be absent. Absent store means legacy project, not 0 providers. + // The project store should not be absent. Currently absent store means legacy project, not 0 providers. IFile fileStorePrj = getStoreInProjectArea(project); URI uriStoreWsp = getStoreInWorkspaceArea(project.getName()+'.'+STORAGE_WORKSPACE_LANGUAGE_SETTINGS); @@ -629,17 +663,17 @@ public class LanguageSettingsProvidersSerializer { try { serializingLock.acquire(); - // Note that need for serialization may exist even if LSE event delta is empty, - // as number or properties of providers may differ + // Note that need for serialization may exist even if LS *entries* event delta is empty, + // as set of providers or their properties may differ serializeLanguageSettingsInternal(projectElementStorePrj, projectElementStoreWsp, prjDescription); XmlUtil.serializeXml(docStorePrj, fileStorePrj); // project-specific location in workspace area boolean isWorkspaceStoreEmpty = projectElementStoreWsp.getChildNodes().getLength() == 0; - if (!isWorkspaceStoreEmpty) { - XmlUtil.serializeXml(docStoreWsp, uriStoreWsp); - } else { + if (isWorkspaceStoreEmpty) { new java.io.File(uriStoreWsp).delete(); + } else { + XmlUtil.serializeXml(docStoreWsp, uriStoreWsp); } // manufacture the event only if serialization was successful @@ -677,45 +711,41 @@ public class LanguageSettingsProvidersSerializer { */ NodeList configurationNodes = projectElementPrj.getChildNodes(); - for (int ic=0;ic providers = new ArrayList(); String cfgId = XmlUtil.determineAttributeValue(cfgNode, ATTR_ID); - @SuppressWarnings("unused") - String cfgName = XmlUtil.determineAttributeValue(cfgNode, ATTR_NAME); - NodeList extensionAndReferenceNodes = cfgNode.getChildNodes(); - for (int ie=0;ie @@ -746,52 +786,51 @@ public class LanguageSettingsProvidersSerializer { */ - NodeList configurationNodes = projectElementWsp.getChildNodes(); - for (int ic=0;ic + doc = XmlUtil.loadXml(storeInPrjArea); + Element rootElementPrj = doc.getDocumentElement(); // URI uriStoreWsp = getStoreInWorkspaceArea(project.getName()+'.'+STORAGE_WORKSPACE_LANGUAGE_SETTINGS); Document docWsp = null; @@ -824,18 +864,14 @@ public class LanguageSettingsProvidersSerializer { serializingLock.release(); } - Element rootElementWsp = null; // - if (docWsp!=null) { + Element rootElementWsp = null; // + if (docWsp != null) { rootElementWsp = docWsp.getDocumentElement(); } - loadLanguageSettingsInternal(rootElementPrj, rootElementWsp, prjDescription); } catch (Exception e) { - CCorePlugin.log("Can't load preferences from file "+storePrj.getLocation(), e); //$NON-NLS-1$ - } - - if (doc!=null) { + CCorePlugin.log("Can't load preferences from file " + storeInPrjArea.getLocation(), e); //$NON-NLS-1$ } } else { @@ -854,11 +890,8 @@ public class LanguageSettingsProvidersSerializer { } /** - * FIXME Get Language Settings Provider defined in the workspace. That includes user-defined - * providers and after that providers defined as extensions via - * {@code org.eclipse.cdt.core.LanguageSettingsProvider} extension point. - * That returns actual object, any modifications will affect any configuration - * referring to the provider. + * Get Language Settings Provider from the list of workspace providers, + * see {@link #getWorkspaceProviders()}. * * @param id - ID of provider to find. * @return the provider or {@code null} if provider is not defined. @@ -873,9 +906,9 @@ public class LanguageSettingsProvidersSerializer { } /** - * Helper method to get to real underlying provider collecting entries as opposed to wrapper - * which is normally used for workspace provider. - * @see LanguageSettingsProvidersSerializer#isWorkspaceProvider(ILanguageSettingsProvider) + * Helper method to get to real underlying provider collecting entries as opposed + * to wrapper which is normally used for workspace provider. + * @see #isWorkspaceProvider(ILanguageSettingsProvider) * * @param id - ID of the provider. * @return raw underlying provider. @@ -885,9 +918,14 @@ public class LanguageSettingsProvidersSerializer { } /** - * TODO - * @return ordered set of providers defined in the workspace which include contributed through extension + user defined ones + * Get Language Settings Providers defined in the workspace. That includes + * user-defined providers and after that providers defined as extensions via + * {@code org.eclipse.cdt.core.LanguageSettingsProvider} extension point. + * Note that this returns wrappers around workspace provider so underlying + * provider could be replaced internally without need to change configuration. + * See also {@link #getRawWorkspaceProvider(String)}. * + * @return list of workspace providers. */ public static List getWorkspaceProviders() { ArrayList workspaceProviders = new ArrayList(); @@ -911,9 +949,10 @@ public class LanguageSettingsProvidersSerializer { } /** - * TODO - remove me - * Temporary method to report inconsistency in log. + * Reports inconsistency in log. + * AG FIXME - temporary method to remove before CDT Juno release */ + @SuppressWarnings("nls") @Deprecated public static void assertConsistency(ICProjectDescription prjDescription) { if (prjDescription != null) { @@ -1029,33 +1068,35 @@ public class LanguageSettingsProvidersSerializer { */ public static void reRegisterListeners(ICProjectDescription oldPrjDescription, ICProjectDescription newPrjDescription) { if (oldPrjDescription == newPrjDescription) { - assertConsistency(oldPrjDescription); // TODO - remove me + assertConsistency(oldPrjDescription); return; } - assertConsistency(oldPrjDescription); // TODO - remove me - assertConsistency(newPrjDescription); // TODO - remove me + assertConsistency(oldPrjDescription); + assertConsistency(newPrjDescription); List oldListeners = getListeners(oldPrjDescription); List newAssociations = getListenersAssociations(newPrjDescription); + // unregister old listeners for (ICListenerAgent oldListener : oldListeners) { if (!isListenerInTheListOfAssociations(newAssociations, oldListener)) { int count = 0; if (oldListener instanceof LanguageSettingsWorkspaceProvider) { count = ((LanguageSettingsWorkspaceProvider) oldListener).decrementProjectCount(); } - if (count == 0) { + if (count <= 0) { try { oldListener.unregisterListener(); } catch (Throwable e) { // protect from any exceptions from implementers - CCorePlugin.log(e); + CCorePlugin.log("Exception trying unregister listener "+((ILanguageSettingsProvider) oldListener).getId(), e); //$NON-NLS-1$ } } } } + // register new listeners for (ListenerAssociation newListenerAssociation : newAssociations) { ICListenerAgent newListener = newListenerAssociation.listener; if (!isInList(oldListeners, newListener)) { @@ -1068,7 +1109,7 @@ public class LanguageSettingsProvidersSerializer { newListener.registerListener(newListenerAssociation.cfgDescription); } catch (Throwable e) { // protect from any exceptions from implementers - CCorePlugin.log(e); + CCorePlugin.log("Exception trying register listener "+((ILanguageSettingsProvider) newListener).getId(), e); //$NON-NLS-1$ } } } @@ -1076,30 +1117,10 @@ public class LanguageSettingsProvidersSerializer { } - /** - * Deep clone of a list of language settings providers. - * - * @param baseProviders - list of providers to clone. - * @return newly cloned list. - */ - public static List cloneProviders(List baseProviders) { - List newProviders = new ArrayList(); - for (ILanguageSettingsProvider provider : baseProviders) { - if (provider instanceof ILanguageSettingsEditableProvider) { - ILanguageSettingsEditableProvider newProvider = LanguageSettingsManager.getProviderCopy((ILanguageSettingsEditableProvider) provider, true); - if (newProvider != null) { - provider = newProvider; - } - } - newProviders.add(provider); - } - return new ArrayList(newProviders); - } - /** * Adds a listener that will be notified of changes in language settings. * - * @param listener the listener to add + * @param listener - the listener to add */ public static void registerLanguageSettingsChangeListener(ILanguageSettingsChangeListener listener) { fLanguageSettingsChangeListeners.add(listener); @@ -1108,30 +1129,31 @@ public class LanguageSettingsProvidersSerializer { /** * Removes a language settings change listener. * - * @param listener the listener to remove. + * @param listener - the listener to remove. */ public static void unregisterLanguageSettingsChangeListener(ILanguageSettingsChangeListener listener) { fLanguageSettingsChangeListeners.remove(listener); } /** - * Notifies all language settings change listeners of a change. + * Notifies all language settings change listeners of a change in language settings entries. * - * @param event the ILanguageSettingsChangeEvent event to be broadcast. + * @param event - the {@link ILanguageSettingsChangeEvent} event to be broadcast. */ - public static void notifyLanguageSettingsChangeListeners(ILanguageSettingsChangeEvent event) { - // AG FIXME - temporary log to remove before CDT 9.0 release + private static void notifyLanguageSettingsChangeListeners(ILanguageSettingsChangeEvent event) { + // AG FIXME - temporary log to remove before CDT Juno release LanguageSettingsLogger.logWarning("Firing " + event); - Object[] listeners = fLanguageSettingsChangeListeners.getListeners(); - for (Object listener : listeners) { + for (Object listener : fLanguageSettingsChangeListeners.getListeners()) { ((ILanguageSettingsChangeListener) listener).handleEvent(event); } } + /** + * Get list of setting entries from the pool in {@link LanguageSettingsStorage}. + */ private static List getSettingEntriesPooled(ILanguageSettingsProvider provider, ICConfigurationDescription cfgDescription, IResource rc, String languageId) { - try { return LanguageSettingsStorage.getPooledList(provider.getSettingEntries(cfgDescription, rc, languageId)); } catch (Throwable e) { @@ -1148,7 +1170,7 @@ public class LanguageSettingsProvidersSerializer { * Returns the list of setting entries of the given provider * for the given configuration description, resource and language. * This method reaches to the parent folder of the resource recursively - * in case the resource does not define the entries for the given provider. + * if the resource does not define the entries for the given provider. * * @param provider - language settings provider. * @param cfgDescription - configuration description. @@ -1160,19 +1182,19 @@ public class LanguageSettingsProvidersSerializer { */ public static List getSettingEntriesUpResourceTree(ILanguageSettingsProvider provider, ICConfigurationDescription cfgDescription, IResource rc, String languageId) { Assert.isTrue( !(rc instanceof IWorkspaceRoot) ); - if (provider!=null) { + if (provider != null) { List entries = getSettingEntriesPooled(provider, cfgDescription, rc, languageId); - if (entries!=null) { + if (entries != null) { return entries; } - if (rc!=null) { + if (rc != null) { IResource parentFolder = (rc instanceof IProject) ? null : rc.getParent(); - if (parentFolder!=null) { + if (parentFolder != null) { return getSettingEntriesUpResourceTree(provider, cfgDescription, parentFolder, languageId); } - // if out of parent resources - get default entries for the applicable language scope + // if out of parent resources - get default entries entries = getSettingEntriesPooled(provider, null, null, languageId); - if (entries!=null) { + if (entries != null) { return entries; } } @@ -1182,99 +1204,8 @@ public class LanguageSettingsProvidersSerializer { } /** - * Builds for the provider a nice looking resource tree to present hierarchical view to the user. - * Note that it is not advisable to "compact" the tree because of potential loss of information - * which is especially important during partial or incremental builds. - * - * @param provider - language settings provider to build the tree for. - * @param cfgDescription - configuration description. - * @param languageId - language ID. - * @param folder - container where the tree roots. + * Test if the binary flag contains a particular bit. */ - public static void buildResourceTree(LanguageSettingsSerializableProvider provider, - ICConfigurationDescription cfgDescription, String languageId, IContainer folder) { - IResource[] members = null; - try { - members = folder.members(); - } catch (Exception e) { - CCorePlugin.log(e); - } - if (members==null) - return; - - for (IResource rc : members) { - if (rc instanceof IContainer) { - buildResourceTree(provider, cfgDescription, languageId, (IContainer) rc); - } - } - - int rcNumber = members.length; - - Map, Integer> listMap = new HashMap, Integer>(); - - // on the first pass find majority entries - List majorityEntries = null; - List candidate = null; - int candidateCount = 0; - for (IResource rc : members) { - if (!isLanguageInScope(rc, cfgDescription, languageId)) { - rcNumber--; - } else { - List entries = provider.getSettingEntries(null, rc, languageId); - if (entries==null && rc instanceof IContainer) { - rcNumber--; - } else { - Integer count = listMap.get(entries); - if (count==null) { - count = 0; - } - count++; - - if (count>candidateCount) { - candidateCount = count; - candidate = entries; - } - - listMap.put(entries, count); - } - } - - if (candidateCount > rcNumber/2) { - majorityEntries = candidate; - break; - } - } - - if (majorityEntries!=null) { - provider.setSettingEntries(cfgDescription, folder, languageId, majorityEntries); - } - - // second pass - assign the entries to the folders - for (IResource rc : members) { - List entries = provider.getSettingEntries(null, rc, languageId); - if (entries!=null && entries==majorityEntries) { - if (!(rc instanceof IFile)) { // preserve information which files were collected - provider.setSettingEntries(cfgDescription, rc, languageId, null); - } - } - } - } - - private static boolean isLanguageInScope(IResource rc, ICConfigurationDescription cfgDescription, String languageId) { - if (rc instanceof IFile) { - ILanguage lang = null; - try { - lang = LanguageManager.getInstance().getLanguageForFile((IFile) rc, cfgDescription); - } catch (CoreException e) { - CCorePlugin.log("Error loading language settings providers extensions", e); //$NON-NLS-1$ - } - if (lang==null || (languageId!=null && !languageId.equals(lang.getId()))) { - return false; - } - } - return true; - } - private static boolean checkBit(int flags, int bit) { return (flags & bit) == bit; } @@ -1313,9 +1244,9 @@ public class LanguageSettingsProvidersSerializer { for (ILanguageSettingsProvider provider: providers) { List providerEntries = getSettingEntriesUpResourceTree(provider, cfgDescription, rc, languageId); for (ICLanguageSettingEntry entry : providerEntries) { - if (entry!=null) { + if (entry != null) { String entryName = entry.getName(); - boolean isRightKind = (entry.getKind() & kind) != 0; + boolean isRightKind = checkBit(entry.getKind(), kind); // Only first entry is considered // Entry flagged as "UNDEFINED" prevents adding entry with the same name down the line if (isRightKind && !alreadyAdded.contains(entryName)) { @@ -1397,28 +1328,128 @@ public class LanguageSettingsProvidersSerializer { } /** - * Tells if language settings entries of the provider are persisted with the project - * (under .settings/ folder) or in workspace area. Persistence in the project area lets - * the entries migrate with the project. + * Deep clone of a list of language settings providers. * - * @param provider - provider to check the persistence mode. - * @return {@code true} if LSE persisted with the project or {@code false} if in the workspace. + * @param baseProviders - list of providers to clone. + * @return newly cloned list. */ - public static boolean isStoringEntriesInProjectArea(LanguageSettingsSerializableProvider provider) { - String value = provider.getProperty(ATTR_STORE_ENTRIES); - return VALUE_PROJECT.equals(value); + public static List cloneProviders(List baseProviders) { + List newProviders = new ArrayList(); + for (ILanguageSettingsProvider provider : baseProviders) { + if (provider instanceof ILanguageSettingsEditableProvider) { + ILanguageSettingsEditableProvider newProvider = LanguageSettingsManager.getProviderCopy((ILanguageSettingsEditableProvider) provider, true); + if (newProvider != null) { + provider = newProvider; + } + } + newProviders.add(provider); + } + return new ArrayList(newProviders); } /** - * Define where language settings are persisted for the provider. - * - * @param provider - provider to set the persistence mode. - * @param storeEntriesWithProject - {@code true} if with the project, - * {@code false} if in workspace area. + * Check if the language is applicable for the file. */ - public static void setStoringEntriesInProjectArea(LanguageSettingsSerializableProvider provider, boolean storeEntriesWithProject) { - provider.setProperty(ATTR_STORE_ENTRIES, storeEntriesWithProject ? VALUE_PROJECT : VALUE_WORKSPACE); + private static boolean isLanguageInScope(IResource rc, ICConfigurationDescription cfgDescription, String languageId) { + if (rc instanceof IFile) { + ILanguage lang = null; + try { + lang = LanguageManager.getInstance().getLanguageForFile((IFile) rc, cfgDescription); + } catch (CoreException e) { + CCorePlugin.log("Error while determining language for a file", e); //$NON-NLS-1$ + } + if (lang == null || (languageId != null && !languageId.equals(lang.getId()))) { + return false; + } + } + return true; } + /** + * Builds for the provider a nicer-looking resource tree to present hierarchical view to the user. + * + * Note that it is not advisable to "compact" the tree because of potential loss of information + * which is especially important during partial or incremental builds. + * + * Note also that after using this method for a while for BOP parsers it appears that disadvantages + * outweigh benefits. In particular, it doesn't result in saving memory as the language settings + * (and the lists itself) are not duplicated in memory anyway but optimized with using WeakHashSet + * and SafeStringInterner. + * + * This method is a candidate for removal. + * + * @param provider - language settings provider to build the tree for. + * @param cfgDescription - configuration description. + * @param languageId - language ID. + * @param folder - container where the tree roots. + */ + public static void buildResourceTree(LanguageSettingsSerializableProvider provider, + ICConfigurationDescription cfgDescription, String languageId, IContainer folder) { + IResource[] members = null; + try { + members = folder.members(); + } catch (Exception e) { + CCorePlugin.log(e); + } + if (members==null) + return; + + for (IResource rc : members) { + if (rc instanceof IContainer) { + buildResourceTree(provider, cfgDescription, languageId, (IContainer) rc); + } + } + + int rcNumber = members.length; + + Map, Integer> listMap = new HashMap, Integer>(); + + // on the first pass find majority entry list, i.e. list present most often + List majorityEntries = null; + List candidate = null; + int candidateCount = 0; + for (IResource rc : members) { + if (!isLanguageInScope(rc, cfgDescription, languageId)) { + rcNumber--; + } else { + List entries = provider.getSettingEntries(null, rc, languageId); + if (entries==null && rc instanceof IContainer) { + rcNumber--; + } else { + Integer count = listMap.get(entries); + if (count==null) { + count = 0; + } + count++; + + if (count>candidateCount) { + candidateCount = count; + candidate = entries; + } + + listMap.put(entries, count); + } + } + + if (candidateCount > rcNumber/2) { + majorityEntries = candidate; + break; + } + } + + if (majorityEntries!=null) { + provider.setSettingEntries(cfgDescription, folder, languageId, majorityEntries); + } + + // second pass - assign the entries to the folders + for (IResource rc : members) { + List entries = provider.getSettingEntries(null, rc, languageId); + if (entries!=null && entries==majorityEntries) { + if (!(rc instanceof IFile)) { // preserve information which files were collected + provider.setSettingEntries(cfgDescription, rc, languageId, null); + } + } + } + } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java index ece845d9b5e..56016322ae1 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java @@ -52,7 +52,7 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider @Override public ExtendedScannerInfo getScannerInformation(IResource rc) { - // AG FIXME - temporary log to remove before CDT 9.0 release + // AG FIXME - temporary log to remove before CDT Juno release LanguageSettingsLogger.logScannerInfoProvider(rc, this); IProject project = rc.getProject(); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/DescriptionScannerInfoProvider.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/DescriptionScannerInfoProvider.java index 087656f76c6..b662f38c14e 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/DescriptionScannerInfoProvider.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/DescriptionScannerInfoProvider.java @@ -78,7 +78,7 @@ public class DescriptionScannerInfoProvider implements IScannerInfoProvider, ICP @Override public IScannerInfo getScannerInformation(IResource resource) { - // AG FIXME - temporary log to remove before CDT 9.0 release + // AG FIXME - temporary log to remove before CDT Juno release LanguageSettingsLogger.logScannerInfoProvider(resource, this); if(!fInited) diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java index 7a87ec34f65..3ab88b851cc 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java @@ -98,7 +98,7 @@ public class ScannerProvider extends AbstractCExtension implements IScannerInfoP */ @Override public IScannerInfo getScannerInformation(IResource resource) { - // AG FIXME - temporary log to remove before CDT 9.0 release + // AG FIXME - temporary log to remove before CDT Juno release if (resource instanceof IFile) { LanguageSettingsLogger.logInfo("rc="+resource+" (ScannerProvider.getScannerInformation())"); } else {