mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
23540: Macro expansion exploration
This commit is contained in:
parent
df87215071
commit
13bad2303e
9 changed files with 1197 additions and 483 deletions
|
@ -0,0 +1,436 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 Wind River Systems, 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:
|
||||||
|
* Anton Leherbauer (Wind River Systems) - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.ui.text;
|
||||||
|
|
||||||
|
import org.eclipse.compare.CompareConfiguration;
|
||||||
|
import org.eclipse.compare.CompareUI;
|
||||||
|
import org.eclipse.compare.structuremergeviewer.ICompareInput;
|
||||||
|
import org.eclipse.jface.action.IMenuManager;
|
||||||
|
import org.eclipse.jface.dialogs.IDialogSettings;
|
||||||
|
import org.eclipse.jface.dialogs.PopupDialog;
|
||||||
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
|
import org.eclipse.jface.preference.PreferenceConverter;
|
||||||
|
import org.eclipse.jface.text.IInformationControl;
|
||||||
|
import org.eclipse.jface.text.IInformationControlExtension;
|
||||||
|
import org.eclipse.jface.text.IInformationControlExtension2;
|
||||||
|
import org.eclipse.jface.viewers.Viewer;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.custom.ViewForm;
|
||||||
|
import org.eclipse.swt.events.DisposeEvent;
|
||||||
|
import org.eclipse.swt.events.DisposeListener;
|
||||||
|
import org.eclipse.swt.events.FocusListener;
|
||||||
|
import org.eclipse.swt.events.KeyEvent;
|
||||||
|
import org.eclipse.swt.events.KeyListener;
|
||||||
|
import org.eclipse.swt.graphics.Color;
|
||||||
|
import org.eclipse.swt.graphics.Point;
|
||||||
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract class for "quick" compare views in light-weight controls.
|
||||||
|
*
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
public abstract class AbstractCompareViewerInformationControl extends PopupDialog implements IInformationControl, IInformationControlExtension, IInformationControlExtension2, DisposeListener {
|
||||||
|
|
||||||
|
protected class CompareViewerControl extends ViewForm {
|
||||||
|
private CompareConfiguration fCompareConfiguration;
|
||||||
|
private Viewer fViewer;
|
||||||
|
public CompareViewerControl(Composite parent, int styles, CompareConfiguration cc) {
|
||||||
|
super(parent, styles & ~SWT.BORDER);
|
||||||
|
verticalSpacing= 0;
|
||||||
|
fCompareConfiguration= cc;
|
||||||
|
}
|
||||||
|
public CompareConfiguration getCompareConfiguration() {
|
||||||
|
return fCompareConfiguration;
|
||||||
|
}
|
||||||
|
public void setInput(ICompareInput input) {
|
||||||
|
if (fViewer == null) {
|
||||||
|
fViewer= createContentViewer(this, input, fCompareConfiguration);
|
||||||
|
applyBackgroundColor(fBackgroundColor, fViewer.getControl());
|
||||||
|
setContent(fViewer.getControl());
|
||||||
|
}
|
||||||
|
fViewer.setInput(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int fStyle;
|
||||||
|
|
||||||
|
private CompareViewerControl fCompareViewerControl;
|
||||||
|
private ICompareInput fCompareInput;
|
||||||
|
|
||||||
|
private Color fBackgroundColor;
|
||||||
|
private boolean fIsSystemBackgroundColor;
|
||||||
|
|
||||||
|
private int fMaxWidth;
|
||||||
|
private int fMaxHeight;
|
||||||
|
|
||||||
|
private boolean fUseDefaultBounds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a source viewer information control with the given shell as parent. The given
|
||||||
|
* styles are applied to the shell and the source viewer.
|
||||||
|
*
|
||||||
|
* @param parent the parent shell
|
||||||
|
* @param shellStyle the additional styles for the shell
|
||||||
|
* @param textStyle the additional styles for the source viewer
|
||||||
|
* @param takeFocus flag indicating whether to take the focus
|
||||||
|
* @param showViewMenu flag indicating whether to show the "view" menu
|
||||||
|
* @param persistBounds flag indicating whether control size and location should be persisted
|
||||||
|
*/
|
||||||
|
public AbstractCompareViewerInformationControl(Shell parent, int shellStyle, int textStyle, boolean takeFocus, boolean showViewMenu, boolean persistBounds) {
|
||||||
|
super(parent, shellStyle, takeFocus, persistBounds, showViewMenu, false, null, null);
|
||||||
|
fStyle= textStyle & ~(SWT.V_SCROLL | SWT.H_SCROLL);
|
||||||
|
// Title and status text must be set to get the title label created, so force empty values here.
|
||||||
|
if (hasHeader())
|
||||||
|
setTitleText(""); //$NON-NLS-1$
|
||||||
|
setInfoText(""); // //$NON-NLS-1$
|
||||||
|
|
||||||
|
// Create all controls
|
||||||
|
create();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeColors() {
|
||||||
|
RGB bgRGB= getHoverBackgroundColorRGB();
|
||||||
|
if (bgRGB != null) {
|
||||||
|
fBackgroundColor= new Color(getShell().getDisplay(), bgRGB);
|
||||||
|
fIsSystemBackgroundColor= false;
|
||||||
|
} else {
|
||||||
|
fBackgroundColor= getShell().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND);
|
||||||
|
fIsSystemBackgroundColor= true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RGB getHoverBackgroundColorRGB() {
|
||||||
|
IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore();
|
||||||
|
return store.getBoolean(PreferenceConstants.EDITOR_SOURCE_HOVER_BACKGROUND_COLOR_SYSTEM_DEFAULT)
|
||||||
|
? null
|
||||||
|
: PreferenceConverter.getColor(store, PreferenceConstants.EDITOR_SOURCE_HOVER_BACKGROUND_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.dialogs.PopupDialog#createContents(org.eclipse.swt.widgets.Composite)
|
||||||
|
*/
|
||||||
|
protected Control createContents(Composite parent) {
|
||||||
|
initializeColors();
|
||||||
|
Control contents= super.createContents(parent);
|
||||||
|
applyBackgroundColor(fBackgroundColor, contents);
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void applyBackgroundColor(Color color, Control control) {
|
||||||
|
super.applyBackgroundColor(fBackgroundColor, control);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the main content for this information control.
|
||||||
|
*
|
||||||
|
* @param parent The parent composite
|
||||||
|
* @return The control representing the main content.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected Control createDialogArea(Composite parent) {
|
||||||
|
CompareConfiguration compareConfig= new CompareConfiguration();
|
||||||
|
compareConfig.setLeftEditable(false);
|
||||||
|
compareConfig.setRightEditable(false);
|
||||||
|
fCompareViewerControl= createCompareViewerControl(parent, fStyle, compareConfig);
|
||||||
|
|
||||||
|
final Control control= fCompareViewerControl;
|
||||||
|
control.addKeyListener(new KeyListener() {
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
if (e.character == 0x1B) // ESC
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
addDisposeListener(this);
|
||||||
|
return fCompareViewerControl;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CompareViewerControl createCompareViewerControl(Composite parent, int style, CompareConfiguration compareConfig) {
|
||||||
|
CompareViewerControl compareViewer= new CompareViewerControl(parent, style, compareConfig);
|
||||||
|
return compareViewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Viewer createContentViewer(Composite parent, ICompareInput input, CompareConfiguration cc) {
|
||||||
|
return CompareUI.findContentViewer(null, input, parent, cc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the dialog settings section.
|
||||||
|
* <p>
|
||||||
|
* The default is to return <code>null</code>.
|
||||||
|
* </p>
|
||||||
|
* @return the name of the dialog settings section or <code>null</code> if
|
||||||
|
* nothing should be persisted
|
||||||
|
*/
|
||||||
|
protected String getId() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the compare viewer.
|
||||||
|
*
|
||||||
|
* @return the compare viewer.
|
||||||
|
*/
|
||||||
|
protected final CompareViewerControl getCompareViewer() {
|
||||||
|
return fCompareViewerControl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the compare configuration.
|
||||||
|
*
|
||||||
|
* @return the compare configuration.
|
||||||
|
*/
|
||||||
|
protected final CompareConfiguration getCompareConfiguration() {
|
||||||
|
return fCompareViewerControl.getCompareConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the control has a header, <code>false</code> otherwise.
|
||||||
|
* <p>
|
||||||
|
* The default is to return <code>false</code>.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the control has a header
|
||||||
|
*/
|
||||||
|
protected boolean hasHeader() {
|
||||||
|
// default is to have no header
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void setInformation(String content) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void setInput(Object input) {
|
||||||
|
if (input instanceof ICompareInput) {
|
||||||
|
fCompareInput= (ICompareInput) input;
|
||||||
|
if (fCompareViewerControl != null) {
|
||||||
|
fCompareViewerControl.setInput(fCompareInput);
|
||||||
|
}
|
||||||
|
} else if (input instanceof String) {
|
||||||
|
// do nothing
|
||||||
|
} else {
|
||||||
|
fCompareInput= null;
|
||||||
|
if (fCompareViewerControl != null) {
|
||||||
|
fCompareViewerControl.setInput(fCompareInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills the view menu.
|
||||||
|
* Clients can extend or override.
|
||||||
|
*
|
||||||
|
* @param viewMenu the menu manager that manages the menu
|
||||||
|
*/
|
||||||
|
protected void fillViewMenu(IMenuManager viewMenu) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.dialogs.PopupDialog#fillDialogMenu(IMenuManager)
|
||||||
|
*/
|
||||||
|
protected void fillDialogMenu(IMenuManager dialogMenu) {
|
||||||
|
super.fillDialogMenu(dialogMenu);
|
||||||
|
fillViewMenu(dialogMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void setVisible(boolean visible) {
|
||||||
|
if (visible) {
|
||||||
|
open();
|
||||||
|
} else {
|
||||||
|
saveDialogBounds(getShell());
|
||||||
|
getShell().setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public final void dispose() {
|
||||||
|
if (!fIsSystemBackgroundColor) {
|
||||||
|
fBackgroundColor.dispose();
|
||||||
|
}
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Point getInitialLocation(Point initialSize) {
|
||||||
|
if (!getPersistBounds()) {
|
||||||
|
Point size = new Point(400, 400);
|
||||||
|
Rectangle parentBounds = getParentShell().getBounds();
|
||||||
|
int x = parentBounds.x + parentBounds.width / 2 - size.x / 2;
|
||||||
|
int y = parentBounds.y + parentBounds.height / 2 - size.y / 2;
|
||||||
|
return new Point(x, y);
|
||||||
|
}
|
||||||
|
return super.getInitialLocation(initialSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @param event can be null
|
||||||
|
* <p>
|
||||||
|
* Subclasses may extend.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public void widgetDisposed(DisposeEvent event) {
|
||||||
|
fCompareViewerControl= null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public boolean hasContents() {
|
||||||
|
return fCompareViewerControl != null && fCompareInput != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void setSizeConstraints(int maxWidth, int maxHeight) {
|
||||||
|
fMaxWidth= maxWidth;
|
||||||
|
fMaxHeight= maxHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public Point computeSizeHint() {
|
||||||
|
// compute the preferred size
|
||||||
|
int x= SWT.DEFAULT;
|
||||||
|
int y= SWT.DEFAULT;
|
||||||
|
Point size= getShell().computeSize(x, y);
|
||||||
|
if (size.x > fMaxWidth)
|
||||||
|
x= fMaxWidth;
|
||||||
|
if (size.y > fMaxHeight)
|
||||||
|
y= fMaxHeight;
|
||||||
|
|
||||||
|
// recompute using the constraints if the preferred size is larger than the constraints
|
||||||
|
if (x != SWT.DEFAULT || y != SWT.DEFAULT)
|
||||||
|
size= getShell().computeSize(x, y, false);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void setLocation(Point location) {
|
||||||
|
if (!getPersistBounds() || getDialogSettings() == null || fUseDefaultBounds)
|
||||||
|
getShell().setLocation(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void setSize(int width, int height) {
|
||||||
|
if (!getPersistBounds() || getDialogSettings() == null || fUseDefaultBounds) {
|
||||||
|
getShell().setSize(width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void addDisposeListener(DisposeListener listener) {
|
||||||
|
getShell().addDisposeListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void removeDisposeListener(DisposeListener listener) {
|
||||||
|
getShell().removeDisposeListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void setForegroundColor(Color foreground) {
|
||||||
|
applyForegroundColor(foreground, getContents());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void setBackgroundColor(Color background) {
|
||||||
|
applyBackgroundColor(background, getContents());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.dialogs.PopupDialog#getFocusControl()
|
||||||
|
*/
|
||||||
|
protected Control getFocusControl() {
|
||||||
|
return fCompareViewerControl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public boolean isFocusControl() {
|
||||||
|
return fCompareViewerControl.isFocusControl();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void setFocus() {
|
||||||
|
getShell().forceFocus();
|
||||||
|
fCompareViewerControl.setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void addFocusListener(FocusListener listener) {
|
||||||
|
getShell().addFocusListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void removeFocusListener(FocusListener listener) {
|
||||||
|
getShell().removeFocusListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.dialogs.PopupDialog#getDialogSettings()
|
||||||
|
*/
|
||||||
|
protected IDialogSettings getDialogSettings() {
|
||||||
|
String sectionName= getId();
|
||||||
|
if (sectionName == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
IDialogSettings settings= CUIPlugin.getDefault().getDialogSettings().getSection(sectionName);
|
||||||
|
if (settings == null) {
|
||||||
|
fUseDefaultBounds= true;
|
||||||
|
settings= CUIPlugin.getDefault().getDialogSettings().addNewSection(sectionName);
|
||||||
|
}
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2007 Wind River Systems, Inc. and others.
|
* Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -52,9 +52,9 @@ import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
import org.eclipse.cdt.internal.ui.editor.CSourceViewer;
|
import org.eclipse.cdt.internal.ui.editor.CSourceViewer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class for "quick" views in light-weight controls.
|
* Abstract class for "quick" source views in light-weight controls.
|
||||||
*
|
*
|
||||||
* @since 4.0
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractSourceViewerInformationControl extends PopupDialog implements IInformationControl, IInformationControlExtension, IInformationControlExtension2, DisposeListener {
|
public abstract class AbstractSourceViewerInformationControl extends PopupDialog implements IInformationControl, IInformationControlExtension, IInformationControlExtension2, DisposeListener {
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
CMacroExpansionControl_statusText=Press {0} or {1} to step through macro expansion
|
CMacroExpansionControl_statusText=Press {0} or {1} to step through macro expansion
|
||||||
CMacroExpansionControl_title_expansion=Expansion \#{0) of {1}
|
CMacroExpansionControl_title_expansion=Expansion \#{0} of {1}
|
||||||
CMacroExpansionControl_title_fullyExpanded=Fully Expanded
|
CMacroExpansionControl_title_fullyExpanded=Fully Expanded
|
||||||
CMacroExpansionControl_title_macroExpansion=Macro Expansion
|
CMacroExpansionControl_title_macroExpansion=Macro Expansion
|
||||||
CMacroExpansionControl_title_original=Original
|
CMacroExpansionControl_title_original=Original
|
||||||
|
|
|
@ -33,8 +33,9 @@ import org.eclipse.cdt.internal.ui.text.HTMLTextPresenter;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides information for the current word under the cursor based on available hovers.
|
* Provides information for the current word under the cursor based on the documentation hover.
|
||||||
*
|
*
|
||||||
|
* @see CDocHover
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
public class CInformationProvider implements IInformationProvider, IInformationProviderExtension2 {
|
public class CInformationProvider implements IInformationProvider, IInformationProviderExtension2 {
|
||||||
|
@ -91,7 +92,7 @@ public class CInformationProvider implements IInformationProvider, IInformationP
|
||||||
fPartListener= new EditorWatcher();
|
fPartListener= new EditorWatcher();
|
||||||
IWorkbenchWindow window= fEditor.getSite().getWorkbenchWindow();
|
IWorkbenchWindow window= fEditor.getSite().getWorkbenchWindow();
|
||||||
window.getPartService().addPartListener(fPartListener);
|
window.getPartService().addPartListener(fPartListener);
|
||||||
fImplementation= new BestMatchHover();
|
fImplementation= new CDocHover();
|
||||||
fImplementation.setEditor(fEditor);
|
fImplementation.setEditor(fEditor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,290 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, 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:
|
||||||
|
* Anton Leherbauer (Wind River Systems) - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.internal.ui.text.c.hover;
|
||||||
|
|
||||||
|
import org.eclipse.compare.CompareConfiguration;
|
||||||
|
import org.eclipse.compare.contentmergeviewer.ITokenComparator;
|
||||||
|
import org.eclipse.compare.rangedifferencer.IRangeComparator;
|
||||||
|
import org.eclipse.jface.action.IToolBarManager;
|
||||||
|
import org.eclipse.jface.resource.JFaceResources;
|
||||||
|
import org.eclipse.jface.text.ITextPresentationListener;
|
||||||
|
import org.eclipse.jface.text.TextPresentation;
|
||||||
|
import org.eclipse.jface.text.TextViewer;
|
||||||
|
import org.eclipse.swt.custom.StyleRange;
|
||||||
|
import org.eclipse.swt.events.DisposeEvent;
|
||||||
|
import org.eclipse.swt.graphics.Color;
|
||||||
|
import org.eclipse.swt.graphics.Font;
|
||||||
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.text.edits.ReplaceEdit;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.rewrite.MacroExpansionExplorer.IMacroExpansionStep;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.compare.CMergeViewer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A viewer for comparison of macro expansions.
|
||||||
|
*
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
class CMacroCompareViewer extends CMergeViewer {
|
||||||
|
|
||||||
|
private static final RGB CHANGE_COLOR= new RGB(212,212,212);
|
||||||
|
|
||||||
|
private class ReplaceEditsHighlighter implements ITextPresentationListener {
|
||||||
|
private boolean fBefore;
|
||||||
|
private int[] fStarts;
|
||||||
|
private int[] fLengths;
|
||||||
|
private Color fBackground;
|
||||||
|
|
||||||
|
public ReplaceEditsHighlighter(Color background, boolean before) {
|
||||||
|
fBackground= background;
|
||||||
|
fBefore= before;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReplaceEdits(ReplaceEdit[] edits) {
|
||||||
|
int[] deltas= new int[edits.length];
|
||||||
|
if (fBefore) {
|
||||||
|
for (int i= 1; i < edits.length; i++) {
|
||||||
|
ReplaceEdit edit= edits[i-1];
|
||||||
|
deltas[i]= deltas[i-1] + (edit.getText().length() - edit.getLength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fStarts= new int[edits.length];
|
||||||
|
fLengths= new int[edits.length];
|
||||||
|
for (int i= 0; i < edits.length; i++) {
|
||||||
|
ReplaceEdit edit= edits[i];
|
||||||
|
fStarts[i]= edit.getOffset() + deltas[i];
|
||||||
|
fLengths[i]= fBefore ? edit.getLength() : edit.getText().length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.ITextPresentationListener#applyTextPresentation(org.eclipse.jface.text.TextPresentation)
|
||||||
|
*/
|
||||||
|
public void applyTextPresentation(TextPresentation textPresentation) {
|
||||||
|
for (int i = 0; i < fStarts.length; i++) {
|
||||||
|
textPresentation.mergeStyleRange(new StyleRange(fStarts[i], fLengths[i], null, fBackground));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// private class MacroExpansionComparator implements ITokenComparator {
|
||||||
|
//
|
||||||
|
// private final int[] fStarts;
|
||||||
|
// private final int[] fLengths;
|
||||||
|
// private int fCount;
|
||||||
|
//
|
||||||
|
// public MacroExpansionComparator(String text, ReplaceEdit[] edits, boolean before) {
|
||||||
|
// int[] deltas= new int[edits.length];
|
||||||
|
// if (before) {
|
||||||
|
// for (int i= 1; i < edits.length; i++) {
|
||||||
|
// ReplaceEdit edit= edits[i-1];
|
||||||
|
// deltas[i]= deltas[i-1] + (edit.getText().length() - edit.getLength());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// fStarts= new int[edits.length * 2 + 1];
|
||||||
|
// fLengths= new int[edits.length * 2 + 1];
|
||||||
|
// int offset= 0;
|
||||||
|
// int i= 0;
|
||||||
|
// for (; i < edits.length; i++) {
|
||||||
|
// if (offset >= text.length()) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// fStarts[2*i]= offset;
|
||||||
|
// ReplaceEdit edit= edits[i];
|
||||||
|
// fLengths[2*i]= edit.getOffset() + deltas[i] - offset;
|
||||||
|
// fStarts[2*i+1]= edit.getOffset() + deltas[i];
|
||||||
|
// fLengths[2*i+1]= before ? edit.getLength() : edit.getText().length();
|
||||||
|
// offset= fStarts[2*i+1] + fLengths[2*i+1];
|
||||||
|
// }
|
||||||
|
// fCount= 2*i;
|
||||||
|
//
|
||||||
|
// if (offset < text.length()) {
|
||||||
|
// fStarts[fCount]= offset;
|
||||||
|
// fLengths[fCount]= text.length() - offset;
|
||||||
|
// fCount++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /*
|
||||||
|
// * @see org.eclipse.compare.contentmergeviewer.ITokenComparator#getTokenLength(int)
|
||||||
|
// */
|
||||||
|
// public int getTokenLength(int index) {
|
||||||
|
// return fLengths[index];
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /*
|
||||||
|
// * @see org.eclipse.compare.contentmergeviewer.ITokenComparator#getTokenStart(int)
|
||||||
|
// */
|
||||||
|
// public int getTokenStart(int index) {
|
||||||
|
// return fStarts[index];
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /*
|
||||||
|
// * @see org.eclipse.compare.rangedifferencer.IRangeComparator#getRangeCount()
|
||||||
|
// */
|
||||||
|
// public int getRangeCount() {
|
||||||
|
// return fCount;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /*
|
||||||
|
// * @see org.eclipse.compare.rangedifferencer.IRangeComparator#rangesEqual(int, org.eclipse.compare.rangedifferencer.IRangeComparator, int)
|
||||||
|
// */
|
||||||
|
// public boolean rangesEqual(int thisIndex, IRangeComparator other, int otherIndex) {
|
||||||
|
// return thisIndex == otherIndex && thisIndex % 2 == 0;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /*
|
||||||
|
// * @see org.eclipse.compare.rangedifferencer.IRangeComparator#skipRangeComparison(int, int, org.eclipse.compare.rangedifferencer.IRangeComparator)
|
||||||
|
// */
|
||||||
|
// public boolean skipRangeComparison(int length, int maxLength, IRangeComparator other) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A dummy {@link ITokenComparator}.
|
||||||
|
*/
|
||||||
|
private static class NullTokenComparator implements ITokenComparator {
|
||||||
|
public int getTokenLength(int index) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
public int getTokenStart(int index) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
public int getRangeCount() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
public boolean rangesEqual(int thisIndex, IRangeComparator other, int otherIndex) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public boolean skipRangeComparison(int length, int maxLength, IRangeComparator other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextViewer fLeftViewer;
|
||||||
|
TextViewer fRightViewer;
|
||||||
|
TextViewer fTopViewer;
|
||||||
|
|
||||||
|
int fIndex;
|
||||||
|
private CMacroExpansionInput fInput;
|
||||||
|
private int fStepIndex;
|
||||||
|
private ReplaceEditsHighlighter fLeftHighlighter;
|
||||||
|
private ReplaceEditsHighlighter fRightHighlighter;
|
||||||
|
private Color fChangeBackground;
|
||||||
|
|
||||||
|
public CMacroCompareViewer(Composite parent, int styles, CompareConfiguration mp) {
|
||||||
|
super(parent, styles, mp);
|
||||||
|
Font font= JFaceResources.getFont(CMergeViewer.class.getName());
|
||||||
|
fLeftViewer.getTextWidget().setFont(font);
|
||||||
|
fRightViewer.getTextWidget().setFont(font);
|
||||||
|
fTopViewer.getTextWidget().setFont(font);
|
||||||
|
|
||||||
|
fChangeBackground= new Color(parent.getDisplay(), CHANGE_COLOR);
|
||||||
|
fLeftViewer.addTextPresentationListener(fLeftHighlighter= new ReplaceEditsHighlighter(fChangeBackground, true));
|
||||||
|
fRightViewer.addTextPresentationListener(fRightHighlighter= new ReplaceEditsHighlighter(fChangeBackground, false));
|
||||||
|
fIndex= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.cdt.internal.ui.compare.AbstractMergeViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
|
||||||
|
*/
|
||||||
|
protected void handleDispose(DisposeEvent event) {
|
||||||
|
fLeftViewer.removeTextPresentationListener(fLeftHighlighter);
|
||||||
|
fRightViewer.removeTextPresentationListener(fRightHighlighter);
|
||||||
|
fChangeBackground.dispose();
|
||||||
|
super.handleDispose(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IToolBarManager getToolBarManager(Composite parent) {
|
||||||
|
// no toolbar
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.cdt.internal.ui.compare.AbstractMergeViewer#configureTextViewer(org.eclipse.jface.text.TextViewer)
|
||||||
|
*/
|
||||||
|
protected void configureTextViewer(TextViewer textViewer) {
|
||||||
|
super.configureTextViewer(textViewer);
|
||||||
|
|
||||||
|
// hack: gain access to text viewers
|
||||||
|
switch (fIndex++) {
|
||||||
|
case 0:
|
||||||
|
fTopViewer= textViewer;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
fLeftViewer= textViewer;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
fRightViewer= textViewer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.compare.contentmergeviewer.TextMergeViewer#createTokenComparator(java.lang.String)
|
||||||
|
*/
|
||||||
|
protected ITokenComparator createTokenComparator(String line) {
|
||||||
|
// boolean before= fIndex++ % 2 != 0;
|
||||||
|
// final IMacroExpansionStep step;
|
||||||
|
// if (fStepIndex < fInput.fExplorer.getExpansionStepCount()) {
|
||||||
|
// step= fInput.fExplorer.getExpansionStep(fStepIndex);
|
||||||
|
// } else {
|
||||||
|
// before= !before;
|
||||||
|
// step= fInput.fExplorer.getFullExpansion();
|
||||||
|
// }
|
||||||
|
// return new MacroExpansionComparator(line, step.getReplacements(), before);
|
||||||
|
return new NullTokenComparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMacroExpansionInput(CMacroExpansionInput input) {
|
||||||
|
fInput= input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.viewers.ContentViewer#setInput(java.lang.Object)
|
||||||
|
*/
|
||||||
|
public void setInput(Object input) {
|
||||||
|
fLeftViewer.setRedraw(false);
|
||||||
|
fRightViewer.setRedraw(false);
|
||||||
|
|
||||||
|
final ReplaceEdit[] edits;
|
||||||
|
try {
|
||||||
|
if (fStepIndex < fInput.fExplorer.getExpansionStepCount()) {
|
||||||
|
final IMacroExpansionStep step;
|
||||||
|
step= fInput.fExplorer.getExpansionStep(fStepIndex);
|
||||||
|
edits= step.getReplacements();
|
||||||
|
} else {
|
||||||
|
edits= new ReplaceEdit[0];
|
||||||
|
}
|
||||||
|
fLeftHighlighter.setReplaceEdits(edits);
|
||||||
|
fRightHighlighter.setReplaceEdits(edits);
|
||||||
|
|
||||||
|
super.setInput(input);
|
||||||
|
} finally {
|
||||||
|
fLeftViewer.setRedraw(true);
|
||||||
|
fRightViewer.setRedraw(true);
|
||||||
|
}
|
||||||
|
if (edits.length > 0) {
|
||||||
|
fLeftViewer.revealRange(edits[0].getOffset(), edits[0].getLength());
|
||||||
|
fRightViewer.revealRange(edits[0].getOffset(), edits[0].getText().length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMacroExpansionStep(int index) {
|
||||||
|
fStepIndex= index;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2007 Wind River Systems, Inc. and others.
|
* Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -11,26 +11,8 @@
|
||||||
|
|
||||||
package org.eclipse.cdt.internal.ui.text.c.hover;
|
package org.eclipse.cdt.internal.ui.text.c.hover;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.eclipse.core.commands.AbstractHandler;
|
|
||||||
import org.eclipse.core.commands.ExecutionEvent;
|
|
||||||
import org.eclipse.core.commands.ExecutionException;
|
|
||||||
import org.eclipse.core.commands.IHandler;
|
|
||||||
import org.eclipse.jface.text.Document;
|
|
||||||
import org.eclipse.jface.text.IDocument;
|
|
||||||
import org.eclipse.osgi.util.NLS;
|
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.widgets.Shell;
|
import org.eclipse.swt.widgets.Shell;
|
||||||
import org.eclipse.ui.IWorkbench;
|
|
||||||
import org.eclipse.ui.PlatformUI;
|
|
||||||
import org.eclipse.ui.contexts.IContextActivation;
|
|
||||||
import org.eclipse.ui.contexts.IContextService;
|
|
||||||
import org.eclipse.ui.handlers.IHandlerService;
|
|
||||||
import org.eclipse.ui.keys.IBindingService;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.text.AbstractSourceViewerInformationControl;
|
import org.eclipse.cdt.internal.ui.text.AbstractSourceViewerInformationControl;
|
||||||
|
|
||||||
|
@ -41,30 +23,6 @@ import org.eclipse.cdt.internal.ui.text.AbstractSourceViewerInformationControl;
|
||||||
*/
|
*/
|
||||||
public class CMacroExpansionControl extends AbstractSourceViewerInformationControl {
|
public class CMacroExpansionControl extends AbstractSourceViewerInformationControl {
|
||||||
|
|
||||||
private static final String COMMAND_ID_EXPANSION_BACK= "org.eclipse.cdt.ui.hover.backwardMacroExpansion"; //$NON-NLS-1$
|
|
||||||
private static final String COMMAND_ID_EXPANSION_FORWARD= "org.eclipse.cdt.ui.hover.forwardMacroExpansion"; //$NON-NLS-1$
|
|
||||||
private static final String CONTEXT_ID_MACRO_EXPANSION_HOVER= "org.eclipse.cdt.ui.macroExpansionHoverScope"; //$NON-NLS-1$
|
|
||||||
|
|
||||||
private IHandlerService fHandlerService;
|
|
||||||
private Collection fHandlerActivations;
|
|
||||||
private IContextService fContextService;
|
|
||||||
private IContextActivation fContextActivation;
|
|
||||||
private int fIndex;
|
|
||||||
private CMacroExpansionInput fInput;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new control for use as a "quick view" where the control immediately takes the focus.
|
|
||||||
*
|
|
||||||
* @param parent parent shell
|
|
||||||
* @param shellStyle shell style bits
|
|
||||||
* @param style text viewer style bits
|
|
||||||
* @param input the input object, may be <code>null</code>
|
|
||||||
*/
|
|
||||||
public CMacroExpansionControl(Shell parent, int shellStyle, int style, CMacroExpansionInput input) {
|
|
||||||
super(parent, shellStyle, style, true, false, true);
|
|
||||||
setMacroExpansionInput(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new control for use as a hover which does not take the focus.
|
* Creates a new control for use as a hover which does not take the focus.
|
||||||
*
|
*
|
||||||
|
@ -86,93 +44,6 @@ public class CMacroExpansionControl extends AbstractSourceViewerInformationContr
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @see org.eclipse.jface.dialogs.PopupDialog#open()
|
|
||||||
*/
|
|
||||||
public int open() {
|
|
||||||
int result= super.open();
|
|
||||||
|
|
||||||
if (fInput != null) {
|
|
||||||
IHandler fBackwardHandler= new AbstractHandler() {
|
|
||||||
public Object execute(ExecutionEvent event) throws ExecutionException {
|
|
||||||
backward();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
IHandler fForwardHandler= new AbstractHandler() {
|
|
||||||
public Object execute(ExecutionEvent event) throws ExecutionException {
|
|
||||||
forward();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
IWorkbench workbench= PlatformUI.getWorkbench();
|
|
||||||
fHandlerService= (IHandlerService) workbench.getService(IHandlerService.class);
|
|
||||||
fContextService= (IContextService) workbench.getService(IContextService.class);
|
|
||||||
fContextActivation= fContextService.activateContext(CONTEXT_ID_MACRO_EXPANSION_HOVER);
|
|
||||||
fHandlerActivations= new ArrayList();
|
|
||||||
fHandlerActivations.add(fHandlerService.activateHandler(COMMAND_ID_EXPANSION_BACK, fBackwardHandler));
|
|
||||||
fHandlerActivations.add(fHandlerService.activateHandler(COMMAND_ID_EXPANSION_FORWARD, fForwardHandler));
|
|
||||||
|
|
||||||
String infoText= getInfoText();
|
|
||||||
if (infoText != null) {
|
|
||||||
setInfoText(infoText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void forward() {
|
|
||||||
++fIndex;
|
|
||||||
if (fIndex >= fInput.fExpansions.length) {
|
|
||||||
fIndex= 0;
|
|
||||||
}
|
|
||||||
showExpansion(fIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void backward() {
|
|
||||||
--fIndex;
|
|
||||||
if (fIndex < 0) {
|
|
||||||
fIndex += fInput.fExpansions.length;
|
|
||||||
}
|
|
||||||
showExpansion(fIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the text to be shown in the popups's information area.
|
|
||||||
* May return <code>null</code>.
|
|
||||||
*
|
|
||||||
* @return The text to be shown in the popup's information area or <code>null</code>
|
|
||||||
*/
|
|
||||||
protected String getInfoText() {
|
|
||||||
IWorkbench workbench= PlatformUI.getWorkbench();
|
|
||||||
IBindingService bindingService= (IBindingService) workbench.getService(IBindingService.class);
|
|
||||||
String formattedBindingBack= bindingService.getBestActiveBindingFormattedFor(COMMAND_ID_EXPANSION_BACK);
|
|
||||||
String formattedBindingForward= bindingService.getBestActiveBindingFormattedFor(COMMAND_ID_EXPANSION_FORWARD);
|
|
||||||
|
|
||||||
String infoText= null;
|
|
||||||
if (formattedBindingBack != null && formattedBindingForward != null) {
|
|
||||||
infoText= NLS.bind(CHoverMessages.CMacroExpansionControl_statusText, formattedBindingBack, formattedBindingForward);
|
|
||||||
}
|
|
||||||
return infoText;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see org.eclipse.jface.dialogs.PopupDialog#close()
|
|
||||||
*/
|
|
||||||
public boolean close() {
|
|
||||||
if (fHandlerService != null) {
|
|
||||||
fHandlerService.deactivateHandlers(fHandlerActivations);
|
|
||||||
fHandlerActivations.clear();
|
|
||||||
fHandlerService= null;
|
|
||||||
}
|
|
||||||
if (fContextActivation != null) {
|
|
||||||
fContextService.deactivateContext(fContextActivation);
|
|
||||||
}
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @see org.eclipse.cdt.internal.ui.text.AbstractSourceViewerInformationControl#getId()
|
* @see org.eclipse.cdt.internal.ui.text.AbstractSourceViewerInformationControl#getId()
|
||||||
*/
|
*/
|
||||||
|
@ -180,45 +51,4 @@ public class CMacroExpansionControl extends AbstractSourceViewerInformationContr
|
||||||
return "org.eclipse.cdt.ui.text.hover.CMacroExpansion"; //$NON-NLS-1$
|
return "org.eclipse.cdt.ui.text.hover.CMacroExpansion"; //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @see org.eclipse.cdt.internal.ui.text.AbstractSourceViewerInformationControl#setInput(java.lang.Object)
|
|
||||||
*/
|
|
||||||
public void setInput(Object input) {
|
|
||||||
if (input instanceof String && fInput == null) {
|
|
||||||
super.setInput(input);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (input instanceof CMacroExpansionInput) {
|
|
||||||
setMacroExpansionInput((CMacroExpansionInput) input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the input for this information control.
|
|
||||||
* @param input
|
|
||||||
*/
|
|
||||||
private void setMacroExpansionInput(CMacroExpansionInput input) {
|
|
||||||
fInput= input;
|
|
||||||
fIndex= input.fExpansions.length - 1;
|
|
||||||
showExpansion(fIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showExpansion(int index) {
|
|
||||||
if (fIndex == 0) {
|
|
||||||
setTitleText(CHoverMessages.CMacroExpansionControl_title_original);
|
|
||||||
} else if (fIndex < fInput.fExpansions.length - 1) {
|
|
||||||
setTitleText(NLS.bind(CHoverMessages.CMacroExpansionControl_title_expansion,
|
|
||||||
String.valueOf(fIndex), String.valueOf(fInput.fExpansions.length - 1)));
|
|
||||||
} else {
|
|
||||||
setTitleText(CHoverMessages.CMacroExpansionControl_title_fullyExpanded);
|
|
||||||
}
|
|
||||||
IDocument document= getSourceViewer().getDocument();
|
|
||||||
if (document == null) {
|
|
||||||
document= new Document(fInput.fExpansions[index]);
|
|
||||||
CUIPlugin.getDefault().getTextTools().setupCDocument(document);
|
|
||||||
getSourceViewer().setDocument(document);
|
|
||||||
} else {
|
|
||||||
document.set(fInput.fExpansions[index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,360 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 Wind River Systems, 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:
|
||||||
|
* Anton Leherbauer (Wind River Systems) - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.internal.ui.text.c.hover;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.eclipse.compare.CompareConfiguration;
|
||||||
|
import org.eclipse.compare.ITypedElement;
|
||||||
|
import org.eclipse.compare.Splitter;
|
||||||
|
import org.eclipse.compare.structuremergeviewer.Differencer;
|
||||||
|
import org.eclipse.compare.structuremergeviewer.DocumentRangeNode;
|
||||||
|
import org.eclipse.compare.structuremergeviewer.ICompareInput;
|
||||||
|
import org.eclipse.core.commands.AbstractHandler;
|
||||||
|
import org.eclipse.core.commands.ExecutionEvent;
|
||||||
|
import org.eclipse.core.commands.ExecutionException;
|
||||||
|
import org.eclipse.core.commands.IHandler;
|
||||||
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
|
import org.eclipse.jface.resource.JFaceResources;
|
||||||
|
import org.eclipse.jface.text.Document;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.source.ISourceViewer;
|
||||||
|
import org.eclipse.jface.text.source.SourceViewer;
|
||||||
|
import org.eclipse.jface.viewers.Viewer;
|
||||||
|
import org.eclipse.osgi.util.NLS;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.custom.StyledText;
|
||||||
|
import org.eclipse.swt.graphics.Font;
|
||||||
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
import org.eclipse.ui.IWorkbench;
|
||||||
|
import org.eclipse.ui.PlatformUI;
|
||||||
|
import org.eclipse.ui.contexts.IContextActivation;
|
||||||
|
import org.eclipse.ui.contexts.IContextService;
|
||||||
|
import org.eclipse.ui.handlers.IHandlerService;
|
||||||
|
import org.eclipse.ui.keys.IBindingService;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.editor.CSourceViewer;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.AbstractCompareViewerInformationControl;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.CTextTools;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.SimpleCSourceViewerConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information control for macro expansion exploration.
|
||||||
|
*
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
public class CMacroExpansionExplorationControl extends AbstractCompareViewerInformationControl {
|
||||||
|
|
||||||
|
private static final String COMMAND_ID_EXPANSION_BACK= "org.eclipse.cdt.ui.hover.backwardMacroExpansion"; //$NON-NLS-1$
|
||||||
|
private static final String COMMAND_ID_EXPANSION_FORWARD= "org.eclipse.cdt.ui.hover.forwardMacroExpansion"; //$NON-NLS-1$
|
||||||
|
private static final String CONTEXT_ID_MACRO_EXPANSION_HOVER= "org.eclipse.cdt.ui.macroExpansionHoverScope"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private static class CDiffNode extends DocumentRangeNode implements ITypedElement {
|
||||||
|
public CDiffNode(DocumentRangeNode parent, int type, String id, IDocument doc, int start, int length) {
|
||||||
|
super(parent, type, id, doc, start, length);
|
||||||
|
}
|
||||||
|
public CDiffNode(int type, String id, IDocument doc, int start, int length) {
|
||||||
|
super(type, id, doc, start, length);
|
||||||
|
}
|
||||||
|
public String getName() {
|
||||||
|
return getId();
|
||||||
|
}
|
||||||
|
public String getType() {
|
||||||
|
return "c2"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
public Image getImage() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IHandlerService fHandlerService;
|
||||||
|
private Collection fHandlerActivations;
|
||||||
|
private IContextService fContextService;
|
||||||
|
private IContextActivation fContextActivation;
|
||||||
|
private int fIndex;
|
||||||
|
private CMacroExpansionInput fInput;
|
||||||
|
private CMacroCompareViewer fMacroCompareViewer;
|
||||||
|
private ISourceViewer fMacroViewer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new control for use as a "quick view" where the control immediately takes the focus.
|
||||||
|
*
|
||||||
|
* @param parent parent shell
|
||||||
|
* @param shellStyle shell style bits
|
||||||
|
* @param style text viewer style bits
|
||||||
|
* @param input the input object, may be <code>null</code>
|
||||||
|
*/
|
||||||
|
public CMacroExpansionExplorationControl(Shell parent, int shellStyle, int style, CMacroExpansionInput input) {
|
||||||
|
super(parent, shellStyle, style, true, true, true);
|
||||||
|
setMacroExpansionInput(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.cdt.internal.ui.text.AbstractSourceViewerInformationControl#hasHeader()
|
||||||
|
*/
|
||||||
|
protected boolean hasHeader() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.cdt.internal.ui.text.AbstractCompareViewerInformationControl#createCompareViewerControl(org.eclipse.swt.widgets.Composite, int, org.eclipse.compare.CompareConfiguration)
|
||||||
|
*/
|
||||||
|
protected CompareViewerControl createCompareViewerControl(Composite parent, int style, CompareConfiguration compareConfig) {
|
||||||
|
Splitter splitter= new Splitter(parent, SWT.VERTICAL);
|
||||||
|
splitter.setLayoutData(new GridData(GridData.FILL_BOTH));
|
||||||
|
fMacroViewer= createSourceViewer(splitter, style | SWT.V_SCROLL | SWT.H_SCROLL);
|
||||||
|
CompareViewerControl control= super.createCompareViewerControl(splitter, style, compareConfig);
|
||||||
|
splitter.setWeights(new int[] { 30, 70 });
|
||||||
|
return control;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.cdt.internal.ui.text.AbstractCompareViewerInformationControl#createContentViewer(org.eclipse.swt.widgets.Composite, org.eclipse.compare.structuremergeviewer.ICompareInput, org.eclipse.compare.CompareConfiguration)
|
||||||
|
*/
|
||||||
|
protected Viewer createContentViewer(Composite parent, ICompareInput input, CompareConfiguration cc) {
|
||||||
|
fMacroCompareViewer= new CMacroCompareViewer(parent, SWT.NULL, cc);
|
||||||
|
if (fInput != null) {
|
||||||
|
fMacroCompareViewer.setMacroExpansionInput(fInput);
|
||||||
|
fMacroCompareViewer.setMacroExpansionStep(fIndex);
|
||||||
|
}
|
||||||
|
return fMacroCompareViewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ISourceViewer createSourceViewer(Composite parent, int style) {
|
||||||
|
IPreferenceStore store= CUIPlugin.getDefault().getCombinedPreferenceStore();
|
||||||
|
SourceViewer sourceViewer= new CSourceViewer(parent, null, null, false, style, store);
|
||||||
|
CTextTools tools= CUIPlugin.getDefault().getTextTools();
|
||||||
|
sourceViewer.configure(new SimpleCSourceViewerConfiguration(tools.getColorManager(), store, null, ICPartitions.C_PARTITIONING, false));
|
||||||
|
sourceViewer.setEditable(false);
|
||||||
|
|
||||||
|
StyledText styledText= sourceViewer.getTextWidget();
|
||||||
|
|
||||||
|
Font font= JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT);
|
||||||
|
styledText.setFont(font);
|
||||||
|
|
||||||
|
GridData gd= new GridData(GridData.BEGINNING | GridData.FILL_BOTH);
|
||||||
|
gd.heightHint= styledText.getLineHeight() * 2;
|
||||||
|
styledText.setLayoutData(gd);
|
||||||
|
styledText.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
|
||||||
|
|
||||||
|
final Document doc= new Document();
|
||||||
|
CUIPlugin.getDefault().getTextTools().setupCDocument(doc);
|
||||||
|
sourceViewer.setDocument(doc);
|
||||||
|
return sourceViewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.dialogs.PopupDialog#open()
|
||||||
|
*/
|
||||||
|
public int open() {
|
||||||
|
int result= super.open();
|
||||||
|
|
||||||
|
if (fInput != null) {
|
||||||
|
IHandler fBackwardHandler= new AbstractHandler() {
|
||||||
|
public Object execute(ExecutionEvent event) throws ExecutionException {
|
||||||
|
backward();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
IHandler fForwardHandler= new AbstractHandler() {
|
||||||
|
public Object execute(ExecutionEvent event) throws ExecutionException {
|
||||||
|
forward();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
IWorkbench workbench= PlatformUI.getWorkbench();
|
||||||
|
fHandlerService= (IHandlerService) workbench.getService(IHandlerService.class);
|
||||||
|
fContextService= (IContextService) workbench.getService(IContextService.class);
|
||||||
|
fContextActivation= fContextService.activateContext(CONTEXT_ID_MACRO_EXPANSION_HOVER);
|
||||||
|
fHandlerActivations= new ArrayList();
|
||||||
|
fHandlerActivations.add(fHandlerService.activateHandler(COMMAND_ID_EXPANSION_BACK, fBackwardHandler));
|
||||||
|
fHandlerActivations.add(fHandlerService.activateHandler(COMMAND_ID_EXPANSION_FORWARD, fForwardHandler));
|
||||||
|
|
||||||
|
String infoText= getInfoText();
|
||||||
|
if (infoText != null) {
|
||||||
|
setInfoText(infoText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void forward() {
|
||||||
|
++fIndex;
|
||||||
|
if (fIndex > fInput.fExplorer.getExpansionStepCount()) {
|
||||||
|
fIndex= 0;
|
||||||
|
}
|
||||||
|
showExpansion();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void backward() {
|
||||||
|
--fIndex;
|
||||||
|
if (fIndex < 0) {
|
||||||
|
fIndex = fInput.fExplorer.getExpansionStepCount();
|
||||||
|
}
|
||||||
|
showExpansion();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the text to be shown in the popups's information area.
|
||||||
|
* May return <code>null</code>.
|
||||||
|
*
|
||||||
|
* @return The text to be shown in the popup's information area or <code>null</code>
|
||||||
|
*/
|
||||||
|
private String getInfoText() {
|
||||||
|
IWorkbench workbench= PlatformUI.getWorkbench();
|
||||||
|
IBindingService bindingService= (IBindingService) workbench.getService(IBindingService.class);
|
||||||
|
String formattedBindingBack= bindingService.getBestActiveBindingFormattedFor(COMMAND_ID_EXPANSION_BACK);
|
||||||
|
String formattedBindingForward= bindingService.getBestActiveBindingFormattedFor(COMMAND_ID_EXPANSION_FORWARD);
|
||||||
|
|
||||||
|
String infoText= null;
|
||||||
|
if (formattedBindingBack != null && formattedBindingForward != null) {
|
||||||
|
infoText= NLS.bind(CHoverMessages.CMacroExpansionControl_statusText, formattedBindingBack, formattedBindingForward);
|
||||||
|
}
|
||||||
|
return infoText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.dialogs.PopupDialog#close()
|
||||||
|
*/
|
||||||
|
public boolean close() {
|
||||||
|
if (fHandlerService != null) {
|
||||||
|
fHandlerService.deactivateHandlers(fHandlerActivations);
|
||||||
|
fHandlerActivations.clear();
|
||||||
|
fHandlerService= null;
|
||||||
|
}
|
||||||
|
if (fContextActivation != null) {
|
||||||
|
fContextService.deactivateContext(fContextActivation);
|
||||||
|
}
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.cdt.internal.ui.text.AbstractCompareViewerInformationControl#getId()
|
||||||
|
*/
|
||||||
|
protected String getId() {
|
||||||
|
return "org.eclipse.cdt.ui.text.hover.CMacroExpansionExploration"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.cdt.internal.ui.text.AbstractCompareViewerInformationControl#setInput(java.lang.Object)
|
||||||
|
*/
|
||||||
|
public void setInput(Object input) {
|
||||||
|
if (input instanceof CMacroExpansionInput) {
|
||||||
|
setMacroExpansionInput((CMacroExpansionInput) input);
|
||||||
|
} else {
|
||||||
|
if (fMacroCompareViewer != null) {
|
||||||
|
fMacroCompareViewer.setMacroExpansionStep(fIndex);
|
||||||
|
}
|
||||||
|
super.setInput(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the input for this information control.
|
||||||
|
* @param input
|
||||||
|
*/
|
||||||
|
private void setMacroExpansionInput(CMacroExpansionInput input) {
|
||||||
|
fInput= input;
|
||||||
|
fIndex= 0;
|
||||||
|
if (fMacroCompareViewer != null) {
|
||||||
|
fMacroCompareViewer.setMacroExpansionInput(fInput);
|
||||||
|
}
|
||||||
|
showExpansion();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showExpansion() {
|
||||||
|
final int idxLeft= fIndex;
|
||||||
|
final int idxRight= (fIndex + 1) % (fInput.fExplorer.getExpansionStepCount() + 1);
|
||||||
|
|
||||||
|
CompareConfiguration config= getCompareConfiguration();
|
||||||
|
config.setAncestorLabel(getLabelForIndex(0));
|
||||||
|
config.setLeftLabel(getLabelForIndex(idxLeft));
|
||||||
|
config.setRightLabel(getLabelForIndex(idxRight));
|
||||||
|
|
||||||
|
final ITypedElement original= getContentForIndex(0);
|
||||||
|
final ITypedElement left= getContentForIndex(idxLeft);
|
||||||
|
final ITypedElement right= getContentForIndex(idxRight);
|
||||||
|
|
||||||
|
setTitleText(CHoverMessages.CMacroExpansionControl_title_macroExpansion);
|
||||||
|
fMacroViewer.getDocument().set(getMacroText(fIndex));
|
||||||
|
setInput(createCompareInput(original, left, right));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getLabelForIndex(int index) {
|
||||||
|
if (index == 0) {
|
||||||
|
return CHoverMessages.CMacroExpansionControl_title_original;
|
||||||
|
} else if (index < fInput.fExplorer.getExpansionStepCount()) {
|
||||||
|
return NLS.bind(CHoverMessages.CMacroExpansionControl_title_expansion,
|
||||||
|
String.valueOf(index), String.valueOf(fInput.fExplorer.getExpansionStepCount()));
|
||||||
|
} else {
|
||||||
|
return CHoverMessages.CMacroExpansionControl_title_fullyExpanded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private Object createCompareInput(ITypedElement original, ITypedElement left, ITypedElement right) {
|
||||||
|
Differencer d= new Differencer();
|
||||||
|
return d.findDifferences(false, new NullProgressMonitor(), null, original, left, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ITypedElement getContentForIndex(int index) {
|
||||||
|
final String text;
|
||||||
|
if (index < fInput.fExplorer.getExpansionStepCount()) {
|
||||||
|
text= fInput.fExplorer.getExpansionStep(index).getCodeBeforeStep();
|
||||||
|
} else {
|
||||||
|
text= fInput.fExplorer.getFullExpansion().getCodeAfterStep();
|
||||||
|
}
|
||||||
|
final Document doc= new Document(text);
|
||||||
|
CUIPlugin.getDefault().getTextTools().setupCDocument(doc);
|
||||||
|
return new CDiffNode(0, String.valueOf(index), doc, 0, text.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMacroText(int index) {
|
||||||
|
final String text;
|
||||||
|
if (index < fInput.fExplorer.getExpansionStepCount()) {
|
||||||
|
IMacroBinding binding= fInput.fExplorer.getExpansionStep(index).getExpandedMacro();
|
||||||
|
StringBuffer buffer= new StringBuffer();
|
||||||
|
buffer.append("#define ").append(binding.getName()); //$NON-NLS-1$
|
||||||
|
char[][] params= binding.getParameterList();
|
||||||
|
if (params != null) {
|
||||||
|
buffer.append('(');
|
||||||
|
for (int i= 0; i < params.length; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
buffer.append(',');
|
||||||
|
buffer.append(' ');
|
||||||
|
}
|
||||||
|
char[] param= params[i];
|
||||||
|
buffer.append(new String(param));
|
||||||
|
}
|
||||||
|
buffer.append(')');
|
||||||
|
}
|
||||||
|
buffer.append(' ');
|
||||||
|
buffer.append(binding.getExpansionImage());
|
||||||
|
text= buffer.toString();
|
||||||
|
} else {
|
||||||
|
text= ""; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2007 Wind River Systems, Inc. and others.
|
* Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -11,33 +11,31 @@
|
||||||
|
|
||||||
package org.eclipse.cdt.internal.ui.text.c.hover;
|
package org.eclipse.cdt.internal.ui.text.c.hover;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.Reference;
|
||||||
|
import java.lang.ref.SoftReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
import org.eclipse.jface.text.BadLocationException;
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
import org.eclipse.jface.text.Document;
|
|
||||||
import org.eclipse.jface.text.IDocument;
|
import org.eclipse.jface.text.IDocument;
|
||||||
import org.eclipse.jface.text.IInformationControl;
|
import org.eclipse.jface.text.IInformationControl;
|
||||||
import org.eclipse.jface.text.IInformationControlCreator;
|
import org.eclipse.jface.text.IInformationControlCreator;
|
||||||
import org.eclipse.jface.text.IRegion;
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.ITextSelection;
|
||||||
import org.eclipse.jface.text.ITextViewer;
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
import org.eclipse.jface.text.Position;
|
import org.eclipse.jface.text.Position;
|
||||||
import org.eclipse.jface.text.Region;
|
import org.eclipse.jface.text.Region;
|
||||||
import org.eclipse.jface.text.TextUtilities;
|
|
||||||
import org.eclipse.jface.text.information.IInformationProviderExtension2;
|
import org.eclipse.jface.text.information.IInformationProviderExtension2;
|
||||||
|
import org.eclipse.jface.viewers.ISelection;
|
||||||
|
import org.eclipse.jface.viewers.ISelectionProvider;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.widgets.Shell;
|
import org.eclipse.swt.widgets.Shell;
|
||||||
import org.eclipse.text.edits.MalformedTreeException;
|
|
||||||
import org.eclipse.text.edits.TextEdit;
|
|
||||||
import org.eclipse.ui.IEditorInput;
|
import org.eclipse.ui.IEditorInput;
|
||||||
import org.eclipse.ui.IEditorPart;
|
import org.eclipse.ui.IEditorPart;
|
||||||
import org.eclipse.ui.texteditor.ITextEditor;
|
import org.eclipse.ui.texteditor.ITextEditor;
|
||||||
|
@ -46,40 +44,22 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionStyleMacroParameter;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion;
|
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorFunctionStyleMacroDefinition;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||||
import org.eclipse.cdt.core.dom.parser.IScannerExtensionConfiguration;
|
import org.eclipse.cdt.core.dom.rewrite.MacroExpansionExplorer;
|
||||||
import org.eclipse.cdt.core.dom.parser.c.GCCScannerExtensionConfiguration;
|
|
||||||
import org.eclipse.cdt.core.dom.parser.cpp.GPPScannerExtensionConfiguration;
|
|
||||||
import org.eclipse.cdt.core.formatter.CodeFormatter;
|
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
|
||||||
import org.eclipse.cdt.core.model.ILanguage;
|
import org.eclipse.cdt.core.model.ILanguage;
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||||
import org.eclipse.cdt.core.parser.CodeReader;
|
|
||||||
import org.eclipse.cdt.core.parser.EndOfFileException;
|
|
||||||
import org.eclipse.cdt.core.parser.IGCCToken;
|
|
||||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
|
||||||
import org.eclipse.cdt.core.parser.IToken;
|
|
||||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
|
||||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
|
||||||
import org.eclipse.cdt.core.parser.ScannerInfo;
|
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
import org.eclipse.cdt.ui.IWorkingCopyManager;
|
import org.eclipse.cdt.ui.IWorkingCopyManager;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.dom.NullCodeReaderFactory;
|
|
||||||
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
|
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor;
|
|
||||||
import org.eclipse.cdt.internal.corext.util.CodeFormatterUtil;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.editor.ASTProvider;
|
import org.eclipse.cdt.internal.ui.editor.ASTProvider;
|
||||||
|
|
||||||
|
@ -226,16 +206,14 @@ public class CMacroExpansionHover extends AbstractCEditorTextHover implements II
|
||||||
*/
|
*/
|
||||||
private static class ComputeExpansionRegionRunnable implements ASTRunnable {
|
private static class ComputeExpansionRegionRunnable implements ASTRunnable {
|
||||||
private final Position fTextRegion;
|
private final Position fTextRegion;
|
||||||
|
private final boolean fAllowSelection;
|
||||||
private IASTNode fEnclosingNode;
|
private IASTNode fEnclosingNode;
|
||||||
private Map fMacroDict;
|
|
||||||
private List fExpansionNodes= new ArrayList();
|
private List fExpansionNodes= new ArrayList();
|
||||||
|
private MacroExpansionExplorer fExplorer;
|
||||||
|
|
||||||
/**
|
private ComputeExpansionRegionRunnable(ITranslationUnit tUnit, IRegion textRegion, boolean allowSelection) {
|
||||||
* @param tUnit
|
|
||||||
* @param textRegion
|
|
||||||
*/
|
|
||||||
private ComputeExpansionRegionRunnable(ITranslationUnit tUnit, IRegion textRegion) {
|
|
||||||
fTextRegion= new Position(textRegion.getOffset(), textRegion.getLength());
|
fTextRegion= new Position(textRegion.getOffset(), textRegion.getLength());
|
||||||
|
fAllowSelection= allowSelection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -243,79 +221,56 @@ public class CMacroExpansionHover extends AbstractCEditorTextHover implements II
|
||||||
*/
|
*/
|
||||||
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) {
|
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) {
|
||||||
if (ast != null) {
|
if (ast != null) {
|
||||||
// try object style macro expansion first
|
// try macro name match first
|
||||||
IASTNode node= ast.selectNodeForLocation(ast.getFilePath(), fTextRegion.getOffset(), fTextRegion.getLength());
|
IASTNode node= ast.selectNodeForLocation(ast.getFilePath(), fTextRegion.getOffset(), fTextRegion.getLength());
|
||||||
if (node instanceof IASTName) {
|
if (node instanceof IASTName) {
|
||||||
IASTName macroName= (IASTName) node;
|
IASTName macroName= (IASTName) node;
|
||||||
IBinding binding= macroName.getBinding();
|
IBinding binding= macroName.getBinding();
|
||||||
if (binding instanceof IMacroBinding) {
|
if (binding instanceof IMacroBinding) {
|
||||||
IMacroBinding macroBinding= (IMacroBinding) binding;
|
addExpansionNode(node);
|
||||||
if (!macroBinding.isFunctionStyle()) {
|
createMacroExpansionExplorer(ast, getExpansionRegion());
|
||||||
addExpansionNode(node);
|
return Status.OK_STATUS;
|
||||||
buildMacroDictionary(ast);
|
|
||||||
return Status.OK_STATUS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// function style macro or selection
|
if (fAllowSelection) {
|
||||||
FindEnclosingNodeAction nodeFinder= new FindEnclosingNodeAction(ast.getFilePath(), fTextRegion.getOffset(), fTextRegion.getLength());
|
// selection
|
||||||
ast.accept(nodeFinder);
|
FindEnclosingNodeAction nodeFinder= new FindEnclosingNodeAction(ast.getFilePath(), fTextRegion.getOffset(), fTextRegion.getLength());
|
||||||
fEnclosingNode= nodeFinder.getNode();
|
ast.accept(nodeFinder);
|
||||||
if (fEnclosingNode != null) {
|
fEnclosingNode= nodeFinder.getNode();
|
||||||
boolean macroOccurrence= false;
|
if (fEnclosingNode != null) {
|
||||||
IASTNodeLocation[] locations= fEnclosingNode.getNodeLocations();
|
boolean macroOccurrence= false;
|
||||||
for (int i = 0; i < locations.length; i++) {
|
IASTNodeLocation[] locations= fEnclosingNode.getNodeLocations();
|
||||||
IASTNodeLocation location= locations[i];
|
for (int i = 0; i < locations.length; i++) {
|
||||||
if (location instanceof IASTMacroExpansion) {
|
IASTNodeLocation location= locations[i];
|
||||||
IASTFileLocation fileLocation= location.asFileLocation();
|
if (location instanceof IASTMacroExpansion) {
|
||||||
if (fileLocation != null && ast.getFilePath().equals(fileLocation.getFileName())) {
|
IASTFileLocation fileLocation= location.asFileLocation();
|
||||||
if (fTextRegion.overlapsWith(fileLocation.getNodeOffset(), fileLocation.getNodeLength())) {
|
if (fileLocation != null && ast.getFilePath().equals(fileLocation.getFileName())) {
|
||||||
nodeFinder= new FindEnclosingNodeAction(ast.getFilePath(), fileLocation.getNodeOffset(), fileLocation.getNodeLength());
|
if (fTextRegion.overlapsWith(fileLocation.getNodeOffset(), fileLocation.getNodeLength())) {
|
||||||
ast.accept(nodeFinder);
|
nodeFinder= new FindEnclosingNodeAction(ast.getFilePath(), fileLocation.getNodeOffset(), fileLocation.getNodeLength());
|
||||||
addExpansionNode(nodeFinder.getNode());
|
ast.accept(nodeFinder);
|
||||||
macroOccurrence= true;
|
addExpansionNode(nodeFinder.getNode());
|
||||||
|
macroOccurrence= true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (macroOccurrence) {
|
||||||
if (macroOccurrence) {
|
CollectEnclosedNodesAction nodeCollector= new CollectEnclosedNodesAction(ast.getFilePath(), fTextRegion.getOffset(), fTextRegion.getLength());
|
||||||
CollectEnclosedNodesAction nodeCollector= new CollectEnclosedNodesAction(ast.getFilePath(), fTextRegion.getOffset(), fTextRegion.getLength());
|
ast.accept(nodeCollector);
|
||||||
ast.accept(nodeCollector);
|
fExpansionNodes.addAll(nodeCollector.getNodes());
|
||||||
fExpansionNodes.addAll(nodeCollector.getNodes());
|
createMacroExpansionExplorer(ast, getExpansionRegion());
|
||||||
buildMacroDictionary(ast);
|
return Status.OK_STATUS;
|
||||||
return Status.OK_STATUS;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Status.CANCEL_STATUS;
|
return Status.CANCEL_STATUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildMacroDictionary(IASTTranslationUnit ast) {
|
private void createMacroExpansionExplorer(IASTTranslationUnit ast, IRegion region) {
|
||||||
Map macroDict= new HashMap(500);
|
if (region != null) {
|
||||||
IASTPreprocessorMacroDefinition[] macroDefs;
|
fExplorer= MacroExpansionExplorer.create(ast, region);
|
||||||
final IASTPreprocessorMacroDefinition[] localMacroDefs= ast.getMacroDefinitions();
|
|
||||||
for (macroDefs= localMacroDefs; macroDefs != null; macroDefs= (macroDefs == localMacroDefs) ? ast.getBuiltinMacroDefinitions() : null) {
|
|
||||||
for (int i = 0; i < macroDefs.length; i++) {
|
|
||||||
IASTPreprocessorMacroDefinition macroDef= macroDefs[i];
|
|
||||||
StringBuffer macroName= new StringBuffer();
|
|
||||||
macroName.append(macroDef.getName().toCharArray());
|
|
||||||
if (macroDef instanceof IASTPreprocessorFunctionStyleMacroDefinition) {
|
|
||||||
macroName.append('(');
|
|
||||||
IASTPreprocessorFunctionStyleMacroDefinition functionMacro= (IASTPreprocessorFunctionStyleMacroDefinition)macroDef;
|
|
||||||
IASTFunctionStyleMacroParameter[] macroParams= functionMacro.getParameters();
|
|
||||||
for (int j = 0; j < macroParams.length; j++) {
|
|
||||||
if (j > 0) {
|
|
||||||
macroName.append(',');
|
|
||||||
}
|
|
||||||
IASTFunctionStyleMacroParameter param= macroParams[j];
|
|
||||||
macroName.append(param.getParameter());
|
|
||||||
}
|
|
||||||
macroName.append(')');
|
|
||||||
}
|
|
||||||
macroDict.put(macroName.toString(), macroDef.getExpansion());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fMacroDict= macroDict;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addExpansionNode(IASTNode node) {
|
private void addExpansionNode(IASTNode node) {
|
||||||
|
@ -375,41 +330,42 @@ public class CMacroExpansionHover extends AbstractCEditorTextHover implements II
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map getMacroDictionary() {
|
|
||||||
return fMacroDict;
|
|
||||||
}
|
|
||||||
|
|
||||||
IASTNode getEnclosingNode() {
|
IASTNode getEnclosingNode() {
|
||||||
return fEnclosingNode;
|
return fEnclosingNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MacroExpansionExplorer getMacroExpansionExplorer() {
|
||||||
|
return fExplorer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Cache {
|
private Reference fCache;
|
||||||
ComputeExpansionRegionRunnable fComputer;
|
|
||||||
IWorkingCopy fTranslationUnit;
|
|
||||||
String fExpansionText;
|
|
||||||
String fExpandedText;
|
|
||||||
}
|
|
||||||
|
|
||||||
private WeakReference fCache;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @see org.eclipse.cdt.internal.ui.text.c.hover.AbstractCEditorTextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
|
* @see org.eclipse.cdt.internal.ui.text.c.hover.AbstractCEditorTextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
|
||||||
*/
|
*/
|
||||||
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
|
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
|
||||||
IEditorPart editor = getEditor();
|
CMacroExpansionInput input= createMacroExpansionInput(getEditor(), hoverRegion, true);
|
||||||
|
if (input == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
fCache= new SoftReference(input);
|
||||||
|
return input.fExplorer.getFullExpansion().getCodeAfterStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CMacroExpansionInput createMacroExpansionInput(IEditorPart editor, IRegion hoverRegion, boolean allowSelection) {
|
||||||
if (editor == null || !(editor instanceof ITextEditor)) {
|
if (editor == null || !(editor instanceof ITextEditor)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
IEditorInput input= editor.getEditorInput();
|
IEditorInput editorInput= editor.getEditorInput();
|
||||||
IWorkingCopyManager manager= CUIPlugin.getDefault().getWorkingCopyManager();
|
IWorkingCopyManager manager= CUIPlugin.getDefault().getWorkingCopyManager();
|
||||||
IWorkingCopy tu = manager.getWorkingCopy(input);
|
IWorkingCopy tu = manager.getWorkingCopy(editorInput);
|
||||||
if (tu == null) {
|
if (tu == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
IProgressMonitor monitor= new NullProgressMonitor();
|
IProgressMonitor monitor= new NullProgressMonitor();
|
||||||
ComputeExpansionRegionRunnable computer= new ComputeExpansionRegionRunnable(tu, hoverRegion);
|
ComputeExpansionRegionRunnable computer= new ComputeExpansionRegionRunnable(tu, hoverRegion, allowSelection);
|
||||||
IStatus status= ASTProvider.getASTProvider().runOnAST(tu, ASTProvider.WAIT_ACTIVE_ONLY, monitor, computer);
|
IStatus status= ASTProvider.getASTProvider().runOnAST(tu, ASTProvider.WAIT_ACTIVE_ONLY, monitor, computer);
|
||||||
if (!status.isOK()) {
|
if (!status.isOK()) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -418,49 +374,19 @@ public class CMacroExpansionHover extends AbstractCEditorTextHover implements II
|
||||||
if (region == null) {
|
if (region == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
ITextEditor textEditor= (ITextEditor)editor;
|
MacroExpansionExplorer explorer= computer.getMacroExpansionExplorer();
|
||||||
IDocument document= textEditor.getDocumentProvider().getDocument(input);
|
if (explorer == null) {
|
||||||
region= alignRegion(region, document);
|
|
||||||
|
|
||||||
String expansionText;
|
|
||||||
try {
|
|
||||||
expansionText= document.get(region.getOffset(), region.getLength());
|
|
||||||
} catch (BadLocationException exc) {
|
|
||||||
CUIPlugin.getDefault().log(exc);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// expand
|
ITextEditor textEditor= (ITextEditor)editor;
|
||||||
String expandedText= expandMacros(computer.getMacroDictionary(), expansionText, tu.isCXXLanguage());
|
IDocument document= textEditor.getDocumentProvider().getDocument(editorInput);
|
||||||
|
region= alignRegion(region, document);
|
||||||
|
|
||||||
// format
|
CMacroExpansionInput input= new CMacroExpansionInput();
|
||||||
final String lineDelimiter= TextUtilities.getDefaultLineDelimiter(document);
|
input.fExplorer= explorer;
|
||||||
final int nodeKind = getNodeKind(computer.getEnclosingNode());
|
input.fDocument= document;
|
||||||
String formattedText= formatSource(nodeKind, expandedText, lineDelimiter, tu.getCProject());
|
input.fRegion= region;
|
||||||
|
return input;
|
||||||
// cache objects for later macro exploration
|
|
||||||
Cache cache= new Cache();
|
|
||||||
cache.fComputer= computer;
|
|
||||||
cache.fExpansionText= expansionText;
|
|
||||||
cache.fTranslationUnit= tu;
|
|
||||||
cache.fExpandedText= formattedText;
|
|
||||||
fCache= new WeakReference(cache);
|
|
||||||
return formattedText;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getNodeKind(IASTNode node) {
|
|
||||||
if (node instanceof IASTDeclaration) {
|
|
||||||
return CodeFormatter.K_TRANSLATION_UNIT;
|
|
||||||
}
|
|
||||||
if (node instanceof IASTStatement) {
|
|
||||||
return CodeFormatter.K_STATEMENTS;
|
|
||||||
}
|
|
||||||
if (node instanceof IASTExpression) {
|
|
||||||
return CodeFormatter.K_EXPRESSION;
|
|
||||||
}
|
|
||||||
if (node instanceof IASTTranslationUnit) {
|
|
||||||
return CodeFormatter.K_TRANSLATION_UNIT;
|
|
||||||
}
|
|
||||||
return CodeFormatter.K_UNKNOWN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final IRegion alignRegion(IRegion region, IDocument document) {
|
private static final IRegion alignRegion(IRegion region, IDocument document) {
|
||||||
|
@ -491,151 +417,6 @@ public class CMacroExpansionHover extends AbstractCEditorTextHover implements II
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Format given source content according given options.
|
|
||||||
*
|
|
||||||
* @param kind
|
|
||||||
* one of {@link CodeFormatter#K_TRANSLATION_UNIT},
|
|
||||||
* {@link CodeFormatter#K_STATEMENTS},
|
|
||||||
* {@link CodeFormatter#K_EXPRESSION}
|
|
||||||
* @param content
|
|
||||||
* the source content
|
|
||||||
* @param lineDelimiter
|
|
||||||
* the line delimiter to be used
|
|
||||||
* @param project
|
|
||||||
* @return the formatted source text or the original if the text could not
|
|
||||||
* be formatted successfully
|
|
||||||
*/
|
|
||||||
private static String formatSource(int kind, String content, String lineDelimiter, ICProject project) {
|
|
||||||
TextEdit edit= CodeFormatterUtil.format(kind, content, 0, lineDelimiter, project.getOptions(true));
|
|
||||||
if (edit != null) {
|
|
||||||
IDocument doc= new Document(content);
|
|
||||||
try {
|
|
||||||
edit.apply(doc);
|
|
||||||
content= doc.get().trim();
|
|
||||||
} catch (MalformedTreeException exc) {
|
|
||||||
CUIPlugin.getDefault().log(exc);
|
|
||||||
} catch (BadLocationException exc) {
|
|
||||||
CUIPlugin.getDefault().log(exc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String expandMacros(Map macroDict, String expansionText, boolean isCpp) {
|
|
||||||
final IScannerInfo scannerInfo= new ScannerInfo(macroDict);
|
|
||||||
final CodeReader codeReader= new CodeReader(expansionText.toCharArray());
|
|
||||||
final IScannerExtensionConfiguration configuration;
|
|
||||||
final ParserLanguage parserLanguage;
|
|
||||||
if (isCpp) {
|
|
||||||
configuration= new GPPScannerExtensionConfiguration();
|
|
||||||
parserLanguage= ParserLanguage.CPP;
|
|
||||||
} else {
|
|
||||||
configuration= new GCCScannerExtensionConfiguration();
|
|
||||||
parserLanguage= ParserLanguage.C;
|
|
||||||
}
|
|
||||||
CPreprocessor preprocessor= new CPreprocessor(codeReader, scannerInfo, parserLanguage, ParserUtil.getParserLogService(), configuration, NullCodeReaderFactory.getInstance());
|
|
||||||
StringBuffer expandedText= new StringBuffer(expansionText.length());
|
|
||||||
IToken token= null;
|
|
||||||
IToken prevToken;
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
prevToken= token;
|
|
||||||
token= preprocessor.nextToken();
|
|
||||||
} catch (EndOfFileException exc) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (requireSpace(prevToken, token)) {
|
|
||||||
expandedText.append(' ');
|
|
||||||
}
|
|
||||||
expandedText.append(token.getImage());
|
|
||||||
}
|
|
||||||
return expandedText.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean requireSpace(IToken prevToken, IToken token) {
|
|
||||||
if (prevToken == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (prevToken.isOperator() && token.isOperator()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
switch (prevToken.getType()) {
|
|
||||||
case IToken.tLPAREN: case IToken.tLBRACKET:
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// bit operations
|
|
||||||
case IToken.tAMPERASSIGN:
|
|
||||||
case IToken.tBITOR: case IToken.tBITORASSIGN:
|
|
||||||
case IToken.tSHIFTL: case IToken.tSHIFTLASSIGN:
|
|
||||||
case IToken.tSHIFTR: case IToken.tSHIFTRASSIGN:
|
|
||||||
case IToken.tXOR: case IToken.tXORASSIGN:
|
|
||||||
|
|
||||||
// logical operations
|
|
||||||
case IToken.tAND: case IToken.tOR:
|
|
||||||
|
|
||||||
// arithmetic
|
|
||||||
case IToken.tDIV: case IToken.tDIVASSIGN:
|
|
||||||
case IToken.tMINUS: case IToken.tMINUSASSIGN:
|
|
||||||
case IToken.tMOD: case IToken.tMODASSIGN:
|
|
||||||
case IToken.tPLUS: case IToken.tPLUSASSIGN:
|
|
||||||
case IToken.tSTARASSIGN:
|
|
||||||
case IGCCToken.tMAX: case IGCCToken.tMIN:
|
|
||||||
|
|
||||||
// comparison
|
|
||||||
case IToken.tEQUAL: case IToken.tNOTEQUAL:
|
|
||||||
case IToken.tGT: case IToken.tGTEQUAL:
|
|
||||||
case IToken.tLT: case IToken.tLTEQUAL:
|
|
||||||
|
|
||||||
// other
|
|
||||||
case IToken.tASSIGN: case IToken.tCOMMA:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (token.getType()) {
|
|
||||||
case IToken.tRPAREN: case IToken.tRBRACKET:
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// bit operations
|
|
||||||
case IToken.tAMPER: case IToken.tAMPERASSIGN:
|
|
||||||
case IToken.tBITOR: case IToken.tBITORASSIGN:
|
|
||||||
case IToken.tSHIFTL: case IToken.tSHIFTLASSIGN:
|
|
||||||
case IToken.tSHIFTR: case IToken.tSHIFTRASSIGN:
|
|
||||||
case IToken.tXOR: case IToken.tXORASSIGN:
|
|
||||||
|
|
||||||
// logical operations
|
|
||||||
case IToken.tAND: case IToken.tOR:
|
|
||||||
|
|
||||||
// arithmetic
|
|
||||||
case IToken.tDIV: case IToken.tDIVASSIGN:
|
|
||||||
case IToken.tMINUS: case IToken.tMINUSASSIGN:
|
|
||||||
case IToken.tMOD: case IToken.tMODASSIGN:
|
|
||||||
case IToken.tPLUS: case IToken.tPLUSASSIGN:
|
|
||||||
case IToken.tSTAR: case IToken.tSTARASSIGN:
|
|
||||||
case IGCCToken.tMAX: case IGCCToken.tMIN:
|
|
||||||
|
|
||||||
// comparison
|
|
||||||
case IToken.tEQUAL: case IToken.tNOTEQUAL:
|
|
||||||
case IToken.tGT: case IToken.tGTEQUAL:
|
|
||||||
case IToken.tLT: case IToken.tLTEQUAL:
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// other
|
|
||||||
case IToken.tASSIGN:
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case IToken.tCOMMA:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char lastChar= prevToken.getCharImage()[prevToken.getLength() - 1];
|
|
||||||
char nextChar= token.getCharImage()[0];
|
|
||||||
if (Character.isJavaIdentifierPart(lastChar) && Character.isJavaIdentifierPart(nextChar)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
|
* @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
|
||||||
*/
|
*/
|
||||||
|
@ -655,21 +436,30 @@ public class CMacroExpansionHover extends AbstractCEditorTextHover implements II
|
||||||
public IInformationControl createInformationControl(Shell parent) {
|
public IInformationControl createInformationControl(Shell parent) {
|
||||||
int shellStyle= SWT.RESIZE;
|
int shellStyle= SWT.RESIZE;
|
||||||
int style= SWT.V_SCROLL | SWT.H_SCROLL;
|
int style= SWT.V_SCROLL | SWT.H_SCROLL;
|
||||||
return new CMacroExpansionControl(parent, shellStyle, style, createMacroExpansionInput());
|
return new CMacroExpansionExplorationControl(parent, shellStyle, style, getMacroExpansionInput());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CMacroExpansionInput createMacroExpansionInput() {
|
protected CMacroExpansionInput getMacroExpansionInput() {
|
||||||
// TODO compute all expansion steps
|
if (fCache == null) {
|
||||||
Cache cache= (Cache) fCache.get();
|
return null;
|
||||||
fCache= null;
|
|
||||||
if (cache != null) {
|
|
||||||
CMacroExpansionInput input= new CMacroExpansionInput();
|
|
||||||
input.fExpansions= new String[] { cache.fExpansionText, cache.fExpandedText };
|
|
||||||
return input;
|
|
||||||
}
|
}
|
||||||
return null;
|
CMacroExpansionInput input= (CMacroExpansionInput) fCache.get();
|
||||||
|
fCache= null;
|
||||||
|
if (input == null) {
|
||||||
|
IEditorPart editor= getEditor();
|
||||||
|
if (editor != null) {
|
||||||
|
ISelectionProvider provider= editor.getSite().getSelectionProvider();
|
||||||
|
ISelection selection= provider.getSelection();
|
||||||
|
if (selection instanceof ITextSelection) {
|
||||||
|
ITextSelection textSelection= (ITextSelection) selection;
|
||||||
|
IRegion region= new Region(textSelection.getOffset(), textSelection.getLength());
|
||||||
|
input= createMacroExpansionInput(editor, region, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2007 Wind River Systems, Inc. and others.
|
* Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -11,11 +11,18 @@
|
||||||
|
|
||||||
package org.eclipse.cdt.internal.ui.text.c.hover;
|
package org.eclipse.cdt.internal.ui.text.c.hover;
|
||||||
|
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.rewrite.MacroExpansionExplorer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An input object to the {@link CMacroExpansionControl}.
|
* An input object to the {@link CMacroExpansionExplorationControl}.
|
||||||
*
|
*
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
public class CMacroExpansionInput {
|
class CMacroExpansionInput {
|
||||||
String[] fExpansions;
|
MacroExpansionExplorer fExplorer;
|
||||||
|
IDocument fDocument;
|
||||||
|
IRegion fRegion;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue