1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 45203. User configurable header substitution rules.

This commit is contained in:
Sergey Prigogin 2013-06-14 15:50:47 -07:00
parent af00e7cd42
commit a79028d2fc
26 changed files with 1979 additions and 600 deletions

View file

@ -23,15 +23,15 @@ public class IncludeMapTest extends TestCase {
assertEquals(expected.toString(), actual.toString());
}
public void testWeakCyclicMap() {
IncludeMap map = new IncludeMap(false, false, new String[] {
public void testOptionalCyclicMap() {
IncludeMap map = new IncludeMap(false, new String[] {
"a", "b",
"b", "c",
"c", "d",
"d", "b",
});
map.transitivelyClose();
IncludeMap expected = new IncludeMap(false, false, new String[] {
IncludeMap expected = new IncludeMap(false, new String[] {
"a", "b",
"a", "d",
"a", "c",
@ -45,15 +45,15 @@ public class IncludeMapTest extends TestCase {
assertEqualMaps(expected, map);
}
public void testStrongCyclicMap() {
IncludeMap map = new IncludeMap(true, false, new String[] {
public void testUnconditionalCyclicMap() {
IncludeMap map = new IncludeMap(true, new String[] {
"a", "b",
"b", "c",
"c", "d",
"d", "b",
});
map.transitivelyClose();
IncludeMap expected = new IncludeMap(true, false, new String[] {
IncludeMap expected = new IncludeMap(true, new String[] {
"a", "b",
"c", "b",
"d", "b",
@ -61,8 +61,8 @@ public class IncludeMapTest extends TestCase {
assertEqualMaps(expected, map);
}
public void testWeakMap() {
IncludeMap map = new IncludeMap(false, false, new String[] {
public void testOptionalMap() {
IncludeMap map = new IncludeMap(false, new String[] {
"a", "b",
"a", "c",
"c", "d",
@ -70,7 +70,7 @@ public class IncludeMapTest extends TestCase {
"d", "f",
});
map.transitivelyClose();
IncludeMap expected = new IncludeMap(false, false, new String[] {
IncludeMap expected = new IncludeMap(false, new String[] {
"a", "b",
"a", "f",
"a", "d",
@ -84,8 +84,8 @@ public class IncludeMapTest extends TestCase {
assertEqualMaps(expected, map);
}
public void testStrongMap() {
IncludeMap map = new IncludeMap(true, false, new String[] {
public void testUpconditionalMap() {
IncludeMap map = new IncludeMap(true, new String[] {
"a", "b",
"a", "c",
"c", "d",
@ -93,7 +93,7 @@ public class IncludeMapTest extends TestCase {
"d", "f",
});
map.transitivelyClose();
IncludeMap expected = new IncludeMap(true, false, new String[] {
IncludeMap expected = new IncludeMap(true, new String[] {
"a", "b",
"c", "f",
"d", "f",

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.cdt.ui; singleton:=true
Bundle-Version: 5.6.0.qualifier
Bundle-Version: 5.7.0.qualifier
Bundle-Activator: org.eclipse.cdt.ui.CUIPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin

View file

@ -198,6 +198,7 @@ codeTemplatePreferencePage.name=Code Templates
codeFormatterPreferencePage.name=Formatter
includeStylePreferencePage.name=Include Style
includePragmasPreferencePage.name=Include Pragmas
headerSubstitutionPreferencePage.name=Header Substitution
organizeIncludesPreferencePage.name=Organize Includes
nameStylePreferencePage.name=Name Style
CodeAssistPreferencePage.name=Content Assist
@ -215,7 +216,7 @@ AsmEditor.name = Assembly Editor
# Task Action
DeleteTaskAction.label=Delete C/C++ Markers
DeleteIProblemMarkerAction.label=Delete IProblem Markers
DeleteIProblemMarkerAction.label=Delete Problem Markers
OpenExternalProblemAction.label=Open external location
# Build configuration actions
@ -583,6 +584,7 @@ preferenceKeywords.codetemplates=comment code constructor method file type conte
preferenceKeywords.namestyle=name style file getter setter field variable
preferenceKeywords.includestyle=include includes style partner system header file system
preferenceKeywords.includepragmas=include includes pragma pragmas IWYU export begin_exports end_exports
preferenceKeywords.headersubstitution=header file substitution map IWYU
preferenceKeywords.organizeincludes=include includes organize
preferenceKeywords.todo=case sensitive task tag todo xxx fix fixme project comments
preferenceKeywords.indexer=index skip references type macro search build configuration cache memory performance

View file

@ -1256,6 +1256,14 @@
<keywordReference id="org.eclipse.cdt.ui.includepragmas"/>
<keywordReference id="org.eclipse.cdt.ui.common"/>
</page>
<page
name="%headerSubstitutionPreferencePage.name"
category="org.eclipse.cdt.ui.preferences.OrganizeIncludesPreferencePage"
class="org.eclipse.cdt.internal.ui.preferences.HeaderSubstitutionPreferencePage"
id="org.eclipse.cdt.ui.preferences.HeaderSubstitutionPreferencePage">
<keywordReference id="org.eclipse.cdt.ui.headersubstitution"/>
<keywordReference id="org.eclipse.cdt.ui.common"/>
</page>
<page
name="%markOccurrencesPreferencePage.name"
category="org.eclipse.cdt.ui.preferences.CEditorPreferencePage"
@ -1315,6 +1323,9 @@
<keyword
label="%preferenceKeywords.includepragmas"
id="org.eclipse.cdt.ui.includepragmas"/>
<keyword
label="%preferenceKeywords.headersubstitution"
id="org.eclipse.cdt.ui.headersubstitution"/>
<keyword
label="%preferenceKeywords.organizeincludes"
id="org.eclipse.cdt.ui.organizeincludes"/>

View file

@ -89,6 +89,9 @@ public interface ICHelpContextIds {
public static final String CODE_STYLE_PREFERENCE_PAGE = PREFIX + "code_style_preference_context"; //$NON-NLS-1$
public static final String CODE_TEMPLATES_PREFERENCE_PAGE = PREFIX + "code_templates_preference_context"; //$NON-NLS-1$
public static final String ORGANIZE_INCLUDES_PREFERENCE_PAGE = PREFIX + "organize_includes_preference_context"; //$NON-NLS-1$
public static final String HEADER_SUBSTITUTION_PREFERENCE_PAGE = PREFIX + "header_substitution_preference_context"; //$NON-NLS-1$
public static final String HEADER_SUBSTITUTION_MAP_EDIT_DIALOG = PREFIX + "header_substitution_map_edit_dialog_context"; //$NON-NLS-1$
public static final String HEADER_SUBSTITUTION_EDIT_DIALOG = PREFIX + "header_substitution_edit_dialog_context"; //$NON-NLS-1$
public static final String INCLUDE_PRAGMAS_PREFERENCE_PAGE = PREFIX + "include_pragmas_preference_context"; //$NON-NLS-1$
public static final String INCLUDE_STYLE_PREFERENCE_PAGE = PREFIX + "include_style_preference_context"; //$NON-NLS-1$
public static final String NAME_STYLE_PREFERENCE_PAGE = PREFIX + "name_style_preference_context"; //$NON-NLS-1$

View file

@ -0,0 +1,55 @@
/*******************************************************************************
* Copyright (c) 2013 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.dialogs;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.StatusDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.cdt.ui.CUIPlugin;
/**
* A resizable {@link StatusDialog} that preserves its dimensions between invocations.
*/
public abstract class ResizableStatusDialog extends StatusDialog {
public ResizableStatusDialog(Shell parent) {
super(parent);
}
@Override
protected Point getInitialSize() {
Point defaultSize= getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
Point restoredSize= super.getInitialSize();
if (restoredSize.x < defaultSize.x)
restoredSize.x= defaultSize.x;
if (restoredSize.y < defaultSize.y)
restoredSize.y= defaultSize.y;
return restoredSize;
}
@Override
protected IDialogSettings getDialogBoundsSettings() {
String sectionName= getClass().getName() + "_dialogBounds"; //$NON-NLS-1$
IDialogSettings settings= CUIPlugin.getDefault().getDialogSettings();
IDialogSettings section= settings.getSection(sectionName);
if (section == null)
section= settings.addNewSection(sectionName);
return section;
}
@Override
protected boolean isResizable() {
return true;
}
}

View file

@ -1,31 +0,0 @@
/*******************************************************************************
* Copyright (c) 2005, 2009 IBM Corporation 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:
* IBM Corporation - initial API and implementation
* QNX Software System
*******************************************************************************/
package org.eclipse.cdt.internal.ui.dialogs;
import org.eclipse.swt.widgets.Shell;
/**
* @deprecated. This class is deprecated since CDT 6.1. Use {@link org.eclipse.jface.dialogs.StatusDialog} instead.
*
* An abstract base class for dialogs with a status bar and ok/cancel buttons.
* The status message must be passed over as StatusInfo object and can be
* an error, warning or ok. The OK button is enabled or disabled depending
* on the status.
*/
@Deprecated
public abstract class StatusDialog extends org.eclipse.jface.dialogs.StatusDialog {
public StatusDialog(Shell parent) {
super(parent);
setHelpAvailable(false);
}
}

View file

@ -0,0 +1,248 @@
/*******************************************************************************
* Copyright (c) 2013 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.preferences;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.internal.ui.dialogs.IStatusChangeListener;
import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.cdt.internal.ui.refactoring.includes.HeaderSubstitutionMap;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.IListAdapter;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.ListDialogField;
/**
* The preference block for configuring header file substitution rules.
*/
public class HeaderSubstitutionBlock extends OptionsConfigurationBlock {
static final Key KEY_HEADER_SUBSTITUTION = getCDTUIKey(PreferenceConstants.INCLUDES_HEADER_SUBSTITUTION);
private static Key[] ALL_KEYS = {
KEY_HEADER_SUBSTITUTION
};
private class HeaderMapLabelProvider extends LabelProvider implements ITableLabelProvider, IFontProvider {
public HeaderMapLabelProvider() {
}
@Override
public Image getImage(Object element) {
return null;
}
@Override
public String getText(Object element) {
return getColumnText(element, 0);
}
@Override
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
@Override
public String getColumnText(Object element, int columnIndex) {
HeaderSubstitutionMap map = (HeaderSubstitutionMap) element;
if (columnIndex == 0) {
return map.getName();
}
return map.isCppOnly() ?
PreferencesMessages.HeaderSubstitutionBlock_cpp_only :
PreferencesMessages.HeaderSubstitutionBlock_c_and_cpp;
}
@Override
public Font getFont(Object element) {
return null;
}
}
private static final int IDX_ADD = 0;
private static final int IDX_EDIT = 1;
private static final int IDX_REMOVE = 2;
private static final int IDX_UP = 3;
private static final int IDX_DOWN = 4;
private final ListDialogField<HeaderSubstitutionMap> fHeaderMapsList;
private IStatus fStatus;
public HeaderSubstitutionBlock(IStatusChangeListener context, IProject project,
IWorkbenchPreferenceContainer container) {
super(context, project, ALL_KEYS, container);
ListAdapter adapter = new ListAdapter();
String[] buttons = new String[] {
PreferencesMessages.HeaderSubstitutionBlock_add_button,
PreferencesMessages.HeaderSubstitutionBlock_edit_button,
PreferencesMessages.HeaderSubstitutionBlock_remove_button,
PreferencesMessages.HeaderSubstitutionBlock_up_button,
PreferencesMessages.HeaderSubstitutionBlock_down_button,
};
fHeaderMapsList = new ListDialogField<HeaderSubstitutionMap>(adapter, buttons, new HeaderMapLabelProvider());
fHeaderMapsList.setLabelText(PreferencesMessages.HeaderSubstitutionBlock_header_substitution_maps);
fHeaderMapsList.setDialogFieldListener(adapter);
fHeaderMapsList.setRemoveButtonIndex(IDX_REMOVE);
fHeaderMapsList.setUpButtonIndex(IDX_UP);
fHeaderMapsList.setDownButtonIndex(IDX_DOWN);
String[] columnsHeaders = new String[] {
PreferencesMessages.HeaderSubstitutionBlock_name_column_title,
PreferencesMessages.HeaderSubstitutionBlock_languages_column_title,
};
ColumnLayoutData[] columnData = new ColumnLayoutData[] {
new ColumnWeightData(5),
new ColumnWeightData(2),
};
fHeaderMapsList.setTableColumns(new ListDialogField.ColumnsDescription(columnData, columnsHeaders, true));
loadHeaderMaps();
if (fHeaderMapsList.getSize() > 0) {
fHeaderMapsList.selectFirstElement();
} else {
fHeaderMapsList.enableButton(IDX_EDIT, false);
}
fStatus = new StatusInfo();
}
private void loadHeaderMaps() {
String str = getValue(KEY_HEADER_SUBSTITUTION);
if (str == null)
return;
List<HeaderSubstitutionMap> maps = HeaderSubstitutionMap.deserializeMaps(str);
fHeaderMapsList.setElements(maps);
}
@Override
protected boolean processChanges(IWorkbenchPreferenceContainer container) {
boolean result = super.processChanges(container);
List<HeaderSubstitutionMap> maps = fHeaderMapsList.getElements();
String str = HeaderSubstitutionMap.serializeMaps(maps);
setValue(KEY_HEADER_SUBSTITUTION, str);
return result;
}
@Override
protected void settingsUpdated() {
if (fHeaderMapsList != null)
loadHeaderMaps();
super.settingsUpdated();
}
public class ListAdapter implements IListAdapter<HeaderSubstitutionMap>, IDialogFieldListener {
private boolean canEdit(List<HeaderSubstitutionMap> selectedElements) {
return selectedElements.size() == 1;
}
@Override
public void customButtonPressed(ListDialogField<HeaderSubstitutionMap> field, int index) {
onButtonPressed(field, index);
}
@Override
public void selectionChanged(ListDialogField<HeaderSubstitutionMap> field) {
List<HeaderSubstitutionMap> selectedElements = field.getSelectedElements();
field.enableButton(IDX_EDIT, canEdit(selectedElements));
}
@Override
public void doubleClicked(ListDialogField<HeaderSubstitutionMap> field) {
if (canEdit(field.getSelectedElements())) {
onButtonPressed(field, IDX_EDIT);
}
}
@Override
public void dialogFieldChanged(DialogField field) {
}
}
@Override
protected Control createContents(Composite parent) {
setShell(parent.getShell());
GridLayout layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.numColumns = 2;
PixelConverter conv = new PixelConverter(parent);
Composite composite = new Composite(parent, SWT.NULL);
composite.setLayout(layout);
composite.setFont(parent.getFont());
LayoutUtil.setHorizontalSpan(fHeaderMapsList.getLabelControl(composite), 2);
GridData data = new GridData(GridData.FILL_BOTH);
data.widthHint = conv.convertWidthInCharsToPixels(50);
Control listControl = fHeaderMapsList.getListControl(composite);
listControl.setLayoutData(data);
Control buttonsControl = fHeaderMapsList.getButtonBox(composite);
buttonsControl.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING));
validateSettings(null, null, null);
return composite;
}
@Override
protected void validateSettings(Key changedKey, String oldValue, String newValue) {
if (!areSettingsEnabled()) {
return;
}
fStatus = new StatusInfo();
fContext.statusChanged(fStatus);
}
private void onButtonPressed(ListDialogField<HeaderSubstitutionMap> field, int index) {
HeaderSubstitutionMap edited = null;
if (index != IDX_ADD) {
edited = field.getSelectedElements().get(0);
}
if (index == IDX_ADD || index == IDX_EDIT) {
HeaderSubstitutionMapEditDialog dialog =
new HeaderSubstitutionMapEditDialog(getShell(), edited, field.getElements());
if (dialog.open() == Window.OK) {
if (edited != null) {
field.replaceElement(edited, dialog.getResult());
} else {
field.addElement(dialog.getResult());
}
}
}
}
}

View file

@ -0,0 +1,139 @@
/*******************************************************************************
* Copyright (c) 2013 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.preferences;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
import org.eclipse.cdt.internal.ui.dialogs.ResizableStatusDialog;
import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.StringDialogField;
public class HeaderSubstitutionEditDialog extends ResizableStatusDialog {
private final StringDialogField fSourceField;
private final StringDialogField fTargetField;
private final SelectionButtonDialogField fRequiredSubstitutionCheckBox;
public HeaderSubstitutionEditDialog(Shell shell, HeaderSubstitutionRule rule) {
super(shell);
if (rule == null || rule.getSource().isEmpty()) {
setTitle(PreferencesMessages.HeaderSubstitutionEditDialog_new_title);
} else {
setTitle(PreferencesMessages.HeaderSubstitutionEditDialog_edit_title);
}
IDialogFieldListener listener = new IDialogFieldListener() {
@Override
public void dialogFieldChanged(DialogField field) {
validate();
}
};
fSourceField = new StringDialogField();
fSourceField.setLabelText(PreferencesMessages.HeaderSubstitutionEditDialog_source);
fSourceField.setDialogFieldListener(listener);
fTargetField = new StringDialogField();
fTargetField.setLabelText(PreferencesMessages.HeaderSubstitutionEditDialog_target);
fTargetField.setDialogFieldListener(listener);
fRequiredSubstitutionCheckBox = new SelectionButtonDialogField(SWT.CHECK);
fRequiredSubstitutionCheckBox.setLabelText(PreferencesMessages.HeaderSubstitutionEditDialog_required_substitution);
if (rule != null) {
fSourceField.setText(rule.getSource());
fTargetField.setText(rule.getTarget());
fRequiredSubstitutionCheckBox.setSelection(rule.isUnconditionalSubstitution());
}
validate();
}
public HeaderSubstitutionRule getResult() {
return new HeaderSubstitutionRule(fSourceField.getText().trim(), fTargetField.getText().trim(),
fRequiredSubstitutionCheckBox.isSelected());
}
@Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, ICHelpContextIds.HEADER_SUBSTITUTION_EDIT_DIALOG);
}
@Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
PixelConverter conv = new PixelConverter(composite);
Composite inner = new Composite(composite, SWT.NONE);
GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
int len = PreferencesMessages.HeaderSubstitutionEditDialog_enter_target.length() + 5;
gridData.widthHint = conv.convertWidthInCharsToPixels(len);
inner.setLayoutData(gridData);
GridLayout layout = new GridLayout(2, false);
layout.marginHeight = 0;
layout.marginWidth = 0;
inner.setLayout(layout);
fSourceField.doFillIntoGrid(inner, 2);
fTargetField.doFillIntoGrid(inner, 2);
fRequiredSubstitutionCheckBox.doFillIntoGrid(composite, 2);
applyDialogFont(composite);
validate();
return composite;
}
private void validate() {
IStatus status = StatusInfo.OK_STATUS;
String source = fSourceField.getText().trim();
String target = fTargetField.getText().trim();
if (source.isEmpty()) {
status = new StatusInfo(IStatus.INFO, PreferencesMessages.HeaderSubstitutionEditDialog_enter_source);
} else if (!isValidHeader(source)) {
status = new StatusInfo(IStatus.WARNING, PreferencesMessages.HeaderSubstitutionEditDialog_invalid_source);
} else if (target.isEmpty()) {
status = new StatusInfo(IStatus.INFO, PreferencesMessages.HeaderSubstitutionEditDialog_enter_target);
} else if (!isValidHeader(target)) {
status = new StatusInfo(IStatus.WARNING, PreferencesMessages.HeaderSubstitutionEditDialog_invalid_target);
} else if (target.equals(source)) {
status = new StatusInfo(IStatus.WARNING, PreferencesMessages.HeaderSubstitutionEditDialog_error_replacement_by_itself);
}
updateStatus(status);
}
@Override
protected void updateButtonsEnableState(IStatus status) {
// OK button is disabled unless the status is OK.
super.updateButtonsEnableState(status.isOK() ? status : new StatusInfo(IStatus.ERROR, null));
}
private boolean isValidHeader(String header) {
if (header.isEmpty())
return false;
if (header.startsWith("<") != header.endsWith(">")) //$NON-NLS-1$//$NON-NLS-2$
return false;
if (header.startsWith("<") && header.length() < 3) //$NON-NLS-1$
return false;
return true;
}
}

View file

@ -0,0 +1,584 @@
/*******************************************************************************
* Copyright (c) 2013 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.preferences;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.XMLMemento;
import com.ibm.icu.text.Collator;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
import org.eclipse.cdt.internal.ui.dialogs.ResizableStatusDialog;
import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.cdt.internal.ui.refactoring.includes.HeaderSubstitutionMap;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeInfo;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeMap;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.ComboDialogField;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.IListAdapter;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.ListDialogField;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.Separator;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.StringDialogField;
/**
* Dialog for editing a header file substitution map.
*/
public class HeaderSubstitutionMapEditDialog extends ResizableStatusDialog {
private static final String UTF_8 = "UTF-8"; //$NON-NLS-1$
private static final String TAG_HEADER_SUBSTITUTION_MAP = "header_substitution_map"; //$NON-NLS-1$
private static final Collator COLLATOR = Collator.getInstance();
private static final Comparator<HeaderSubstitutionRule> SOURCE_COMPARATOR =
new Comparator<HeaderSubstitutionRule>() {
@Override
public int compare(HeaderSubstitutionRule r1, HeaderSubstitutionRule r2) {
return COLLATOR.compare(r1.getSource(), r2.getSource());
}
};
private class HeaderSubstitutionListField extends ListDialogField<HeaderSubstitutionRule> {
HeaderSubstitutionListField(IListAdapter<HeaderSubstitutionRule> adapter, String[] buttons) {
super(adapter, buttons, new HeaderSubstitutionLabelProvider());
}
@Override
protected boolean getManagedButtonState(ISelection sel, int index) {
if (index == IDX_REMOVE) {
return !sel.isEmpty();
} else if (index == IDX_UP) {
return !sel.isEmpty() && canMoveUp();
} else if (index == IDX_DOWN) {
return !sel.isEmpty() && canMoveDown();
}
return true;
}
@Override
protected boolean managedButtonPressed(int index) {
if (index == IDX_REMOVE) {
remove();
} else if (index == IDX_UP) {
up();
} else if (index == IDX_DOWN) {
down();
} else {
return false;
}
return true;
}
@Override
protected boolean canMoveUp() {
if (!isOkToUse(fTableControl))
return false;
int[] indc= fTable.getTable().getSelectionIndices();
for (int i= 0; i < indc.length; i++) {
int index = indc[i];
if (index == 0 ||
SOURCE_COMPARATOR.compare(fElements.get(index), fElements.get(index - 1)) != 0) {
return false;
}
}
return true;
}
@Override
protected boolean canMoveDown() {
if (!isOkToUse(fTableControl))
return false;
int k= fElements.size() - 1;
int[] indc= fTable.getTable().getSelectionIndices();
for (int i= 0; i < indc.length; i++) {
int index = indc[i];
if (index == k ||
SOURCE_COMPARATOR.compare(fElements.get(index), fElements.get(index + 1)) != 0) {
return false;
}
}
return true;
}
}
private class HeaderSubstitutionLabelProvider extends LabelProvider implements ITableLabelProvider, IFontProvider {
public HeaderSubstitutionLabelProvider() {
}
@Override
public Image getImage(Object element) {
return null;
}
@Override
public String getText(Object element) {
return getColumnText(element, 0);
}
@Override
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
@Override
public String getColumnText(Object element, int columnIndex) {
HeaderSubstitutionRule substitution = (HeaderSubstitutionRule) element;
return columnIndex == 0 ? substitution.getSource() : substitution.getTarget();
}
@Override
public Font getFont(Object element) {
return null;
}
}
public class ListAdapter implements IListAdapter<HeaderSubstitutionRule>, IDialogFieldListener {
private boolean canEdit(List<HeaderSubstitutionRule> selectedElements) {
return selectedElements.size() == 1;
}
@Override
public void customButtonPressed(ListDialogField<HeaderSubstitutionRule> field, int index) {
onButtonPressed(field, index);
}
@Override
public void selectionChanged(ListDialogField<HeaderSubstitutionRule> field) {
List<HeaderSubstitutionRule> selectedElements = field.getSelectedElements();
field.enableButton(IDX_EDIT, canEdit(selectedElements));
}
@Override
public void doubleClicked(ListDialogField<HeaderSubstitutionRule> field) {
if (canEdit(field.getSelectedElements())) {
onButtonPressed(field, IDX_EDIT);
}
}
@Override
public void dialogFieldChanged(DialogField field) {
updateButtonState();
}
}
private static abstract class ButtonSelectionListener implements SelectionListener {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
}
private static final int IDX_ADD = 0;
private static final int IDX_EDIT = 1;
private static final int IDX_REMOVE = 2;
private static final int IDX_UP = 3;
private static final int IDX_DOWN = 4;
private final StringDialogField fNameField;
private final ComboDialogField fAppliesToField;
private final HeaderSubstitutionListField fUnconditionalSubstitutionsField;
private final HeaderSubstitutionListField fOptionalSubstitutionsField;
private final Set<String> fExistingNames;
private final boolean fNewMap;
public HeaderSubstitutionMapEditDialog(Shell parent, HeaderSubstitutionMap map,
List<HeaderSubstitutionMap> existingEntries) {
super(parent);
fExistingNames = new HashSet<String>();
for (HeaderSubstitutionMap exising : existingEntries) {
if (!exising.equals(map)) {
fExistingNames.add(exising.getName());
}
}
if (map == null) {
fNewMap = true;
setTitle(PreferencesMessages.HeaderSubstitutionMapEditDialog_new_title);
} else {
fNewMap = false;
setTitle(PreferencesMessages.HeaderSubstitutionMapEditDialog_edit_title);
}
ListAdapter adapter = new ListAdapter();
fNameField = new StringDialogField();
fNameField.setLabelText(PreferencesMessages.HeaderSubstitutionMapEditDialog_name);
fNameField.setDialogFieldListener(adapter);
String[] items = new String[] {
PreferencesMessages.HeaderSubstitutionMapEditDialog_c_and_cpp,
PreferencesMessages.HeaderSubstitutionMapEditDialog_cpp_only,
};
fAppliesToField = new ComboDialogField(SWT.READ_ONLY);
fAppliesToField.setLabelText(PreferencesMessages.HeaderSubstitutionMapEditDialog_applies_to);
fAppliesToField.setItems(items);
String[] buttons = new String[] {
PreferencesMessages.HeaderSubstitutionMapEditDialog_add_button,
PreferencesMessages.HeaderSubstitutionMapEditDialog_edit_button,
PreferencesMessages.HeaderSubstitutionMapEditDialog_remove_button,
};
fUnconditionalSubstitutionsField = new HeaderSubstitutionListField(adapter, buttons);
fUnconditionalSubstitutionsField.setLabelText(PreferencesMessages.HeaderSubstitutionMapEditDialog_required_substitution);
fUnconditionalSubstitutionsField.setDialogFieldListener(adapter);
final String[] columnsHeaders = new String[] {
PreferencesMessages.HeaderSubstitutionMapEditDialog_header,
PreferencesMessages.HeaderSubstitutionMapEditDialog_replacement,
};
fUnconditionalSubstitutionsField.setTableColumns(new ListDialogField.ColumnsDescription(columnsHeaders, true));
buttons = new String[] {
PreferencesMessages.HeaderSubstitutionMapEditDialog_add_button2,
PreferencesMessages.HeaderSubstitutionMapEditDialog_edit_button2,
PreferencesMessages.HeaderSubstitutionMapEditDialog_remove_button2,
PreferencesMessages.HeaderSubstitutionMapEditDialog_up_button,
PreferencesMessages.HeaderSubstitutionMapEditDialog_down_button,
};
fOptionalSubstitutionsField = new HeaderSubstitutionListField(adapter, buttons);
fOptionalSubstitutionsField.setLabelText(PreferencesMessages.HeaderSubstitutionMapEditDialog_optional_substitution);
fOptionalSubstitutionsField.setDialogFieldListener(adapter);
fOptionalSubstitutionsField.enableButton(IDX_EDIT, false);
fOptionalSubstitutionsField.setTableColumns(new ListDialogField.ColumnsDescription(columnsHeaders, true));
updateFromMap(map);
adapter.selectionChanged(fUnconditionalSubstitutionsField);
adapter.selectionChanged(fOptionalSubstitutionsField);
}
private void updateFromMap(HeaderSubstitutionMap map) {
fNameField.setText(map != null ? map.getName() : createUniqueName());
fAppliesToField.selectItem(map != null && map.isCppOnly() ? 1 : 0);
if (map != null) {
List<HeaderSubstitutionRule> substitutionRules = getSubstitutionRules(map.getUnconditionalSubstitutionMap());
fUnconditionalSubstitutionsField.setElements(substitutionRules);
substitutionRules = getSubstitutionRules(map.getOptionalSubstitutionMap());
fOptionalSubstitutionsField.setElements(substitutionRules);
}
}
private String createUniqueName() {
for (int i = 1; ; i++) {
String name = NLS.bind(PreferencesMessages.HeaderSubstitutionMapEditDialog_default_map_name, i);
if (!fExistingNames.contains(name))
return name;
}
}
private List<HeaderSubstitutionRule> getSubstitutionRules(IncludeMap map) {
ArrayList<HeaderSubstitutionRule> result = new ArrayList<HeaderSubstitutionRule>();
for (Entry<IncludeInfo, List<IncludeInfo>> entry : map.getMap().entrySet()) {
String source = stripQuotes(entry.getKey().toString());
for (IncludeInfo target : entry.getValue()) {
boolean unconditional = map.isUnconditionalSubstitution();
HeaderSubstitutionRule rule =
new HeaderSubstitutionRule(source, stripQuotes(target.toString()), unconditional);
result.add(rule);
}
}
Collections.sort(result, SOURCE_COMPARATOR);
return result;
}
private String stripQuotes(String str) {
if (str.length() > 2 && str.charAt(0) == '"' && str.charAt(str.length() - 1) == '"')
return str.substring(1, str.length() - 1);
return str;
}
public HeaderSubstitutionMap getResult() {
HeaderSubstitutionMap map = createEmptyMap();
for (HeaderSubstitutionRule substitution : fUnconditionalSubstitutionsField.getElements()) {
map.addMapping(substitution.getSource(), substitution.getTarget(), true);
}
for (HeaderSubstitutionRule substitution : fOptionalSubstitutionsField.getElements()) {
map.addMapping(substitution.getSource(), substitution.getTarget(), false);
}
return map;
}
private HeaderSubstitutionMap createEmptyMap() {
HeaderSubstitutionMap map = new HeaderSubstitutionMap(fAppliesToField.getSelectionIndex() != 0);
map.setName(fNameField.getText().trim());
return map;
}
@Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
PixelConverter conv = new PixelConverter(composite);
Composite inner = new Composite(composite, SWT.NONE);
inner.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
GridLayout layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.numColumns = 4;
inner.setLayout(layout);
fNameField.doFillIntoGrid(inner, 3);
if (fNewMap)
fNameField.getTextControl(null).selectAll();
Button button = new Button(inner, SWT.PUSH);
button.setText(PreferencesMessages.HeaderSubstitutionMapEditDialog_import_button);
button.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false));
button.addSelectionListener(new ButtonSelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
importFromFile();
}
});
fAppliesToField.doFillIntoGrid(inner, 3);
button = new Button(inner, SWT.PUSH);
button.setText(PreferencesMessages.HeaderSubstitutionMapEditDialog_export_button);
button.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false));
button.addSelectionListener(new ButtonSelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
exportToFile();
}
});
Separator separator = new Separator(SWT.NONE);
separator.doFillIntoGrid(inner, 4, conv.convertHeightInCharsToPixels(1));
int minHeight = convertHeightInCharsToPixels(12);
fUnconditionalSubstitutionsField.doFillIntoGrid(inner, 4);
LayoutUtil.setHeightHint(fUnconditionalSubstitutionsField.getListControl(null), minHeight);
fOptionalSubstitutionsField.doFillIntoGrid(inner, 4);
LayoutUtil.setHeightHint(fOptionalSubstitutionsField.getListControl(null), minHeight);
applyDialogFont(composite);
return composite;
}
private void importFromFile() {
FileDialog dialog= new FileDialog(getShell(), SWT.OPEN);
dialog.setText(PreferencesMessages.HeaderSubstitutionMapEditDialog_import_title);
// TODO(sprigogin): Add import from .imp files
// (see http://code.google.com/p/include-what-you-use/wiki/IWYUMappings)
dialog.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$
String path= dialog.open();
if (path == null)
return;
try {
IFileStore fileStore = EFS.getLocalFileSystem().getStore(Path.fromOSString(path));
InputStream stream = fileStore.openInputStream(EFS.NONE, null);
InputStreamReader reader = new InputStreamReader(new BufferedInputStream(stream), UTF_8);
try {
HeaderSubstitutionMap map = HeaderSubstitutionMap.fromSerializedMemento(reader);
updateFromMap(map);
} finally {
try {
reader.close();
} catch (IOException e) {
}
}
} catch (IOException e) {
String title= PreferencesMessages.HeaderSubstitutionMapEditDialog_import_title;
String message= e.getLocalizedMessage();
if (message != null) {
message= NLS.bind(PreferencesMessages.HeaderSubstitutionMapEditDialog_error_parse_message, message);
} else {
message= NLS.bind(PreferencesMessages.HeaderSubstitutionMapEditDialog_error_read_message, path);
}
MessageDialog.openError(getShell(), title, message);
} catch (CoreException e) {
MessageDialog.openError(getShell(),
PreferencesMessages.HeaderSubstitutionMapEditDialog_import_title,
e.getLocalizedMessage());
}
updateButtonState();
}
private void exportToFile() {
HeaderSubstitutionMap map = getResult();
FileDialog dialog= new FileDialog(getShell(), SWT.SAVE);
dialog.setText(PreferencesMessages.HeaderSubstitutionMapEditDialog_export_title);
dialog.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$
dialog.setFileName(map.getName() + ".xml"); //$NON-NLS-1$
dialog.setOverwrite(true);
String path= dialog.open();
if (path == null)
return;
try {
IFileStore fileStore = EFS.getLocalFileSystem().getStore(Path.fromOSString(path));
OutputStream stream = fileStore.openOutputStream(EFS.OVERWRITE, null);
XMLMemento memento = XMLMemento.createWriteRoot(TAG_HEADER_SUBSTITUTION_MAP);
map.saveToMemento(memento);
Writer writer = new OutputStreamWriter(new BufferedOutputStream(stream), UTF_8);
try {
memento.save(writer);
} finally {
try {
writer.close();
} catch (IOException e) {
}
}
} catch (IOException e) {
MessageDialog.openError(getShell(),
PreferencesMessages.HeaderSubstitutionMapEditDialog_export_title,
PreferencesMessages.HeaderSubstitutionMapEditDialog_error_write_message);
} catch (CoreException e) {
MessageDialog.openError(getShell(),
PreferencesMessages.HeaderSubstitutionMapEditDialog_export_title,
e.getLocalizedMessage());
}
}
@Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, ICHelpContextIds.HEADER_SUBSTITUTION_MAP_EDIT_DIALOG);
}
private void onButtonPressed(ListDialogField<HeaderSubstitutionRule> field, int buttonId) {
HeaderSubstitutionRule oldRule = null;
if (buttonId == IDX_ADD) {
oldRule = new HeaderSubstitutionRule("", "", field == fUnconditionalSubstitutionsField); //$NON-NLS-1$ //$NON-NLS-2$
} else {
oldRule = field.getSelectedElements().get(0);
}
switch (buttonId) {
case IDX_ADD:
case IDX_EDIT:
HeaderSubstitutionEditDialog dialog = new HeaderSubstitutionEditDialog(getShell(), oldRule);
if (dialog.open() != Window.OK)
break;
HeaderSubstitutionRule newRule = dialog.getResult();
ListDialogField<HeaderSubstitutionRule> newField = newRule.isUnconditionalSubstitution() ?
fUnconditionalSubstitutionsField : fOptionalSubstitutionsField;
if (buttonId == IDX_ADD) {
newField.addElement(newRule);
} else {
if (newField == field) {
field.replaceElement(oldRule, newRule);
} else {
field.removeElement(oldRule);
newField.addElement(newRule);
}
}
// Restore order.
List<HeaderSubstitutionRule> elements = newField.getElements();
Collections.sort(elements, SOURCE_COMPARATOR);
newField.setElements(elements);
// There can be no more than one unconditional substitution for any header file.
// The unconditional and optional substitutions are mutually exclusive.
for (HeaderSubstitutionRule rule : fUnconditionalSubstitutionsField.getElements()) {
if (rule != newRule && rule.getSource().equals(newRule.getSource())) {
fUnconditionalSubstitutionsField.removeElement(rule);
}
}
if (newRule.isUnconditionalSubstitution()) {
List<HeaderSubstitutionRule> rulesToDelete = null;
for (HeaderSubstitutionRule rule : fOptionalSubstitutionsField.getElements()) {
if (rule.getSource().equals(newRule.getSource())) {
if (rulesToDelete == null)
rulesToDelete = new ArrayList<HeaderSubstitutionRule>();
rulesToDelete.add(rule);
}
}
if (rulesToDelete != null)
fOptionalSubstitutionsField.removeElements(rulesToDelete);
}
break;
}
updateButtonState();
}
private void updateButtonState() {
IStatus status = StatusInfo.OK_STATUS;
String name = fNameField.getText().trim();
if (name.isEmpty()) {
status = new StatusInfo(IStatus.WARNING, PreferencesMessages.HeaderSubstitutionMapEditDialog_enter_name);
} else if (fExistingNames.contains(name)) {
status = new StatusInfo(IStatus.WARNING, PreferencesMessages.HeaderSubstitutionMapEditDialog_duplicate_name);
} else if (fUnconditionalSubstitutionsField.getElements().isEmpty() &&
fOptionalSubstitutionsField.getElements().isEmpty()) {
status = new StatusInfo(IStatus.WARNING, PreferencesMessages.HeaderSubstitutionMapEditDialog_map_is_empty);
}
updateStatus(status);
}
@Override
protected void updateButtonsEnableState(IStatus status) {
// OK button is disabled unless the status is OK.
super.updateButtonsEnableState(status.isOK() ? status : new StatusInfo(IStatus.ERROR, null));
}
}

View file

@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2013 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.preferences;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
/*
* The preference page for configuring header file substitution rules.
*/
public class HeaderSubstitutionPreferencePage extends ConfigurationBlockPropertyAndPreferencePage {
public static final String PREF_ID= "org.eclipse.cdt.ui.preferences.HeaderSubstitutionPreferencePage"; //$NON-NLS-1$
public static final String PROP_ID= "org.eclipse.cdt.ui.propertyPages.HeaderSubstitutionPreferencePage"; //$NON-NLS-1$
public HeaderSubstitutionPreferencePage() {
setPreferenceStore(CUIPlugin.getDefault().getPreferenceStore());
// Only used when the page is shown programmatically.
setTitle(PreferencesMessages.HeaderSubstitutionPreferencePage_title);
}
@Override
protected OptionsConfigurationBlock createConfigurationBlock(IWorkbenchPreferenceContainer container) {
return new HeaderSubstitutionBlock(getNewStatusChangedListener(), getProject(), container);
}
@Override
protected String getHelpId() {
return ICHelpContextIds.INCLUDE_STYLE_PREFERENCE_PAGE;
}
@Override
protected String getPreferencePageId() {
return PREF_ID;
}
@Override
protected String getPropertyPageId() {
return null;
// TODO(sprigogin): Project specific settings
// return PROP_ID;
}
}

View file

@ -0,0 +1,48 @@
/*******************************************************************************
* Copyright (c) 2013 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.preferences;
/**
* Substitution rule for a single header file.
*/
class HeaderSubstitutionRule {
private final String source;
private final String target;
private final boolean unconditional;
public HeaderSubstitutionRule(String source, String target, boolean unconditional) {
this.source = source;
this.target = target;
this.unconditional = unconditional;
}
public String getSource() {
return source;
}
public String getTarget() {
return target;
}
public boolean isUnconditionalSubstitution() {
return unconditional;
}
/** For debugging only */
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append(source).append(' ');
buf.append(unconditional ? '=' : '-').append('>');
buf.append(' ').append(target);
return buf.toString();
}
}

View file

@ -213,7 +213,8 @@ public class IncludeOrderBlock extends OptionsConfigurationBlock {
return true;
}
private void up() {
@Override
protected void up() {
boolean[] selected = getSelectionMask(false);
extendSelectionForMovingUp(selected, fElements);
if (selected != null) {
@ -222,7 +223,8 @@ public class IncludeOrderBlock extends OptionsConfigurationBlock {
}
}
private void down() {
@Override
protected void down() {
boolean[] selected = getSelectionMask(true);
List<IncludeGroupStyle> reversed = reverse(fElements);
extendSelectionForMovingUp(selected, reversed);
@ -290,7 +292,8 @@ public class IncludeOrderBlock extends OptionsConfigurationBlock {
return -1;
}
private boolean canMoveUp() {
@Override
protected boolean canMoveUp() {
boolean[] selected = getSelectionMask(false);
if (selected == null || selected[0])
return false;
@ -298,7 +301,8 @@ public class IncludeOrderBlock extends OptionsConfigurationBlock {
return canMoveUp(fElements, selected);
}
private boolean canMoveDown() {
@Override
protected boolean canMoveDown() {
boolean[] selected = getSelectionMask(true);
if (selected == null || selected[0])
return false;

View file

@ -29,6 +29,7 @@ import org.eclipse.cdt.internal.ui.wizards.dialogfields.LayoutUtil;
*/
public class OrganizeIncludesBlock extends OptionsConfigurationBlock {
private static final Key KEY_HEURISTIC_HEADER_SUBSTITUTION = getCDTUIKey(PreferenceConstants.INCLUDES_HEURISTIC_HEADER_SUBSTITUTION);
private static final Key KEY_PARTNER_INDIRECT_INCLUSION = getCDTUIKey(PreferenceConstants.INCLUDES_ALLOW_PARTNER_INDIRECT_INCLUSION);
private static final Key KEY_INCLUDES_REORDERING = getCDTUIKey(PreferenceConstants.INCLUDES_ALLOW_REORDERING);
private static final Key KEY_UNUSED_STATEMENTS_DISPOSITION = getCDTUIKey(PreferenceConstants.INCLUDES_UNUSED_STATEMENTS_DISPOSITION);
private static final Key KEY_FORWARD_DECLARE_COMPOSITE_TYPES = getCDTUIKey(PreferenceConstants.FORWARD_DECLARE_COMPOSITE_TYPES);
@ -50,6 +51,7 @@ public class OrganizeIncludesBlock extends OptionsConfigurationBlock {
private static Key[] ALL_KEYS = {
KEY_HEURISTIC_HEADER_SUBSTITUTION,
KEY_PARTNER_INDIRECT_INCLUSION,
KEY_INCLUDES_REORDERING,
KEY_UNUSED_STATEMENTS_DISPOSITION,
KEY_FORWARD_DECLARE_COMPOSITE_TYPES,
@ -81,6 +83,9 @@ public class OrganizeIncludesBlock extends OptionsConfigurationBlock {
control = addCheckBox(composite, PreferencesMessages.OrganizeIncludesBlock_heuristic_header_substitution,
KEY_HEURISTIC_HEADER_SUBSTITUTION, TRUE_FALSE, 0);
LayoutUtil.setHorizontalSpan(control, 2);
control = addCheckBox(composite, PreferencesMessages.OrganizeIncludesBlock_partner_indirect_inclusion,
KEY_PARTNER_INDIRECT_INCLUSION, TRUE_FALSE, 0);
LayoutUtil.setHorizontalSpan(control, 2);
control = addCheckBox(composite, PreferencesMessages.OrganizeIncludesBlock_forward_declare_composite_types,
KEY_FORWARD_DECLARE_COMPOSITE_TYPES, TRUE_FALSE, 0);
LayoutUtil.setHorizontalSpan(control, 2);

View file

@ -364,6 +364,60 @@ public final class PreferencesMessages extends NLS {
public static String CodeTemplateBlock_export_error_hidden;
public static String CodeTemplateBlock_export_error_canNotWrite;
public static String HeaderSubstitutionPreferencePage_title;
public static String HeaderSubstitutionBlock_header_substitution_maps;
public static String HeaderSubstitutionBlock_c_and_cpp;
public static String HeaderSubstitutionBlock_cpp_only;
public static String HeaderSubstitutionBlock_add_button;
public static String HeaderSubstitutionBlock_edit_button;
public static String HeaderSubstitutionBlock_remove_button;
public static String HeaderSubstitutionBlock_up_button;
public static String HeaderSubstitutionBlock_down_button;
public static String HeaderSubstitutionBlock_name_column_title;
public static String HeaderSubstitutionBlock_languages_column_title;
public static String HeaderSubstitutionEditDialog_new_title;
public static String HeaderSubstitutionEditDialog_edit_title;
public static String HeaderSubstitutionEditDialog_source;
public static String HeaderSubstitutionEditDialog_target;
public static String HeaderSubstitutionEditDialog_required_substitution;
public static String HeaderSubstitutionEditDialog_enter_source;
public static String HeaderSubstitutionEditDialog_enter_target;
public static String HeaderSubstitutionEditDialog_error_replacement_by_itself;
public static String HeaderSubstitutionEditDialog_invalid_source;
public static String HeaderSubstitutionEditDialog_invalid_target;
public static String HeaderSubstitutionMapEditDialog_new_title;
public static String HeaderSubstitutionMapEditDialog_edit_title;
public static String HeaderSubstitutionMapEditDialog_name;
public static String HeaderSubstitutionMapEditDialog_applies_to;
public static String HeaderSubstitutionMapEditDialog_required_substitution;
public static String HeaderSubstitutionMapEditDialog_optional_substitution;
public static String HeaderSubstitutionMapEditDialog_header;
public static String HeaderSubstitutionMapEditDialog_replacement;
public static String HeaderSubstitutionMapEditDialog_import_button;
public static String HeaderSubstitutionMapEditDialog_export_button;
public static String HeaderSubstitutionMapEditDialog_add_button;
public static String HeaderSubstitutionMapEditDialog_edit_button;
public static String HeaderSubstitutionMapEditDialog_remove_button;
public static String HeaderSubstitutionMapEditDialog_add_button2;
public static String HeaderSubstitutionMapEditDialog_edit_button2;
public static String HeaderSubstitutionMapEditDialog_remove_button2;
public static String HeaderSubstitutionMapEditDialog_up_button;
public static String HeaderSubstitutionMapEditDialog_down_button;
public static String HeaderSubstitutionMapEditDialog_c_and_cpp;
public static String HeaderSubstitutionMapEditDialog_cpp_only;
public static String HeaderSubstitutionMapEditDialog_import_title;
public static String HeaderSubstitutionMapEditDialog_export_title;
public static String HeaderSubstitutionMapEditDialog_error_read_message;
public static String HeaderSubstitutionMapEditDialog_error_parse_message;
public static String HeaderSubstitutionMapEditDialog_error_write_message;
public static String HeaderSubstitutionMapEditDialog_default_map_name;
public static String HeaderSubstitutionMapEditDialog_enter_name;
public static String HeaderSubstitutionMapEditDialog_duplicate_name;
public static String HeaderSubstitutionMapEditDialog_map_is_empty;
public static String IncludeStylePreferencePage_title;
public static String IncludeStyleBlock_categories_tab;
public static String IncludeStyleBlock_order_tab;
@ -452,6 +506,7 @@ public final class PreferencesMessages extends NLS {
public static String OrganizeIncludesBlock_forward_declare_templates;
public static String OrganizeIncludesBlock_forward_declare_namespace_elements;
public static String OrganizeIncludesBlock_heuristic_header_substitution;
public static String OrganizeIncludesBlock_partner_indirect_inclusion;
public static String OrganizeIncludesBlock_unused_statements;
public static String OrganizeIncludesBlock_comment_out;
public static String OrganizeIncludesBlock_keep;

View file

@ -276,7 +276,7 @@ SpellingPreferencePage_ignore_digits_label=Ignore &words with digits
SpellingPreferencePage_ignore_mixed_label=Ignore &mixed case words
SpellingPreferencePage_ignore_sentence_label=Ignore &sentence capitalization
SpellingPreferencePage_ignore_upper_label=Ignore u&pper case words
SpellingPreferencePage_ignore_url_label=Ignore &internet addresses
SpellingPreferencePage_ignore_url_label=Ignore &Internet addresses
SpellingPreferencePage_ignore_single_letters_label=I&gnore single letters
SpellingPreferencePage_ignore_string_literals_label=Ignore string &literals
SpellingPreferencePage_ignore_non_letters_label=Ignore &non-letters at word boundaries
@ -419,6 +419,60 @@ CodeTemplateBlock_export_error_title= Export Templates
CodeTemplateBlock_export_error_hidden= Export failed.\n{0} is a hidden file.
CodeTemplateBlock_export_error_canNotWrite= Export failed.\n{0} cannot be modified.
HeaderSubstitutionPreferencePage_title= Header Substitution
HeaderSubstitutionBlock_header_substitution_maps= Header File &Substitution Maps:
HeaderSubstitutionBlock_c_and_cpp= C and C++
HeaderSubstitutionBlock_cpp_only= C++ only
HeaderSubstitutionBlock_add_button= &New...
HeaderSubstitutionBlock_edit_button= &Edit...
HeaderSubstitutionBlock_remove_button= &Remove
HeaderSubstitutionBlock_up_button= &Up
HeaderSubstitutionBlock_down_button= &Down
HeaderSubstitutionBlock_name_column_title= Name
HeaderSubstitutionBlock_languages_column_title= Applies To
HeaderSubstitutionEditDialog_new_title= New Header Substitution
HeaderSubstitutionEditDialog_edit_title= Edit Header Substitution
HeaderSubstitutionEditDialog_source= &Header File:
HeaderSubstitutionEditDialog_target= Replace &By:
HeaderSubstitutionEditDialog_required_substitution= &Unconditional substitution
HeaderSubstitutionEditDialog_enter_source= Enter header file, use angle brackets for a system header.
HeaderSubstitutionEditDialog_enter_target= Enter replacement header file, use angle brackets for a system header.
HeaderSubstitutionEditDialog_error_replacement_by_itself= Replacement by itself does not make sense.
HeaderSubstitutionEditDialog_invalid_source= Invalid header file.
HeaderSubstitutionEditDialog_invalid_target= Invalid replacement header file.
HeaderSubstitutionMapEditDialog_new_title= New Header Substitution Map
HeaderSubstitutionMapEditDialog_edit_title= Edit Header Substitution Map
HeaderSubstitutionMapEditDialog_name= Map N&ame:
HeaderSubstitutionMapEditDialog_applies_to= Applie&s To:
HeaderSubstitutionMapEditDialog_required_substitution= Unconditional Su&bstitution:
HeaderSubstitutionMapEditDialog_optional_substitution= &Optional Substitution:
HeaderSubstitutionMapEditDialog_header= Header
HeaderSubstitutionMapEditDialog_replacement= Replacement
HeaderSubstitutionMapEditDialog_import_button= I&mport...
HeaderSubstitutionMapEditDialog_export_button= E&xport...
HeaderSubstitutionMapEditDialog_add_button= &New...
HeaderSubstitutionMapEditDialog_edit_button= &Edit...
HeaderSubstitutionMapEditDialog_remove_button= &Remove
HeaderSubstitutionMapEditDialog_add_button2= Ne&w...
HeaderSubstitutionMapEditDialog_edit_button2= Edi&t...
HeaderSubstitutionMapEditDialog_remove_button2= Remo&ve
HeaderSubstitutionMapEditDialog_up_button= &Up
HeaderSubstitutionMapEditDialog_down_button= &Down
HeaderSubstitutionMapEditDialog_c_and_cpp= C and C++
HeaderSubstitutionMapEditDialog_cpp_only= C++ only
HeaderSubstitutionMapEditDialog_import_title= Header Substitution Map Import
HeaderSubstitutionMapEditDialog_export_title= Header Substitution Map Export
HeaderSubstitutionMapEditDialog_error_read_message= Failed to read the header substitution map\nfrom {0}
HeaderSubstitutionMapEditDialog_error_parse_message= Failed to parse the header substitution map:\n{0}
HeaderSubstitutionMapEditDialog_error_write_message= Failed to write the header substitution map.
HeaderSubstitutionMapEditDialog_default_map_name= Header substitution map {0}
HeaderSubstitutionMapEditDialog_enter_name= Enter a map name.
HeaderSubstitutionMapEditDialog_duplicate_name= A map with this name already exists.
HeaderSubstitutionMapEditDialog_map_is_empty= No substitution rules are defined.
IncludeStylePreferencePage_title= Include Style
IncludeStyleBlock_categories_tab= Grouping
IncludeStyleBlock_order_tab= Ordering
@ -509,6 +563,7 @@ OrganizeIncludesBlock_forward_declare_functions= Forward declare &functions
OrganizeIncludesBlock_forward_declare_templates= Forward declare &templates
OrganizeIncludesBlock_forward_declare_namespace_elements= Forward declare &namespace elements
OrganizeIncludesBlock_heuristic_header_substitution= Allow &heuristic header file substitution
OrganizeIncludesBlock_partner_indirect_inclusion= Skip include if included by &partner header
OrganizeIncludesBlock_unused_statements= &Unused Includes and Forward Declarations:
OrganizeIncludesBlock_comment_out= Comment out
OrganizeIncludesBlock_keep= Keep

View file

@ -0,0 +1,368 @@
/*******************************************************************************
* Copyright (c) 2013 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.Arrays;
import java.util.List;
public class GCCHeaderSubstitutionMaps {
@SuppressWarnings("nls")
private static final String[] cIncludeMap = new String[] {
"<asm/errno-base.h>", "<errno.h>",
"<asm/errno.h>", "<errno.h>",
"<asm/ioctls.h>", "<sys/ioctl.h>",
"<asm/posix_types_32.h>", "<asm/posix_types.h>",
"<asm/posix_types_64.h>", "<asm/posix_types.h>",
"<asm/ptrace-abi.h>", "<asm/ptrace.h>",
"<asm/socket.h>", "<sys/socket.h>",
"<asm/unistd.h>", "<syscall.h>",
"<asm/unistd_32.h>", "<syscall.h>",
"<asm/unistd_64.h>", "<syscall.h>",
"<bits/a.out.h>", "<a.out.h>",
"<bits/byteswap.h>", "<byteswap.h>",
"<bits/cmathcalls.h>", "<complex.h>",
"<bits/confname.h>", "<unistd.h>",
"<bits/dirent.h>", "<dirent.h>",
"<bits/dlfcn.h>", "<dlfcn.h>",
"<bits/elfclass.h>", "<link.h>",
"<bits/endian.h>", "<endian.h>",
"<bits/environments.h>", "<unistd.h>",
"<bits/errno.h>", "<errno.h>",
"<bits/error.h>", "<error.h>",
"<bits/fcntl.h>", "<fcntl.h>",
"<bits/fcntl2.h>", "<fcntl.h>",
"<bits/fenv.h>", "<fenv.h>",
"<bits/fenvinline.h>", "<fenv.h>",
"<bits/huge_val.h>", "<math.h>",
"<bits/huge_valf.h>", "<math.h>",
"<bits/huge_vall.h>", "<math.h>",
"<bits/in.h>", "<netinet/in.h>",
"<bits/inf.h>", "<math.h>",
"<bits/ioctl-types.h>", "<sys/ioctl.h>",
"<bits/ioctls.h>", "<sys/ioctl.h>",
"<bits/ipc.h>", "<sys/ipc.h>",
"<bits/ipctypes.h>", "<sys/ipc.h>",
"<bits/libio-ldbl.h>", "<libio.h>",
"<bits/link.h>", "<link.h>",
"<bits/locale.h>", "<locale.h>",
"<bits/mathcalls.h>", "<math.h>",
"<bits/mathdef.h>", "<math.h>",
"<bits/mathinline.h>", "<math.h>",
"<bits/mman.h>", "<sys/mman.h>",
"<bits/monetary-ldbl.h>", "<monetary.h>",
"<bits/mqueue.h>", "<mqueue.h>",
"<bits/mqueue2.h>", "<mqueue.h>",
"<bits/msq.h>", "<sys/msg.h>",
"<bits/nan.h>", "<math.h>",
"<bits/netdb.h>", "<netdb.h>",
"<bits/poll.h>", "<poll.h>",
"<bits/posix1_lim.h>", "<limits.h>",
"<bits/posix2_lim.h>", "<limits.h>",
"<bits/posix_opt.h>", "<unistd.h>",
"<bits/predefs.h>", "<features.h>",
"<bits/printf-ldbl.h>", "<printf.h>",
"<bits/pthreadtypes.h>", "<pthread.h>",
"<bits/resource.h>", "<sys/resource.h>",
"<bits/sched.h>", "<sched.h>",
"<bits/select.h>", "<sys/select.h>",
"<bits/sem.h>", "<sys/sem.h>",
"<bits/semaphore.h>", "<semaphore.h>",
"<bits/setjmp.h>", "<setjmp.h>",
"<bits/shm.h>", "<sys/shm.h>",
"<bits/sigaction.h>", "<signal.h>",
"<bits/sigcontext.h>", "<signal.h>",
"<bits/siginfo.h>", "<signal.h>",
"<bits/signum.h>", "<signal.h>",
"<bits/sigset.h>", "<signal.h>",
"<bits/sigstack.h>", "<signal.h>",
"<bits/sigthread.h>", "<signal.h>",
"<bits/sockaddr.h>", "<sys/un.h>",
"<bits/socket.h>", "<sys/socket.h>",
"<bits/stab.def>", "<stab.h>",
"<bits/stat.h>", "<sys/stat.h>",
"<bits/statfs.h>", "<sys/statfs.h>",
"<bits/statvfs.h>", "<sys/statvfs.h>",
"<bits/stdio-ldbl.h>", "<stdio.h>",
"<bits/stdio-lock.h>", "<libio.h>",
"<bits/stdio.h>", "<stdio.h>",
"<bits/stdio2.h>", "<stdio.h>",
"<bits/stdio_lim.h>", "<stdio.h>",
"<bits/stdlib-ldbl.h>", "<stdlib.h>",
"<bits/stdlib.h>", "<stdlib.h>",
"<bits/string.h>", "<string.h>",
"<bits/string2.h>", "<string.h>",
"<bits/string3.h>", "<string.h>",
"<bits/stropts.h>", "<stropts.h>",
"<bits/sys_errlist.h>", "<stdio.h>",
"<bits/syscall.h>", "<syscall.h>",
"<bits/syslog-ldbl.h>", "<syslog.h>",
"<bits/syslog-path.h>", "<syslog.h>",
"<bits/syslog.h>", "<syslog.h>",
"<bits/termios.h>", "<termios.h>",
"<bits/time.h>", "<sys/time.h>",
"<bits/types.h>", "<sys/types.h>",
"<bits/uio.h>", "<sys/uio.h>",
"<bits/unistd.h>", "<unistd.h>",
"<bits/ustat.h>", "<ustat.h>",
"<bits/utmp.h>", "<utmp.h>",
"<bits/utmpx.h>", "<utmpx.h>",
"<bits/utsname.h>", "<sys/utsname.h>",
"<bits/waitflags.h>", "<sys/wait.h>",
"<bits/waitstatus.h>", "<sys/wait.h>",
"<bits/wchar-ldbl.h>", "<wchar.h>",
"<bits/wchar.h>", "<wchar.h>",
"<bits/wchar2.h>", "<wchar.h>",
"<bits/xopen_lim.h>", "<limits.h>",
"<bits/xtitypes.h>", "<stropts.h>",
"<linux/errno.h>", "<errno.h>",
"<linux/limits.h>", "<limits.h>",
"<linux/socket.h>", "<sys/socket.h>",
"<sys/poll.h>", "<poll.h>",
"<sys/syscall.h>", "<syscall.h>",
"<sys/syslog.h>", "<syslog.h>",
"<sys/ucontext.h>", "<ucontext.h>",
"<sys/ustat.h>", "<ustat.h>",
"<wait.h>", "<sys/wait.h>",
};
private static final String[] cIncludeMapWeak = new String[] {
};
@SuppressWarnings("nls")
private static final String[] cppIncludeMap = new String[] {
"<auto_ptr.h>", "<memory>",
"<backward/auto_ptr.h>", "<memory>",
"<backward/binders.h>", "<functional>",
"<backward/hash_fun.h>", "<hash_map>",
"<backward/hash_fun.h>", "<hash_set>",
"<backward/hashtable.h>", "<hash_map>",
"<backward/hashtable.h>", "<hash_set>",
"<backward/strstream>", "<strstream>",
"<binders.h>", "<functional>",
"<bits/algorithmfwd.h>", "<algorithm>",
"<bits/allocator.h>", "<memory>",
"<bits/atomic_word.h>", "<ext/atomicity.h>",
"<bits/basic_file.h>", "<fstream>",
"<bits/basic_ios.h>", "<ios>",
"<bits/basic_string.h>", "<string>",
"<bits/basic_string.tcc>", "<string>",
"<bits/boost_concept_check.h>", "<bits/concept_check.h>",
"<bits/boost_sp_shared_count.h>", "<memory>",
"<bits/c++allocator.h>", "<memory>",
"<bits/c++config.h>", "<cstddef>",
"<bits/c++io.h>", "<ext/stdio_sync_filebuf.h>",
"<bits/char_traits.h>", "<string>",
"<bits/cmath.tcc>", "<cmath>",
"<bits/codecvt.h>", "<fstream>",
"<bits/codecvt.h>", "<locale>",
"<bits/ctype_base.h>", "<locale>",
"<bits/ctype_base.h>", "<ios>",
"<bits/ctype_inline.h>", "<locale>",
"<bits/ctype_inline.h>", "<ios>",
"<bits/cxxabi_tweaks.h>", "<cxxabi.h>",
"<bits/deque.tcc>", "<deque>",
"<bits/exception_defines.h>", "<exception>",
"<bits/fstream.tcc>", "<fstream>",
"<bits/functexcept.h>", "<algorithm>",
"<bits/functional_hash.h>", "<unordered_map>",
"<bits/gslice.h>", "<valarray>",
"<bits/gslice_array.h>", "<valarray>",
"<bits/hashtable.h>", "<unordered_map>",
"<bits/hashtable.h>", "<unordered_set>",
"<bits/indirect_array.h>", "<valarray>",
"<bits/ios_base.h>", "<iostream>",
"<bits/ios_base.h>", "<ios>",
"<bits/ios_base.h>", "<iomanip>",
"<bits/istream.tcc>", "<istream>",
"<bits/list.tcc>", "<list>",
"<bits/locale_classes.h>", "<locale>",
"<bits/locale_classes.h>", "<ios>",
"<bits/locale_classes.tcc>", "<locale>",
"<bits/locale_classes.tcc>", "<ios>",
"<bits/locale_facets.h>", "<locale>",
"<bits/locale_facets.h>", "<ios>",
"<bits/locale_facets.tcc>", "<locale>",
"<bits/locale_facets.tcc>", "<ios>",
"<bits/locale_facets_nonio.h>", "<locale>",
"<bits/locale_facets_nonio.tcc>", "<locale>",
"<bits/localefwd.h>", "<locale>",
"<bits/mask_array.h>", "<valarray>",
"<bits/messages_members.h>", "<locale>",
"<bits/move.h>", "<algorithm>",
"<bits/ostream.tcc>", "<ostream>",
"<bits/ostream_insert.h>", "<ostream>",
"<bits/postypes.h>", "<iostream>",
"<bits/postypes.h>", "<string>",
"<bits/slice_array.h>", "<valarray>",
"<bits/sstream.tcc>", "<sstream>",
"<bits/stl_algo.h>", "<algorithm>",
"<bits/stl_algobase.h>", "<algorithm>",
"<bits/stl_bvector.h>", "<vector>",
"<bits/stl_construct.h>", "<memory>",
"<bits/stl_deque.h>", "<deque>",
"<bits/stl_function.h>", "<functional>",
"<bits/stl_heap.h>", "<queue>",
"<bits/stl_iterator.h>", "<iterator>",
"<bits/stl_iterator_base_funcs.h>", "<iterator>",
"<bits/stl_iterator_base_types.h>", "<iterator>",
"<bits/stl_list.h>", "<list>",
"<bits/stl_map.h>", "<map>",
"<bits/stl_move.h>", "<algorithm>",
"<bits/stl_multimap.h>", "<map>",
"<bits/stl_multiset.h>", "<set>",
"<bits/stl_numeric.h>", "<numeric>",
"<bits/stl_pair.h>", "<utility>",
"<bits/stl_pair.h>", "<tr1/utility>",
"<bits/stl_queue.h>", "<queue>",
"<bits/stl_raw_storage_iter.h>", "<memory>",
"<bits/stl_relops.h>", "<utility>",
"<bits/stl_set.h>", "<set>",
"<bits/stl_stack.h>", "<stack>",
"<bits/stl_tempbuf.h>", "<memory>",
"<bits/stl_tree.h>", "<map>",
"<bits/stl_tree.h>", "<set>",
"<bits/stl_uninitialized.h>", "<memory>",
"<bits/stl_vector.h>", "<vector>",
"<bits/stream_iterator.h>", "<iterator>",
"<bits/streambuf.tcc>", "<streambuf>",
"<bits/streambuf_iterator.h>", "<iterator>",
"<bits/streambuf_iterator.h>", "<ios>",
"<bits/stringfwd.h>", "<string>",
"<bits/valarray_after.h>", "<valarray>",
"<bits/valarray_array.h>", "<valarray>",
"<bits/valarray_array.tcc>", "<valarray>",
"<bits/valarray_before.h>", "<valarray>",
"<bits/vector.tcc>", "<vector>",
"<debug/safe_iterator.tcc>", "<debug/safe_iterator.h>",
"<exception_defines.h>", "<exception>",
"<ext/algorithm>", "<algorithm>",
"<ext/functional>", "<functional>",
"<ext/hash_map>", "<hash_map>",
"<ext/hash_set>", "<hash_set>",
"<ext/numeric>", "<numeric>",
"<ext/slist>", "<slist>",
"<ext/sso_string_base.h>", "<string>",
"<ext/vstring.h>", "<string>",
"<ext/vstring.tcc>", "<string>",
"<ext/vstring_fwd.h>", "<string>",
"<hash_fun.h>", "<hash_map>",
"<hash_fun.h>", "<hash_set>",
"<hashtable.h>", "<hash_map>",
"<hashtable.h>", "<hash_set>",
"<tr1/bessel_function.tcc>", "<tr1/cmath>",
"<tr1/beta_function.tcc>", "<tr1/cmath>",
"<tr1/ell_integral.tcc>", "<tr1/cmath>",
"<tr1/exp_integral.tcc>", "<tr1/cmath>",
"<tr1/gamma.tcc>", "<tr1/cmath>",
"<tr1/hypergeometric.tcc>", "<tr1/cmath>",
"<tr1/legendre_function.tcc>", "<tr1/cmath>",
"<tr1/modified_bessel_func.tcc>", "<tr1/cmath>",
"<tr1/poly_hermite.tcc>", "<tr1/cmath>",
"<tr1/poly_laguerre.tcc>", "<tr1/cmath>",
"<tr1/riemann_zeta.tcc>", "<tr1/cmath>",
"<tr1_impl/array>", "<array>",
"<tr1_impl/array>", "<tr1/array>",
"<tr1_impl/boost_shared_ptr.h>", "<memory>",
"<tr1_impl/boost_shared_ptr.h>", "<tr1/memory>",
"<tr1_impl/boost_sp_counted_base.h>", "<memory>",
"<tr1_impl/boost_sp_counted_base.h>", "<tr1/memory>",
"<tr1_impl/cctype>", "<cctype>",
"<tr1_impl/cctype>", "<tr1/cctype>",
"<tr1_impl/cfenv>", "<cfenv>",
"<tr1_impl/cfenv>", "<tr1/cfenv>",
"<tr1_impl/cinttypes>", "<cinttypes>",
"<tr1_impl/cinttypes>", "<tr1/cinttypes>",
"<tr1_impl/cmath>", "<cmath>",
"<tr1_impl/cmath>", "<tr1/cmath>",
"<tr1_impl/complex>", "<complex>",
"<tr1_impl/complex>", "<tr1/complex>",
"<tr1_impl/cstdint>", "<cstdint>",
"<tr1_impl/cstdint>", "<tr1/cstdint>",
"<tr1_impl/cstdio>", "<cstdio>",
"<tr1_impl/cstdio>", "<tr1/cstdio>",
"<tr1_impl/cstdlib>", "<cstdlib>",
"<tr1_impl/cstdlib>", "<tr1/cstdlib>",
"<tr1_impl/cwchar>", "<cwchar>",
"<tr1_impl/cwchar>", "<tr1/cwchar>",
"<tr1_impl/cwctype>", "<cwctype>",
"<tr1_impl/cwctype>", "<tr1/cwctype>",
"<tr1_impl/functional>", "<functional>",
"<tr1_impl/functional>", "<tr1/functional>",
"<tr1_impl/functional_hash.h>", "<tr1/functional_hash.h>",
"<tr1_impl/hashtable>", "<tr1/hashtable.h>",
"<tr1_impl/random.tcc>", "<random>",
"<tr1_impl/random.tcc>", "<tr1/random>",
"<tr1_impl/random>", "<random>",
"<tr1_impl/random>", "<tr1/random>",
"<tr1_impl/regex>", "<regex>",
"<tr1_impl/regex>", "<tr1/regex>",
"<tr1_impl/type_traits>", "<tr1/type_traits>",
"<tr1_impl/type_traits>", "<type_traits>",
"<tr1_impl/unordered_map>", "<tr1/unordered_map>",
"<tr1_impl/unordered_map>", "<unordered_map>",
"<tr1_impl/unordered_set>", "<tr1/unordered_set>",
"<tr1_impl/unordered_set>", "<unordered_set>",
"<tr1_impl/utility>", "<tr1/utility>",
"<tr1_impl/utility>", "<utility>",
};
@SuppressWarnings("nls")
private static final String[] cppIncludeMapWeak = new String[] {
"<assert.h>", "<cassert>",
"<complex.h>", "<ccomplex>",
"<ctype.h>", "<cctype>",
"<errno.h>", "<cerrno>",
"<fenv.h>", "<cfenv>",
"<float.h>", "<cfloat>",
"<inttypes.h>", "<cinttypes>",
"<iso646.h>", "<ciso646>",
"<limits.h>", "<climits>",
"<locale.h>", "<clocale>",
"<math.h>", "<cmath>",
"<setjmp.h>", "<csetjmp>",
"<signal.h>", "<csignal>",
"<stdarg.h>", "<cstdarg>",
"<stdbool.h>", "<cstdbool>",
"<stddef.h>", "<cstddef>",
"<stdint.h>", "<cstdint>",
"<stdio.h>", "<cstdio>",
"<stdlib.h>", "<cstdlib>",
"<string.h>", "<cstring>",
"<tgmath.h>", "<ctgmath>",
"<time.h>", "<ctime>",
"<wchar.h>", "<cwchar>",
"<wctype.h>", "<cwctype>",
"<ios>", "<iostream>",
"<ios>", "<istream>",
"<ios>", "<ostream>",
"<iosfwd>", "<ios>",
"<iosfwd>", "<streambuf>",
"<istream>", "<iostream>",
"<istream>", "<fstream>",
"<istream>", "<sstream>",
"<ostream>", "<iostream>",
"<ostream>", "<fstream>",
"<ostream>", "<istream>",
"<ostream>", "<sstream>",
"<streambuf>", "<ios>",
};
public static List<HeaderSubstitutionMap> getDefaultMaps() {
return Arrays.asList(new HeaderSubstitutionMap[] {
new HeaderSubstitutionMap(Messages.GCCHeaderSubstitutionMaps_c_map, false,
new IncludeMap(true, cIncludeMap),
new IncludeMap(false, cIncludeMapWeak)),
new HeaderSubstitutionMap(Messages.GCCHeaderSubstitutionMaps_cpp_map, true,
new IncludeMap(true, cppIncludeMap),
new IncludeMap(false, cppIncludeMapWeak)),
});
}
}

View file

@ -0,0 +1,177 @@
/*******************************************************************************
* Copyright (c) 2013 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.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.XMLMemento;
import org.eclipse.cdt.ui.CUIPlugin;
/**
* A set of header file substitution rules.
*/
public class HeaderSubstitutionMap {
private static final String TAG_HEADER_SUBSTITUTION_MAPS = "maps"; //$NON-NLS-1$
private static final String TAG_HEADER_SUBSTITUTION_MAP = "map"; //$NON-NLS-1$
private static final String TAG_NAME = "name"; //$NON-NLS-1$
private static final String TAG_CPP_ONLY = "cpp_only"; //$NON-NLS-1$
private static final String TAG_UNCONDITIONAL_SUBSTITUTION_MAP = "unconditional_substitution_map"; //$NON-NLS-1$
private static final String TAG_OPTIONAL_SUBSTITUTION_MAP = "optional_substitution_map"; //$NON-NLS-1$
private String name;
private boolean cppOnly;
private final IncludeMap unconditionalSubstitutionMap;
private final IncludeMap optionalSubstitutionMap;
public HeaderSubstitutionMap(boolean cppOnly) {
this.cppOnly = cppOnly;
this.unconditionalSubstitutionMap = new IncludeMap(true);
this.optionalSubstitutionMap = new IncludeMap(false);
}
public HeaderSubstitutionMap(String name, boolean cppOnly,
IncludeMap unconditionalSubstitutionMap, IncludeMap optionalSubstitutionMap) {
this.name = name;
this.cppOnly = cppOnly;
this.unconditionalSubstitutionMap = unconditionalSubstitutionMap;
this.optionalSubstitutionMap = optionalSubstitutionMap;
}
/**
* Indicates that the header file {@code to} should be used instead of {@code from}.
*
* @param from The header file to be replaced.
* @param to The header file to be used instead.
* @param unconditionalSubstitution {@code true} if the header substitution is mandatory.
* Otherwise substitution only if the {@code to} header has to be included for other
* reasons.
*/
protected void addMapping(IncludeInfo from, IncludeInfo to, boolean unconditionalSubstitution) {
IncludeMap map = unconditionalSubstitution ? unconditionalSubstitutionMap : optionalSubstitutionMap;
map.addMapping(from, to);
}
/**
* Indicates that the header file {@code to} should be used instead of {@code from}.
* @param from The header file to be replaced. The header is represented by an include name
* optionally surrounded by double quotes or angle brackets. Angle brackets indicate
* a system include.
* @param to The header file to be used instead. The header is represented by an include name
* optionally surrounded by double quotes or angle brackets. Angle brackets indicate
* a system include.
* @param unconditionalSubstitution {@code true} if the header substitution is mandatory.
* Otherwise substitution only if the {@code to} header has to be included for other
* reasons.
*/
public void addMapping(String from, String to, boolean unconditionalSubstitution) {
IncludeMap map = unconditionalSubstitution ? unconditionalSubstitutionMap : optionalSubstitutionMap;
map.addMapping(from, to);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isCppOnly() {
return cppOnly;
}
public void setCppOnly(boolean cppOnly) {
this.cppOnly = cppOnly;
}
public void saveToMemento(IMemento memento) {
if (name != null)
memento.putString(TAG_NAME, name);
memento.putBoolean(TAG_CPP_ONLY, cppOnly);
unconditionalSubstitutionMap.saveToMemento(memento.createChild(TAG_UNCONDITIONAL_SUBSTITUTION_MAP));
optionalSubstitutionMap.saveToMemento(memento.createChild(TAG_OPTIONAL_SUBSTITUTION_MAP));
}
public static HeaderSubstitutionMap fromMemento(IMemento memento) {
String name = memento.getString(TAG_NAME);
Boolean b = memento.getBoolean(TAG_CPP_ONLY);
boolean cppOnly = b != null && b.booleanValue();
IncludeMap unconditionalSubstitutionMap = IncludeMap.fromMemento(true, memento.getChild(TAG_UNCONDITIONAL_SUBSTITUTION_MAP));
IncludeMap optionalSubstitutionMap = IncludeMap.fromMemento(false, memento.getChild(TAG_OPTIONAL_SUBSTITUTION_MAP));
// Remove potential redundant substitutions from optionalSubstitutionMap.
for (IncludeInfo header : unconditionalSubstitutionMap.getMap().keySet()) {
optionalSubstitutionMap.removeMapping(header);
}
return new HeaderSubstitutionMap(name, cppOnly, unconditionalSubstitutionMap, optionalSubstitutionMap);
}
public static HeaderSubstitutionMap fromSerializedMemento(String str) {
return fromSerializedMemento(new StringReader(str));
}
public static HeaderSubstitutionMap fromSerializedMemento(Reader reader) {
XMLMemento memento;
try {
memento = XMLMemento.createReadRoot(reader);
} catch (WorkbenchException e) {
return null;
}
return fromMemento(memento);
}
public static List<HeaderSubstitutionMap> deserializeMaps(String str) {
StringReader reader = new StringReader(str);
XMLMemento memento;
try {
memento = XMLMemento.createReadRoot(reader);
} catch (WorkbenchException e) {
return Collections.emptyList();
}
List<HeaderSubstitutionMap> maps = new ArrayList<HeaderSubstitutionMap>();
for (IMemento element : memento.getChildren(TAG_HEADER_SUBSTITUTION_MAP)) {
maps.add(fromMemento(element));
}
return maps;
}
public static String serializeMaps(List<HeaderSubstitutionMap> maps) {
XMLMemento memento = XMLMemento.createWriteRoot(TAG_HEADER_SUBSTITUTION_MAPS);
for (HeaderSubstitutionMap element : maps) {
element.saveToMemento(memento.createChild(TAG_HEADER_SUBSTITUTION_MAP));
}
StringWriter writer = new StringWriter();
try {
memento.save(writer);
} catch (IOException e) {
CUIPlugin.log(e);
}
return writer.toString();
}
public IncludeMap getUnconditionalSubstitutionMap() {
return unconditionalSubstitutionMap;
}
public IncludeMap getOptionalSubstitutionMap() {
return optionalSubstitutionMap;
}
}

View file

@ -20,502 +20,46 @@ import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.index.IndexLocationFactory;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
public class HeaderSubstitutor {
IncludeMap[] INCLUDE_MAPS = {
cIncludeMap, cIncludeMapWeak, cppIncludeMap, cppIncludeMapWeak
};
@SuppressWarnings("nls")
private static final IncludeMap symbolIncludeMap = new IncludeMap(false, false, new String[] {
"EOF", "<stdio.h>",
"EOF", "<libio.h>",
"NULL", "<stddef.h>",
"NULL", "<cstddef>",
"NULL", "<cstdio>",
"NULL", "<cstdlib>",
"NULL", "<cstring>",
"NULL", "<ctime>",
"NULL", "<cwchar>",
"NULL", "<locale.h>",
"NULL", "<stdio.h>",
"NULL", "<stdlib.h>",
"NULL", "<string.h>",
"NULL", "<time.h>",
"NULL", "<wchar.h>",
"blkcnt_t", "<sys/stat.h>",
"blkcnt_t", "<sys/types.h>",
"blksize_t", "<sys/types.h>",
"blksize_t", "<sys/stat.h>",
"calloc", "<stdlib.h>",
"daddr_t", "<sys/types.h>",
"daddr_t", "<rpc/types.h>",
"dev_t", "<sys/types.h>",
"dev_t", "<sys/stat.h>",
"error_t", "<errno.h>",
"error_t", "<argp.h>",
"error_t", "<argz.h>",
"free", "<stdlib.h>",
"fsblkcnt_t", "<sys/types.h>",
"fsblkcnt_t", "<sys/statvfs.h>",
"fsfilcnt_t", "<sys/types.h>",
"fsfilcnt_t", "<sys/statvfs.h>",
"gid_t", "<sys/types.h>",
"gid_t", "<grp.h>",
"gid_t", "<pwd.h>",
"gid_t", "<stropts.h>",
"gid_t", "<sys/ipc.h>",
"gid_t", "<sys/stat.h>",
"gid_t", "<unistd.h>",
"id_t", "<sys/types.h>",
"id_t", "<sys/resource.h>",
"ino64_t", "<sys/types.h>",
"ino64_t", "<dirent.h>",
"ino_t", "<sys/types.h>",
"ino_t", "<dirent.h>",
"ino_t", "<sys/stat.h>",
"int8_t", "<sys/types.h>",
"int8_t", "<stdint.h>",
"intptr_t", "<stdint.h>",
"intptr_t", "<unistd.h>",
"key_t", "<sys/types.h>",
"key_t", "<sys/ipc.h>",
"malloc", "<stdlib.h>",
"mode_t", "<sys/types.h>",
"mode_t", "<sys/stat.h>",
"mode_t", "<sys/ipc.h>",
"mode_t", "<sys/mman.h>",
"nlink_t", "<sys/types.h>",
"nlink_t", "<sys/stat.h>",
"off64_t", "<sys/types.h>",
"off64_t", "<unistd.h>",
"off_t", "<sys/types.h>",
"off_t", "<unistd.h>",
"off_t", "<sys/stat.h>",
"off_t", "<sys/mman.h>",
"pid_t", "<sys/types.h>",
"pid_t", "<unistd.h>",
"pid_t", "<signal.h>",
"pid_t", "<sys/msg.h>",
"pid_t", "<sys/shm.h>",
"pid_t", "<termios.h>",
"pid_t", "<time.h>",
"pid_t", "<utmpx.h>",
"realloc", "<stdlib.h>",
"sigset_t", "<signal.h>",
"sigset_t", "<sys/epoll.h>",
"sigset_t", "<sys/select.h>",
"size_t", "<stddef.h>",
"socklen_t", "<bits/socket.h>",
"socklen_t", "<unistd.h>",
"socklen_t", "<arpa/inet.h>",
"ssize_t", "<sys/types.h>",
"ssize_t", "<unistd.h>",
"ssize_t", "<monetary.h>",
"ssize_t", "<sys/msg.h>",
"std::allocator", "<memory>",
"std::allocator", "<string>",
"std::allocator", "<vector>",
"std::allocator", "<map>",
"std::allocator", "<set>",
"std::char_traits", "<string>",
"std::char_traits", "<ostream>",
"std::char_traits", "<istream>",
"suseconds_t", "<sys/types.h>",
"suseconds_t", "<sys/time.h>",
"suseconds_t", "<sys/select.h>",
"u_char", "<sys/types.h>",
"u_char", "<rpc/types.h>",
"uid_t", "<sys/types.h>",
"uid_t", "<unistd.h>",
"uid_t", "<pwd.h>",
"uid_t", "<signal.h>",
"uid_t", "<stropts.h>",
"uid_t", "<sys/ipc.h>",
"uid_t", "<sys/stat.h>",
"useconds_t", "<sys/types.h>",
"useconds_t", "<unistd.h>",
"va_list", "<stdarg.h>",
});
@SuppressWarnings("nls")
private static final IncludeMap cIncludeMap = new IncludeMap(true, false, new String[] {
"<asm/errno-base.h>", "<errno.h>",
"<asm/errno.h>", "<errno.h>",
"<asm/ioctls.h>", "<sys/ioctl.h>",
"<asm/posix_types_32.h>", "<asm/posix_types.h>",
"<asm/posix_types_64.h>", "<asm/posix_types.h>",
"<asm/ptrace-abi.h>", "<asm/ptrace.h>",
"<asm/socket.h>", "<sys/socket.h>",
"<asm/unistd.h>", "<syscall.h>",
"<asm/unistd_32.h>", "<syscall.h>",
"<asm/unistd_64.h>", "<syscall.h>",
"<bits/a.out.h>", "<a.out.h>",
"<bits/byteswap.h>", "<byteswap.h>",
"<bits/cmathcalls.h>", "<complex.h>",
"<bits/confname.h>", "<unistd.h>",
"<bits/dirent.h>", "<dirent.h>",
"<bits/dlfcn.h>", "<dlfcn.h>",
"<bits/elfclass.h>", "<link.h>",
"<bits/endian.h>", "<endian.h>",
"<bits/environments.h>", "<unistd.h>",
"<bits/errno.h>", "<errno.h>",
"<bits/error.h>", "<error.h>",
"<bits/fcntl.h>", "<fcntl.h>",
"<bits/fcntl2.h>", "<fcntl.h>",
"<bits/fenv.h>", "<fenv.h>",
"<bits/fenvinline.h>", "<fenv.h>",
"<bits/huge_val.h>", "<math.h>",
"<bits/huge_valf.h>", "<math.h>",
"<bits/huge_vall.h>", "<math.h>",
"<bits/in.h>", "<netinet/in.h>",
"<bits/inf.h>", "<math.h>",
"<bits/ioctl-types.h>", "<sys/ioctl.h>",
"<bits/ioctls.h>", "<sys/ioctl.h>",
"<bits/ipc.h>", "<sys/ipc.h>",
"<bits/ipctypes.h>", "<sys/ipc.h>",
"<bits/libio-ldbl.h>", "<libio.h>",
"<bits/link.h>", "<link.h>",
"<bits/locale.h>", "<locale.h>",
"<bits/mathcalls.h>", "<math.h>",
"<bits/mathdef.h>", "<math.h>",
"<bits/mathinline.h>", "<math.h>",
"<bits/mman.h>", "<sys/mman.h>",
"<bits/monetary-ldbl.h>", "<monetary.h>",
"<bits/mqueue.h>", "<mqueue.h>",
"<bits/mqueue2.h>", "<mqueue.h>",
"<bits/msq.h>", "<sys/msg.h>",
"<bits/nan.h>", "<math.h>",
"<bits/netdb.h>", "<netdb.h>",
"<bits/poll.h>", "<poll.h>",
"<bits/posix1_lim.h>", "<limits.h>",
"<bits/posix2_lim.h>", "<limits.h>",
"<bits/posix_opt.h>", "<unistd.h>",
"<bits/predefs.h>", "<features.h>",
"<bits/printf-ldbl.h>", "<printf.h>",
"<bits/pthreadtypes.h>", "<pthread.h>",
"<bits/resource.h>", "<sys/resource.h>",
"<bits/sched.h>", "<sched.h>",
"<bits/select.h>", "<sys/select.h>",
"<bits/sem.h>", "<sys/sem.h>",
"<bits/semaphore.h>", "<semaphore.h>",
"<bits/setjmp.h>", "<setjmp.h>",
"<bits/shm.h>", "<sys/shm.h>",
"<bits/sigaction.h>", "<signal.h>",
"<bits/sigcontext.h>", "<signal.h>",
"<bits/siginfo.h>", "<signal.h>",
"<bits/signum.h>", "<signal.h>",
"<bits/sigset.h>", "<signal.h>",
"<bits/sigstack.h>", "<signal.h>",
"<bits/sigthread.h>", "<signal.h>",
"<bits/sockaddr.h>", "<sys/un.h>",
"<bits/socket.h>", "<sys/socket.h>",
"<bits/stab.def>", "<stab.h>",
"<bits/stat.h>", "<sys/stat.h>",
"<bits/statfs.h>", "<sys/statfs.h>",
"<bits/statvfs.h>", "<sys/statvfs.h>",
"<bits/stdio-ldbl.h>", "<stdio.h>",
"<bits/stdio-lock.h>", "<libio.h>",
"<bits/stdio.h>", "<stdio.h>",
"<bits/stdio2.h>", "<stdio.h>",
"<bits/stdio_lim.h>", "<stdio.h>",
"<bits/stdlib-ldbl.h>", "<stdlib.h>",
"<bits/stdlib.h>", "<stdlib.h>",
"<bits/string.h>", "<string.h>",
"<bits/string2.h>", "<string.h>",
"<bits/string3.h>", "<string.h>",
"<bits/stropts.h>", "<stropts.h>",
"<bits/sys_errlist.h>", "<stdio.h>",
"<bits/syscall.h>", "<syscall.h>",
"<bits/syslog-ldbl.h>", "<syslog.h>",
"<bits/syslog-path.h>", "<syslog.h>",
"<bits/syslog.h>", "<syslog.h>",
"<bits/termios.h>", "<termios.h>",
"<bits/time.h>", "<sys/time.h>",
"<bits/types.h>", "<sys/types.h>",
"<bits/uio.h>", "<sys/uio.h>",
"<bits/unistd.h>", "<unistd.h>",
"<bits/ustat.h>", "<ustat.h>",
"<bits/utmp.h>", "<utmp.h>",
"<bits/utmpx.h>", "<utmpx.h>",
"<bits/utsname.h>", "<sys/utsname.h>",
"<bits/waitflags.h>", "<sys/wait.h>",
"<bits/waitstatus.h>", "<sys/wait.h>",
"<bits/wchar-ldbl.h>", "<wchar.h>",
"<bits/wchar.h>", "<wchar.h>",
"<bits/wchar2.h>", "<wchar.h>",
"<bits/xopen_lim.h>", "<limits.h>",
"<bits/xtitypes.h>", "<stropts.h>",
"<linux/errno.h>", "<errno.h>",
"<linux/limits.h>", "<limits.h>",
"<linux/socket.h>", "<sys/socket.h>",
"<sys/poll.h>", "<poll.h>",
"<sys/syscall.h>", "<syscall.h>",
"<sys/syslog.h>", "<syslog.h>",
"<sys/ucontext.h>", "<ucontext.h>",
"<sys/ustat.h>", "<ustat.h>",
"<wait.h>", "<sys/wait.h>",
});
private static final IncludeMap cIncludeMapWeak = new IncludeMap(false, false, new String[] {
});
@SuppressWarnings("nls")
private static final IncludeMap cppIncludeMap = new IncludeMap(true, true, new String[] {
"<auto_ptr.h>", "<memory>",
"<backward/auto_ptr.h>", "<memory>",
"<backward/binders.h>", "<functional>",
"<backward/hash_fun.h>", "<hash_map>",
"<backward/hash_fun.h>", "<hash_set>",
"<backward/hashtable.h>", "<hash_map>",
"<backward/hashtable.h>", "<hash_set>",
"<backward/strstream>", "<strstream>",
"<binders.h>", "<functional>",
"<bits/algorithmfwd.h>", "<algorithm>",
"<bits/allocator.h>", "<memory>",
"<bits/atomic_word.h>", "<ext/atomicity.h>",
"<bits/basic_file.h>", "<fstream>",
"<bits/basic_ios.h>", "<ios>",
"<bits/basic_string.h>", "<string>",
"<bits/basic_string.tcc>", "<string>",
"<bits/boost_concept_check.h>", "<bits/concept_check.h>",
"<bits/boost_sp_shared_count.h>", "<memory>",
"<bits/c++allocator.h>", "<memory>",
"<bits/c++config.h>", "<cstddef>",
"<bits/c++io.h>", "<ext/stdio_sync_filebuf.h>",
"<bits/char_traits.h>", "<string>",
"<bits/cmath.tcc>", "<cmath>",
"<bits/codecvt.h>", "<fstream>",
"<bits/codecvt.h>", "<locale>",
"<bits/ctype_base.h>", "<locale>",
"<bits/ctype_base.h>", "<ios>",
"<bits/ctype_inline.h>", "<locale>",
"<bits/ctype_inline.h>", "<ios>",
"<bits/cxxabi_tweaks.h>", "<cxxabi.h>",
"<bits/deque.tcc>", "<deque>",
"<bits/exception_defines.h>", "<exception>",
"<bits/fstream.tcc>", "<fstream>",
"<bits/functexcept.h>", "<algorithm>",
"<bits/functional_hash.h>", "<unordered_map>",
"<bits/gslice.h>", "<valarray>",
"<bits/gslice_array.h>", "<valarray>",
"<bits/hashtable.h>", "<unordered_map>",
"<bits/hashtable.h>", "<unordered_set>",
"<bits/indirect_array.h>", "<valarray>",
"<bits/ios_base.h>", "<iostream>",
"<bits/ios_base.h>", "<ios>",
"<bits/ios_base.h>", "<iomanip>",
"<bits/istream.tcc>", "<istream>",
"<bits/list.tcc>", "<list>",
"<bits/locale_classes.h>", "<locale>",
"<bits/locale_classes.h>", "<ios>",
"<bits/locale_classes.tcc>", "<locale>",
"<bits/locale_classes.tcc>", "<ios>",
"<bits/locale_facets.h>", "<locale>",
"<bits/locale_facets.h>", "<ios>",
"<bits/locale_facets.tcc>", "<locale>",
"<bits/locale_facets.tcc>", "<ios>",
"<bits/locale_facets_nonio.h>", "<locale>",
"<bits/locale_facets_nonio.tcc>", "<locale>",
"<bits/localefwd.h>", "<locale>",
"<bits/mask_array.h>", "<valarray>",
"<bits/messages_members.h>", "<locale>",
"<bits/move.h>", "<algorithm>",
"<bits/ostream.tcc>", "<ostream>",
"<bits/ostream_insert.h>", "<ostream>",
"<bits/postypes.h>", "<iostream>",
"<bits/postypes.h>", "<string>",
"<bits/slice_array.h>", "<valarray>",
"<bits/sstream.tcc>", "<sstream>",
"<bits/stl_algo.h>", "<algorithm>",
"<bits/stl_algobase.h>", "<algorithm>",
"<bits/stl_bvector.h>", "<vector>",
"<bits/stl_construct.h>", "<memory>",
"<bits/stl_deque.h>", "<deque>",
"<bits/stl_function.h>", "<functional>",
"<bits/stl_heap.h>", "<queue>",
"<bits/stl_iterator.h>", "<iterator>",
"<bits/stl_iterator_base_funcs.h>", "<iterator>",
"<bits/stl_iterator_base_types.h>", "<iterator>",
"<bits/stl_list.h>", "<list>",
"<bits/stl_map.h>", "<map>",
"<bits/stl_move.h>", "<algorithm>",
"<bits/stl_multimap.h>", "<map>",
"<bits/stl_multiset.h>", "<set>",
"<bits/stl_numeric.h>", "<numeric>",
"<bits/stl_pair.h>", "<utility>",
"<bits/stl_pair.h>", "<tr1/utility>",
"<bits/stl_queue.h>", "<queue>",
"<bits/stl_raw_storage_iter.h>", "<memory>",
"<bits/stl_relops.h>", "<utility>",
"<bits/stl_set.h>", "<set>",
"<bits/stl_stack.h>", "<stack>",
"<bits/stl_tempbuf.h>", "<memory>",
"<bits/stl_tree.h>", "<map>",
"<bits/stl_tree.h>", "<set>",
"<bits/stl_uninitialized.h>", "<memory>",
"<bits/stl_vector.h>", "<vector>",
"<bits/stream_iterator.h>", "<iterator>",
"<bits/streambuf.tcc>", "<streambuf>",
"<bits/streambuf_iterator.h>", "<iterator>",
"<bits/streambuf_iterator.h>", "<ios>",
"<bits/stringfwd.h>", "<string>",
"<bits/valarray_after.h>", "<valarray>",
"<bits/valarray_array.h>", "<valarray>",
"<bits/valarray_array.tcc>", "<valarray>",
"<bits/valarray_before.h>", "<valarray>",
"<bits/vector.tcc>", "<vector>",
"<debug/safe_iterator.tcc>", "<debug/safe_iterator.h>",
"<exception_defines.h>", "<exception>",
"<ext/algorithm>", "<algorithm>",
"<ext/functional>", "<functional>",
"<ext/hash_map>", "<hash_map>",
"<ext/hash_set>", "<hash_set>",
"<ext/numeric>", "<numeric>",
"<ext/slist>", "<slist>",
"<ext/sso_string_base.h>", "<string>",
"<ext/vstring.h>", "<string>",
"<ext/vstring.tcc>", "<string>",
"<ext/vstring_fwd.h>", "<string>",
"<hash_fun.h>", "<hash_map>",
"<hash_fun.h>", "<hash_set>",
"<hashtable.h>", "<hash_map>",
"<hashtable.h>", "<hash_set>",
"<tr1/bessel_function.tcc>", "<tr1/cmath>",
"<tr1/beta_function.tcc>", "<tr1/cmath>",
"<tr1/ell_integral.tcc>", "<tr1/cmath>",
"<tr1/exp_integral.tcc>", "<tr1/cmath>",
"<tr1/gamma.tcc>", "<tr1/cmath>",
"<tr1/hypergeometric.tcc>", "<tr1/cmath>",
"<tr1/legendre_function.tcc>", "<tr1/cmath>",
"<tr1/modified_bessel_func.tcc>", "<tr1/cmath>",
"<tr1/poly_hermite.tcc>", "<tr1/cmath>",
"<tr1/poly_laguerre.tcc>", "<tr1/cmath>",
"<tr1/riemann_zeta.tcc>", "<tr1/cmath>",
"<tr1_impl/array>", "<array>",
"<tr1_impl/array>", "<tr1/array>",
"<tr1_impl/boost_shared_ptr.h>", "<memory>",
"<tr1_impl/boost_shared_ptr.h>", "<tr1/memory>",
"<tr1_impl/boost_sp_counted_base.h>", "<memory>",
"<tr1_impl/boost_sp_counted_base.h>", "<tr1/memory>",
"<tr1_impl/cctype>", "<cctype>",
"<tr1_impl/cctype>", "<tr1/cctype>",
"<tr1_impl/cfenv>", "<cfenv>",
"<tr1_impl/cfenv>", "<tr1/cfenv>",
"<tr1_impl/cinttypes>", "<cinttypes>",
"<tr1_impl/cinttypes>", "<tr1/cinttypes>",
"<tr1_impl/cmath>", "<cmath>",
"<tr1_impl/cmath>", "<tr1/cmath>",
"<tr1_impl/complex>", "<complex>",
"<tr1_impl/complex>", "<tr1/complex>",
"<tr1_impl/cstdint>", "<cstdint>",
"<tr1_impl/cstdint>", "<tr1/cstdint>",
"<tr1_impl/cstdio>", "<cstdio>",
"<tr1_impl/cstdio>", "<tr1/cstdio>",
"<tr1_impl/cstdlib>", "<cstdlib>",
"<tr1_impl/cstdlib>", "<tr1/cstdlib>",
"<tr1_impl/cwchar>", "<cwchar>",
"<tr1_impl/cwchar>", "<tr1/cwchar>",
"<tr1_impl/cwctype>", "<cwctype>",
"<tr1_impl/cwctype>", "<tr1/cwctype>",
"<tr1_impl/functional>", "<functional>",
"<tr1_impl/functional>", "<tr1/functional>",
"<tr1_impl/functional_hash.h>", "<tr1/functional_hash.h>",
"<tr1_impl/hashtable>", "<tr1/hashtable.h>",
"<tr1_impl/random.tcc>", "<random>",
"<tr1_impl/random.tcc>", "<tr1/random>",
"<tr1_impl/random>", "<random>",
"<tr1_impl/random>", "<tr1/random>",
"<tr1_impl/regex>", "<regex>",
"<tr1_impl/regex>", "<tr1/regex>",
"<tr1_impl/type_traits>", "<tr1/type_traits>",
"<tr1_impl/type_traits>", "<type_traits>",
"<tr1_impl/unordered_map>", "<tr1/unordered_map>",
"<tr1_impl/unordered_map>", "<unordered_map>",
"<tr1_impl/unordered_set>", "<tr1/unordered_set>",
"<tr1_impl/unordered_set>", "<unordered_set>",
"<tr1_impl/utility>", "<tr1/utility>",
"<tr1_impl/utility>", "<utility>",
});
@SuppressWarnings("nls")
private static final IncludeMap cppIncludeMapWeak = new IncludeMap(false, true, new String[] {
"<assert.h>", "<cassert>",
"<complex.h>", "<ccomplex>",
"<ctype.h>", "<cctype>",
"<errno.h>", "<cerrno>",
"<fenv.h>", "<cfenv>",
"<float.h>", "<cfloat>",
"<inttypes.h>", "<cinttypes>",
"<iso646.h>", "<ciso646>",
"<limits.h>", "<climits>",
"<locale.h>", "<clocale>",
"<math.h>", "<cmath>",
"<setjmp.h>", "<csetjmp>",
"<signal.h>", "<csignal>",
"<stdarg.h>", "<cstdarg>",
"<stdbool.h>", "<cstdbool>",
"<stddef.h>", "<cstddef>",
"<stdint.h>", "<cstdint>",
"<stdio.h>", "<cstdio>",
"<stdlib.h>", "<cstdlib>",
"<string.h>", "<cstring>",
"<tgmath.h>", "<ctgmath>",
"<time.h>", "<ctime>",
"<wchar.h>", "<cwchar>",
"<wctype.h>", "<cwctype>",
"<ios>", "<iostream>",
"<ios>", "<istream>",
"<ios>", "<ostream>",
"<iosfwd>", "<ios>",
"<iosfwd>", "<streambuf>",
"<istream>", "<iostream>",
"<istream>", "<fstream>",
"<istream>", "<sstream>",
"<ostream>", "<iostream>",
"<ostream>", "<fstream>",
"<ostream>", "<istream>",
"<ostream>", "<sstream>",
"<streambuf>", "<ios>",
});
private final InclusionContext fContext;
private final IncludeMap fIncludeMap;
private final IncludeMap fIncludeMapWeak;
private IncludeMap[] fIncludeMaps;
public HeaderSubstitutor(InclusionContext context) {
fContext = context;
fIncludeMap = new IncludeMap(cIncludeMap);
if (fContext.isCXXLanguage())
fIncludeMap.addAllMappings(cppIncludeMap);
fIncludeMapWeak = new IncludeMap(cIncludeMapWeak);
if (fContext.isCXXLanguage())
fIncludeMapWeak.addAllMappings(cppIncludeMapWeak);
}
public void addIncludeMap(IncludeMap map) {
if (fIncludeMaps != null)
throw new IllegalStateException("Modifications are not allowed after maps have been finalized"); //$NON-NLS-1$
if (map.isCppOnly() && !fContext.isCXXLanguage())
return;
IncludeMap receiver = map.isForcedReplacement() ? fIncludeMap : fIncludeMapWeak;
receiver.addAllMappings(map);
fIncludeMaps = new IncludeMap[] { new IncludeMap(true), new IncludeMap(false) };
IPreferencesService preferences = Platform.getPreferencesService();
IScopeContext[] scopes = PreferenceConstants.getPreferenceScopes(context.getProject());
String str = preferences.getString(CUIPlugin.PLUGIN_ID,
PreferenceConstants.INCLUDES_HEADER_SUBSTITUTION, null, scopes);
if (str != null) {
List<HeaderSubstitutionMap> maps = HeaderSubstitutionMap.deserializeMaps(str);
for (HeaderSubstitutionMap map : maps) {
if (!map.isCppOnly() || fContext.isCXXLanguage()) {
fIncludeMaps[0].addAllMappings(map.getUnconditionalSubstitutionMap());
fIncludeMaps[1].addAllMappings(map.getOptionalSubstitutionMap());
}
}
}
}
/**
* Selects the header file to be appear in the {@code #include} statement given the header file
* that needs to be included. Returns absolute path for the header if it can be uniquely
* Selects the header file to be used in an {@code #include} statement given the header file
* that needs to be included. Returns absolute path of the header if it can be uniquely
* determined, or {@code null} otherwise. The header is determined uniquely if there are no
* optional replacement headers for it, and there are no more that one forced replacement.
* optional replacement headers for it, and there is no more that one unconditional replacement.
*
* @param path absolute path of the header to be included directly or indirectly
* @return absolute path of the header to be included directly
*/
@ -523,9 +67,9 @@ public class HeaderSubstitutor {
IncludeInfo includeInfo = fContext.getIncludeForHeaderFile(path);
if (includeInfo == null)
return null;
IncludeMap[] maps = getAllIncludeMaps();
IncludeMap[] maps = fIncludeMaps;
for (IncludeMap map : maps) {
if (map.isForcedReplacement()) {
if (map.isUnconditionalSubstitution()) {
List<IncludeInfo> replacements = map.getMapping(includeInfo);
if (replacements.size() == 1) {
includeInfo = replacements.get(0);
@ -535,7 +79,7 @@ public class HeaderSubstitutor {
}
}
for (IncludeMap map : maps) {
if (!map.isForcedReplacement()) {
if (!map.isUnconditionalSubstitution()) {
if (!map.getMapping(includeInfo).isEmpty()) {
return null;
}
@ -551,14 +95,14 @@ public class HeaderSubstitutor {
// TODO(sprigogin): Take symbolIncludeMap into account.
List<IncludeInfo> candidates = new ArrayList<IncludeInfo>();
candidates.add(includeInfo);
IncludeMap[] maps = getAllIncludeMaps();
IncludeMap[] maps = fIncludeMaps;
for (IncludeMap map : maps) {
for (int i = 0; i < candidates.size();) {
IncludeInfo candidate = candidates.get(i);
List<IncludeInfo> replacements = map.getMapping(candidate);
int increment = 1;
if (!replacements.isEmpty()) {
if (map.isForcedReplacement()) {
if (map.isUnconditionalSubstitution()) {
candidates.remove(i);
increment = 0;
}
@ -657,15 +201,6 @@ public class HeaderSubstitutor {
return request.getCandidatePaths().iterator().next();
}
private IncludeMap[] getAllIncludeMaps() {
if (fIncludeMaps == null) {
fIncludeMap.transitivelyClose();
fIncludeMapWeak.transitivelyClose();
fIncludeMaps = new IncludeMap[] { fIncludeMap, fIncludeMapWeak };
}
return fIncludeMaps;
}
/**
* Returns whether the given URI points within the workspace.
*/

View file

@ -10,7 +10,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.includes;
import java.io.StringReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
@ -20,28 +19,23 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.XMLMemento;
/**
* A set of header file substitution rules.
*/
public class IncludeMap {
private static final String TAG_CPP_ONLY = "cpp_only"; //$NON-NLS-1$
private static final String TAG_FORCED_REPLACEMENT = "forced_replacement"; //$NON-NLS-1$
private static final String TAG_MAPPING = "mapping"; //$NON-NLS-1$
private static final String TAG_KEY = "key"; //$NON-NLS-1$
private static final String TAG_VALUE = "value"; //$NON-NLS-1$
private final boolean forcedReplacement;
private final boolean cppOnly;
private final boolean unconditionalSubstitution; // Not serialized when saving to a memento.
private final Map<IncludeInfo, List<IncludeInfo>> map;
public IncludeMap(boolean forcedReplacement, boolean cppOnly) {
this.forcedReplacement = forcedReplacement;
this.cppOnly = cppOnly;
public IncludeMap(boolean unconditionalSubstitution) {
this.unconditionalSubstitution = unconditionalSubstitution;
this.map = new HashMap<IncludeInfo, List<IncludeInfo>>();
}
@ -50,11 +44,10 @@ public class IncludeMap {
* Keys and values may be optionally surrounded by double quotes or angle brackets.
* Angle brackets indicate a system include.
*/
public IncludeMap(boolean forcedReplacement, boolean cppOnly, String[] keysAndValues) {
public IncludeMap(boolean unconditionalSubstitution, String[] keysAndValues) {
if (keysAndValues.length % 2 != 0)
throw new IllegalArgumentException("More keys than values"); //$NON-NLS-1$
this.forcedReplacement = forcedReplacement;
this.cppOnly = cppOnly;
this.unconditionalSubstitution = unconditionalSubstitution;
this.map = new HashMap<IncludeInfo, List<IncludeInfo>>(keysAndValues.length / 2);
for (int i = 0; i < keysAndValues.length;) {
String key = keysAndValues[i++];
@ -63,8 +56,7 @@ public class IncludeMap {
}
public IncludeMap(IncludeMap other) {
this.forcedReplacement = other.forcedReplacement;
this.cppOnly = other.cppOnly;
this.unconditionalSubstitution = other.unconditionalSubstitution;
this.map = new HashMap<IncludeInfo, List<IncludeInfo>>(other.map.size());
addAllMappings(other);
}
@ -117,6 +109,28 @@ public class IncludeMap {
return list;
}
/**
* Removes substitutions for a given header file.
*
* @param from the header file to remove substitutions for
* @return the previous substitutions associated with the header file, or
* {@code null} if there were no substitutions for the header.
*/
public List<IncludeInfo> removeMapping(String from) {
return removeMapping(new IncludeInfo(from));
}
/**
* Removes substitutions for a given header file.
*
* @param from the header file to remove substitutions for
* @return the previous substitutions associated with the header file, or
* {@code null} if there were no substitutions for the header.
*/
public List<IncludeInfo> removeMapping(IncludeInfo from) {
return map.remove(from);
}
/**
* Returns header files that should be used instead of the given one.
*
@ -133,18 +147,14 @@ public class IncludeMap {
return list == null ? null : list.get(0);
}
public boolean isForcedReplacement() {
return forcedReplacement;
public boolean isUnconditionalSubstitution() {
return unconditionalSubstitution;
}
public boolean isCppOnly() {
return cppOnly;
}
// XXX Define a class containing two Includemaps, week and strong
/**
* Writes the map to a memento. The {@link #isUnconditionalSubstitution()} flag is not written.
*/
public void saveToMemento(IMemento memento) {
memento.putBoolean(TAG_CPP_ONLY, cppOnly);
memento.putBoolean(TAG_FORCED_REPLACEMENT, forcedReplacement);
for (Entry<IncludeInfo, List<IncludeInfo>> entry : map.entrySet()) {
String key = entry.getKey().toString();
for (IncludeInfo value : entry.getValue()) {
@ -155,29 +165,20 @@ public class IncludeMap {
}
}
public static IncludeMap fromMemento(IMemento memento) {
Boolean cppOnly = memento.getBoolean(TAG_CPP_ONLY);
Boolean forcedReplacement = memento.getBoolean(TAG_FORCED_REPLACEMENT);
IncludeMap includeMap = new IncludeMap(cppOnly, forcedReplacement);
public static IncludeMap fromMemento(boolean unconditionalSubstitution, IMemento memento) {
IncludeMap includeMap = new IncludeMap(unconditionalSubstitution);
Set<String> keys = unconditionalSubstitution ? new HashSet<String>() : Collections.<String>emptySet();
for (IMemento mapping : memento.getChildren(TAG_MAPPING)) {
includeMap.addMapping(mapping.getString(TAG_KEY), mapping.getString(TAG_VALUE));
String key = mapping.getString(TAG_KEY);
// There can be no more than one unconditional substitution for any header file.
if (!unconditionalSubstitution || keys.add(key))
includeMap.addMapping(key, mapping.getString(TAG_VALUE));
}
return includeMap;
}
public static IncludeMap fromSerializedMemento(String str) {
StringReader reader = new StringReader(str);
XMLMemento memento;
try {
memento = XMLMemento.createReadRoot(reader);
} catch (WorkbenchException e) {
return null;
}
return fromMemento(memento);
}
public void addAllMappings(IncludeMap other) {
if (other.forcedReplacement != forcedReplacement)
if (other.unconditionalSubstitution != unconditionalSubstitution)
throw new IllegalArgumentException();
for (Entry<IncludeInfo, List<IncludeInfo>> entry : other.map.entrySet()) {
IncludeInfo source = entry.getKey();
@ -199,7 +200,7 @@ public class IncludeMap {
ArrayDeque<IncludeInfo> queue = new ArrayDeque<IncludeInfo>(targets);
targets.clear();
HashSet<IncludeInfo> processed = new HashSet<IncludeInfo>();
if (!forcedReplacement)
if (!unconditionalSubstitution)
processed.add(source); // Don't allow mapping to itself.
HashSet<IncludeInfo> seenTargets = new HashSet<IncludeInfo>();
IncludeInfo target;
@ -212,10 +213,10 @@ public class IncludeMap {
boolean added = false;
// Check if we saw the same target earlier to protect against an infinite loop.
if (seenTargets.add(target)) {
for (int i = newTargets.size(); --i >=0;) {
for (int i = newTargets.size(); --i >= 0;) {
IncludeInfo newTarget = newTargets.get(i);
if (!processed.contains(newTarget)) {
if (forcedReplacement && newTarget.equals(source)) {
if (unconditionalSubstitution && newTarget.equals(source)) {
break queueLoop; // Leave the mapping empty.
}
queue.addFirst(newTarget);
@ -226,21 +227,21 @@ public class IncludeMap {
if (!added) {
target = queue.pollFirst();
targets.add(target);
if (forcedReplacement)
if (unconditionalSubstitution)
break;
processed.add(target);
seenTargets.clear();
}
} else {
targets.add(target);
if (forcedReplacement)
if (unconditionalSubstitution)
break;
processed.add(target);
seenTargets.clear();
}
}
}
if (forcedReplacement) {
if (unconditionalSubstitution) {
// Remove trivial mappings.
for (Iterator<Entry<IncludeInfo, List<IncludeInfo>>> iter = map.entrySet().iterator(); iter.hasNext();) {
Entry<IncludeInfo, List<IncludeInfo>> entry = iter.next();
@ -257,8 +258,7 @@ public class IncludeMap {
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("forcedReplacement = ").append(forcedReplacement); //$NON-NLS-1$
buf.append(", cppOnly = ").append(cppOnly); //$NON-NLS-1$
buf.append("upconditionalSubstitution = ").append(unconditionalSubstitution); //$NON-NLS-1$
ArrayList<IncludeInfo> sources = new ArrayList<IncludeInfo>(map.keySet());
Collections.sort(sources);
for (IncludeInfo source : sources) {
@ -274,4 +274,8 @@ public class IncludeMap {
}
return buf.toString();
}
public Map<IncludeInfo, List<IncludeInfo>> getMap() {
return Collections.unmodifiableMap(map);
}
}

View file

@ -35,6 +35,7 @@ public class IncludePreferences {
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;
@ -89,8 +90,11 @@ public class IncludePreferences {
allowReordering = PreferenceConstants.getPreference(
PreferenceConstants.INCLUDES_ALLOW_REORDERING, project, true);
// TODO(sprigogin): Create a preference for this.
allowPartnerIndirectInclusion = false;
// 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);
@ -159,11 +163,16 @@ public class IncludePreferences {
store.setDefault(PreferenceConstants.INCLUDES_PARTNER_FILE_SUFFIXES, DEFAULT_PARTNER_FILE_SUFFIXES);
store.setDefault(PreferenceConstants.INCLUDES_HEURISTIC_HEADER_SUBSTITUTION, true);
store.setDefault(PreferenceConstants.INCLUDES_ALLOW_REORDERING, true);
store.setDefault(PreferenceConstants.INCLUDES_ALLOW_PARTNER_INDIRECT_INCLUSION, false);
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_TEMPLATES, false);
store.setDefault(PreferenceConstants.FORWARD_DECLARE_NAMESPACE_ELEMENTS, true);
store.setDefault(PreferenceConstants.INCLUDES_UNUSED_STATEMENTS_DISPOSITION, UnusedStatementDisposition.COMMENT_OUT.toString());
store.setDefault(PreferenceConstants.INCLUDES_UNUSED_STATEMENTS_DISPOSITION,
UnusedStatementDisposition.COMMENT_OUT.toString());
store.setDefault(PreferenceConstants.INCLUDES_HEADER_SUBSTITUTION,
HeaderSubstitutionMap.serializeMaps(GCCHeaderSubstitutionMaps.getDefaultMaps()));
}
}

View file

@ -174,7 +174,7 @@ public class InclusionContext {
queue.add(file);
while ((file = queue.pollFirst()) != null) {
for (IIndexInclude include : file.getIncludes()) {
if (include.isIncludedFileExported()) {
if (fPreferences.allowIndirectInclusion || include.isIncludedFileExported()) {
file = fIndex.resolveInclude(include);
if (file != null) {
if (exportedHeaders.add(getPath(file)))

View file

@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2013 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 org.eclipse.osgi.util.NLS;
public final class Messages extends NLS {
public static String GCCHeaderSubstitutionMaps_c_map;
public static String GCCHeaderSubstitutionMaps_cpp_map;
private Messages() {
// Do not instantiate
}
static {
NLS.initializeMessages(Messages.class.getName(), Messages.class);
}
}

View file

@ -0,0 +1,13 @@
###############################################################################
# Copyright (c) 2013 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
###############################################################################
GCCHeaderSubstitutionMaps_c_map=GCC C Header Substitution Map
GCCHeaderSubstitutionMaps_cpp_map=GCC C++ Header Substitution Map

View file

@ -786,19 +786,19 @@ public class ListDialogField<T> extends DialogField {
return reverse;
}
private void remove() {
protected void remove() {
removeElements(getSelectedElements());
}
private void up() {
protected void up() {
moveUp(getSelectedElements());
}
private void down() {
protected void down() {
moveDown(getSelectedElements());
}
private boolean canMoveUp() {
protected boolean canMoveUp() {
if (isOkToUse(fTableControl)) {
int[] indc= fTable.getTable().getSelectionIndices();
for (int i= 0; i < indc.length; i++) {
@ -810,7 +810,7 @@ public class ListDialogField<T> extends DialogField {
return false;
}
private boolean canMoveDown() {
protected boolean canMoveDown() {
if (isOkToUse(fTableControl)) {
int[] indc= fTable.getTable().getSelectionIndices();
int k= fElements.size() - 1;

View file

@ -2038,6 +2038,13 @@ public class PreferenceConstants {
*/
public static final String INCLUDES_ALLOW_REORDERING = "organizeIncludes.allowReordering"; //$NON-NLS-1$
/**
* Whether indirect inclusion through a partner header file is allowed.
*
* @since 5.7
*/
public static final String INCLUDES_ALLOW_PARTNER_INDIRECT_INCLUSION = "organizeIncludes.allowPartnerIndirectInclusion"; //$NON-NLS-1$
/**
* Determines what should be done with any unused include directives and forward declarations.
* This preference may have one of the three values defined by
@ -2048,6 +2055,15 @@ public class PreferenceConstants {
*/
public static final String INCLUDES_UNUSED_STATEMENTS_DISPOSITION = "organizeIncludes.unusedStatements"; //$NON-NLS-1$
/**
* Header file substitution rules.
* The value of the preference is an XML representation of one or more
* {@link org.eclipse.cdt.internal.ui.refactoring.includes.HeaderSubstitutionMap}s.
*
* @since 5.7
*/
public static final String INCLUDES_HEADER_SUBSTITUTION = "organizeIncludes.headerSubstitution"; //$NON-NLS-1$
/**
* Include style for headers closely related to the including file.
* The value of the preference is an XML representation of