/******************************************************************************* * Copyright (c) 2012, 2015 Google, Inc 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: * Sergey Prigogin (Google) - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.ui.refactoring.includes; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.ui.PreferenceConstants; import org.eclipse.cdt.internal.corext.codemanipulation.StyledInclude; import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle.IncludeKind; /** * Preferences for managing of includes. */ public class IncludePreferences implements Comparator<StyledInclude> { private static final String DEFAULT_PARTNER_FILE_SUFFIXES = "test,unittest"; //$NON-NLS-1$ private static final String DEFAULT_EXTENSIONS_OF_AUTO_EXPORTED_FILES = "inc"; //$NON-NLS-1$ public static enum UnusedStatementDisposition { REMOVE, COMMENT_OUT, KEEP } public final Map<IncludeKind, IncludeGroupStyle> includeStyles; public final boolean allowReordering; public final boolean heuristicHeaderSubstitution; public final boolean allowPartnerIndirectInclusion; public final boolean allowIndirectInclusion; public final boolean forwardDeclareCompositeTypes; public final boolean forwardDeclareEnums; public final boolean forwardDeclareFunctions; public final boolean forwardDeclareExternalVariables; public final boolean forwardDeclareTemplates; public final boolean forwardDeclareNamespaceElements; public final boolean assumeTemplatesMayBeForwardDeclared; public final UnusedStatementDisposition unusedStatementsDisposition; public final String[] partnerFileSuffixes; public final String[] extensionsOfAutoExportedFiles; public IncludePreferences(ICProject project) { includeStyles = new HashMap<>(); loadStyle(IncludeKind.RELATED, PreferenceConstants.INCLUDE_STYLE_RELATED, project); loadStyle(IncludeKind.PARTNER, PreferenceConstants.INCLUDE_STYLE_PARTNER, project); loadStyle(IncludeKind.IN_SAME_FOLDER, PreferenceConstants.INCLUDE_STYLE_SAME_FOLDER, project); loadStyle(IncludeKind.IN_SUBFOLDER, PreferenceConstants.INCLUDE_STYLE_SUBFOLDER, project); loadStyle(IncludeKind.SYSTEM, PreferenceConstants.INCLUDE_STYLE_SYSTEM, project); loadStyle(IncludeKind.SYSTEM_WITH_EXTENSION, PreferenceConstants.INCLUDE_STYLE_SYSTEM_WITH_EXTENSION, project); loadStyle(IncludeKind.SYSTEM_WITHOUT_EXTENSION, PreferenceConstants.INCLUDE_STYLE_SYSTEM_WITHOUT_EXTENSION, project); loadStyle(IncludeKind.OTHER, PreferenceConstants.INCLUDE_STYLE_OTHER, project); loadStyle(IncludeKind.IN_SAME_PROJECT, PreferenceConstants.INCLUDE_STYLE_SAME_PROJECT, project); loadStyle(IncludeKind.IN_OTHER_PROJECT, PreferenceConstants.INCLUDE_STYLE_OTHER_PROJECT, project); loadStyle(IncludeKind.EXTERNAL, PreferenceConstants.INCLUDE_STYLE_EXTERNAL, project); // Unclassified includes are always kept together. includeStyles.get(IncludeKind.OTHER).setKeepTogether(true); // Normalize order property of the styles to make sure that the numbers are sequential. List<IncludeGroupStyle> styles = new ArrayList<>(includeStyles.values()); Collections.sort(styles); for (int i = 0; i < styles.size(); i++) { styles.get(i).setOrder(i); } // TODO(sprigogin): Load styles for headers matching patterns. forwardDeclareCompositeTypes = PreferenceConstants.getPreference( PreferenceConstants.FORWARD_DECLARE_COMPOSITE_TYPES, project, true); forwardDeclareEnums = PreferenceConstants.getPreference( PreferenceConstants.FORWARD_DECLARE_ENUMS, project, false); forwardDeclareFunctions = PreferenceConstants.getPreference( PreferenceConstants.FORWARD_DECLARE_FUNCTIONS, project, false); forwardDeclareExternalVariables = PreferenceConstants.getPreference( PreferenceConstants.FORWARD_DECLARE_EXTERNAL_VARIABLES, project, false); forwardDeclareTemplates = PreferenceConstants.getPreference( PreferenceConstants.FORWARD_DECLARE_TEMPLATES, project, false); forwardDeclareNamespaceElements = PreferenceConstants.getPreference( PreferenceConstants.FORWARD_DECLARE_NAMESPACE_ELEMENTS, project, true); // Although templates may be forward declared, it is done so rarely that we assume that it // never happens. // TODO(sprigogin): Create a preference for this. assumeTemplatesMayBeForwardDeclared = false; String value = PreferenceConstants.getPreference( PreferenceConstants.INCLUDES_PARTNER_FILE_SUFFIXES, project, DEFAULT_PARTNER_FILE_SUFFIXES); partnerFileSuffixes = value.split(","); //$NON-NLS-1$ value = PreferenceConstants.getPreference( PreferenceConstants.INCLUDES_EXTENSIONS_OF_AUTO_EXPORTED_FILES, project, DEFAULT_EXTENSIONS_OF_AUTO_EXPORTED_FILES); extensionsOfAutoExportedFiles = value.split(","); //$NON-NLS-1$ heuristicHeaderSubstitution = PreferenceConstants.getPreference( PreferenceConstants.INCLUDES_HEURISTIC_HEADER_SUBSTITUTION, project, true); allowReordering = PreferenceConstants.getPreference( PreferenceConstants.INCLUDES_ALLOW_REORDERING, project, true); // TODO(sprigogin): Create a preference for this. allowIndirectInclusion = false; allowPartnerIndirectInclusion = PreferenceConstants.getPreference( PreferenceConstants.INCLUDES_ALLOW_PARTNER_INDIRECT_INCLUSION, project, true); // Unused include handling preferences value = PreferenceConstants.getPreference(PreferenceConstants.INCLUDES_UNUSED_STATEMENTS_DISPOSITION, project, null); UnusedStatementDisposition disposition = null; if (value != null) disposition = UnusedStatementDisposition.valueOf(value); if (disposition == null) disposition = UnusedStatementDisposition.COMMENT_OUT; unusedStatementsDisposition = disposition; } private void loadStyle(IncludeKind includeKind, String preferenceKey, ICProject project) { String value = PreferenceConstants.getPreference(preferenceKey, project, null); IncludeGroupStyle style = null; if (value != null) style = IncludeGroupStyle.fromXmlString(value, includeKind); if (style == null) style = new IncludeGroupStyle(includeKind); includeStyles.put(includeKind, style); } /** * Initializes the given preference store with the default values. * * @param store the preference store to be initialized */ public static void initializeDefaultValues(IPreferenceStore store) { IncludeGroupStyle style = new IncludeGroupStyle(IncludeKind.RELATED); store.setDefault(PreferenceConstants.INCLUDE_STYLE_RELATED, style.toXmlString()); style = new IncludeGroupStyle(IncludeKind.PARTNER); style.setKeepTogether(true); style.setBlankLineBefore(true); style.setOrder(0); store.setDefault(PreferenceConstants.INCLUDE_STYLE_PARTNER, style.toXmlString()); style = new IncludeGroupStyle(IncludeKind.IN_SAME_FOLDER); store.setDefault(PreferenceConstants.INCLUDE_STYLE_SAME_FOLDER, style.toXmlString()); style = new IncludeGroupStyle(IncludeKind.IN_SUBFOLDER); store.setDefault(PreferenceConstants.INCLUDE_STYLE_SUBFOLDER, style.toXmlString()); style = new IncludeGroupStyle(IncludeKind.SYSTEM); style.setKeepTogether(true); style.setBlankLineBefore(true); store.setDefault(PreferenceConstants.INCLUDE_STYLE_SYSTEM, style.toXmlString()); style = new IncludeGroupStyle(IncludeKind.SYSTEM_WITH_EXTENSION); style.setKeepTogether(true); style.setAngleBrackets(true); style.setOrder(1); store.setDefault(PreferenceConstants.INCLUDE_STYLE_SYSTEM_WITH_EXTENSION, style.toXmlString()); style = new IncludeGroupStyle(IncludeKind.SYSTEM_WITHOUT_EXTENSION); style.setKeepTogether(true); style.setAngleBrackets(true); style.setOrder(2); store.setDefault(PreferenceConstants.INCLUDE_STYLE_SYSTEM_WITHOUT_EXTENSION, style.toXmlString()); style = new IncludeGroupStyle(IncludeKind.OTHER); style.setKeepTogether(true); style.setBlankLineBefore(true); style.setOrder(3); store.setDefault(PreferenceConstants.INCLUDE_STYLE_OTHER, style.toXmlString()); style = new IncludeGroupStyle(IncludeKind.IN_SAME_PROJECT); store.setDefault(PreferenceConstants.INCLUDE_STYLE_SAME_PROJECT, style.toXmlString()); style = new IncludeGroupStyle(IncludeKind.IN_OTHER_PROJECT); store.setDefault(PreferenceConstants.INCLUDE_STYLE_OTHER_PROJECT, style.toXmlString()); style = new IncludeGroupStyle(IncludeKind.EXTERNAL); store.setDefault(PreferenceConstants.INCLUDE_STYLE_EXTERNAL, style.toXmlString()); store.setDefault(PreferenceConstants.INCLUDE_STYLE_MATCHING_PATTERN, ""); //$NON-NLS-1$ store.setDefault(PreferenceConstants.INCLUDES_PARTNER_FILE_SUFFIXES, DEFAULT_PARTNER_FILE_SUFFIXES); store.setDefault(PreferenceConstants.INCLUDES_EXTENSIONS_OF_AUTO_EXPORTED_FILES, DEFAULT_EXTENSIONS_OF_AUTO_EXPORTED_FILES); store.setDefault(PreferenceConstants.INCLUDES_HEURISTIC_HEADER_SUBSTITUTION, true); store.setDefault(PreferenceConstants.INCLUDES_ALLOW_REORDERING, true); store.setDefault(PreferenceConstants.INCLUDES_ALLOW_PARTNER_INDIRECT_INCLUSION, true); store.setDefault(PreferenceConstants.FORWARD_DECLARE_COMPOSITE_TYPES, true); store.setDefault(PreferenceConstants.FORWARD_DECLARE_ENUMS, false); store.setDefault(PreferenceConstants.FORWARD_DECLARE_FUNCTIONS, false); store.setDefault(PreferenceConstants.FORWARD_DECLARE_EXTERNAL_VARIABLES, false); store.setDefault(PreferenceConstants.FORWARD_DECLARE_TEMPLATES, false); store.setDefault(PreferenceConstants.FORWARD_DECLARE_NAMESPACE_ELEMENTS, true); store.setDefault(PreferenceConstants.INCLUDES_UNUSED_STATEMENTS_DISPOSITION, UnusedStatementDisposition.REMOVE.toString()); store.setDefault(PreferenceConstants.INCLUDES_HEADER_SUBSTITUTION, HeaderSubstitutionMap.serializeMaps(GCCHeaderSubstitutionMaps.getDefaultMaps())); store.setDefault(PreferenceConstants.INCLUDES_SYMBOL_EXPORTING_HEADERS, SymbolExportMap.serializeMaps(Collections.singletonList(GCCHeaderSubstitutionMaps.getSymbolExportMap()))); } @Override public int compare(StyledInclude include1, StyledInclude include2) { int c = include1.getStyle().getGroupingStyle(includeStyles).getOrder() - include2.getStyle().getGroupingStyle(includeStyles).getOrder(); if (c != 0) return c; return include1.getIncludeInfo().compareTo(include2.getIncludeInfo()); } }