diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTCompletionNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTCompletionNode.java new file mode 100644 index 00000000000..fde761e778d --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTCompletionNode.java @@ -0,0 +1,41 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.core.parser.ast; + +import org.eclipse.cdt.core.parser.Enum; + +/** + * @author jcamelon + * + */ +public interface IASTCompletionNode { + + public static class CompletionKind extends Enum + { + public static final CompletionKind TYPE = new CompletionKind( 0 ); + public static final CompletionKind DOT_MEMBER = new CompletionKind( 1 ); + public static final CompletionKind ARROW_MEMBER = new CompletionKind( 2 ); + public static final CompletionKind QUALIFIEDNAME_MEMBER = new CompletionKind( 3 ); + //TODO MORE TO COME + /** + * @param enumValue + */ + protected CompletionKind(int enumValue) { + super(enumValue); + } + + } + + + public CompletionKind getCompletionKind(); + public IASTNode getCompletionContext(); + public String getCompletionPrefix(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTNode.java new file mode 100644 index 00000000000..ffc45fb681a --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTNode.java @@ -0,0 +1,55 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.core.parser.ast; + +import java.util.Iterator; + +import org.eclipse.cdt.core.parser.Enum; + +/** + * @author jcamelon + * + */ +public interface IASTNode { + + public static class LookupKind extends Enum { + + public static final LookupKind ALL = new LookupKind( 0 ); + public static final LookupKind STRUCTURES = new LookupKind( 1 ); + public static final LookupKind FUNCTIONS = new LookupKind( 2 ); + public static final LookupKind LOCAL_VARIABLES = new LookupKind( 3 ); + public static final LookupKind METHODS = new LookupKind( 4 ); + public static final LookupKind FIELDS = new LookupKind( 5 ); + public static final LookupKind NAMESPACES = new LookupKind( 6 ); + + /** + * @param enumValue + */ + protected LookupKind(int enumValue) { + super(enumValue); + // TODO Auto-generated constructor stub + } + } + + public static class InvalidLookupKind extends Exception + { + } + + public static interface LookupResult + { + public String getPrefix(); + public Iterator getNodes(); + public Iterator getKeywords(); + } + + public LookupResult lookup( String prefix, LookupKind kind ); +} + diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/SourceLookupFactory.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/SourceLookupFactory.java new file mode 100644 index 00000000000..b3e6471443a --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/SourceLookupFactory.java @@ -0,0 +1,42 @@ +/* + *(c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + * + */ + +package org.eclipse.cdt.debug.core.sourcelookup; + +import org.eclipse.cdt.debug.internal.core.sourcelookup.CDirectorySourceLocation; +import org.eclipse.cdt.debug.internal.core.sourcelookup.CProjectSourceLocation; +import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLocator; +import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceManager; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IPath; + +/** + * Enter type comment. + * + * @since Jul 14, 2003 + */ +public class SourceLookupFactory +{ + public static IProjectSourceLocation createProjectSourceLocation( IProject project ) + { + return new CProjectSourceLocation( project ); + } + + public static IProjectSourceLocation createProjectSourceLocation( IProject project, boolean generated ) + { + return new CProjectSourceLocation( project, generated ); + } + + public static IDirectorySourceLocation createDirectorySourceLocation( IPath directory, IPath association, boolean searchSubfolders ) + { + return new CDirectorySourceLocation( directory, association, searchSubfolders ); + } + + public static ICSourceLocator createSourceLocator( IProject project ) + { + return new CSourceManager( new CSourceLocator( project ) ); + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/sourcelookup/DefaultSourceLocator.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/sourcelookup/DefaultSourceLocator.java new file mode 100644 index 00000000000..5dac8882209 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/sourcelookup/DefaultSourceLocator.java @@ -0,0 +1,434 @@ +/* + *(c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + * + */ + +package org.eclipse.cdt.debug.ui.sourcelookup; + +import java.io.IOException; +import java.io.StringReader; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.xerces.dom.DocumentImpl; +import org.eclipse.cdt.core.resources.FileStorage; +import org.eclipse.cdt.debug.core.CDebugUtils; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.debug.core.model.IStackFrameInfo; +import org.eclipse.cdt.debug.core.sourcelookup.ICSourceLocator; +import org.eclipse.cdt.debug.core.sourcelookup.ISourceMode; +import org.eclipse.cdt.debug.core.sourcelookup.SourceLookupFactory; +import org.eclipse.cdt.debug.internal.ui.CDebugImageDescriptorRegistry; +import org.eclipse.cdt.debug.internal.ui.CDebugImages; +import org.eclipse.cdt.debug.internal.ui.dialogfields.SelectionButtonDialogField; +import org.eclipse.cdt.debug.internal.ui.editors.FileNotFoundElement; +import org.eclipse.cdt.debug.internal.ui.editors.NoSymbolOrSourceElement; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.utils.ui.controls.ControlFactory; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.model.IPersistableSourceLocator; +import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.dialogs.ListDialog; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Enter type comment. + * + * @since Oct 24, 2003 + */ +public class DefaultSourceLocator implements IPersistableSourceLocator, IAdaptable +{ + public class SourceSelectionDialog extends ListDialog + { + private SelectionButtonDialogField fAlwaysUseThisFileButton = new SelectionButtonDialogField( SWT.CHECK ); + + public SourceSelectionDialog( Shell parent ) + { + super( parent ); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.dialogs.ListDialog#createDialogArea(org.eclipse.swt.widgets.Composite) + */ + protected Control createDialogArea( Composite parent ) + { + Composite comp = ControlFactory.createComposite( parent, 1 ); + super.createDialogArea( comp ); + Composite comp1 = ControlFactory.createComposite( comp, 1 ); + fAlwaysUseThisFileButton.setLabelText( "Always map to the selection" ); + fAlwaysUseThisFileButton.doFillIntoGrid( comp1, 1 ); + return comp; + } + + public boolean alwaysMapToSelection() + { + return fAlwaysUseThisFileButton.isSelected(); + } + } + + public class SourceElementLabelProvider extends LabelProvider + { + protected CDebugImageDescriptorRegistry fDebugImageRegistry = CDebugUIPlugin.getImageDescriptorRegistry(); + + public SourceElementLabelProvider() + { + super(); + } + + public String getText(Object element) + { + if ( element instanceof IFile ) + return ((IFile)element).getFullPath().toString(); + if ( element instanceof FileStorage ) + return ((FileStorage)element).getFullPath().toOSString(); + return super.getText(element); + } + + public Image getImage( Object element ) + { + if ( element instanceof IFile ) + return fDebugImageRegistry.get( CDebugImages.DESC_OBJS_WORKSPACE_SOURCE_FILE ); + if ( element instanceof FileStorage ) + return fDebugImageRegistry.get( CDebugImages.DESC_OBJS_EXTERNAL_SOURCE_FILE ); + return super.getImage( element ); + } + } + + /** + * Identifier for the 'Default C/C++ Source Locator' extension + * (value "org.eclipse.cdt.debug.ui.DefaultSourceLocator"). + */ + public static final String ID_DEFAULT_SOURCE_LOCATOR = CDebugUIPlugin.getUniqueIdentifier() + ".DefaultSourceLocator"; //$NON-NLS-1$ + // to support old configurations + public static final String ID_OLD_DEFAULT_SOURCE_LOCATOR = "org.eclipse.cdt.launch" + ".DefaultSourceLocator"; //$NON-NLS-1$ + + private static final String ELEMENT_NAME = "PromptingSourceLocator"; + private static final String ATTR_PROJECT = "project"; + private static final String ATTR_MEMENTO = "memento"; + + /** + * The project being debugged. + */ + private IProject fProject = null; + + /** + * Underlying source locator. + */ + private ICSourceLocator fSourceLocator; + + private HashMap fFramesToSource = null; + private HashMap fNamesToSource = null; + + public DefaultSourceLocator() + { + super(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IPersistableSourceLocator#getMemento() + */ + public String getMemento() throws CoreException + { + if ( fSourceLocator != null ) + { + Document doc = new DocumentImpl(); + Element node = doc.createElement( ELEMENT_NAME ); + doc.appendChild( node ); + node.setAttribute( ATTR_PROJECT, fSourceLocator.getProject().getName() ); + + IPersistableSourceLocator psl = getPersistableSourceLocator(); + if ( psl != null ) + { + node.setAttribute( ATTR_MEMENTO, psl.getMemento() ); + } + try + { + return CDebugUtils.serializeDocument( doc, " " ); + } + catch( IOException e ) + { + abort( "Unable to create memento for C/C++ source locator.", e ); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IPersistableSourceLocator#initializeFromMemento(java.lang.String) + */ + public void initializeFromMemento( String memento ) throws CoreException + { + Exception ex = null; + try + { + Element root = null; + DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + StringReader reader = new StringReader( memento ); + InputSource source = new InputSource( reader ); + root = parser.parse( source ).getDocumentElement(); + + if ( !root.getNodeName().equalsIgnoreCase( ELEMENT_NAME ) ) + { + abort( "Unable to restore prompting source locator - invalid format.", null ); + } + + String projectName = root.getAttribute( ATTR_PROJECT ); + String data = root.getAttribute( ATTR_MEMENTO ); + if ( isEmpty( projectName ) ) + { + abort( "Unable to restore prompting source locator - invalid format.", null ); + } + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject( projectName ); + if ( project == null || !project.exists() || !project.isOpen() ) + { + abort( MessageFormat.format( "Unable to restore prompting source locator - project {0} not found.", new String[] { projectName } ), null ); + } + ICSourceLocator locator = getCSourceLocator(); + if ( locator == null ) + { + fSourceLocator = SourceLookupFactory.createSourceLocator( project ); + } + else if ( locator.getProject() != null && !project.equals( locator.getProject() ) ) + { + return; + } + IPersistableSourceLocator psl = getPersistableSourceLocator(); + if ( psl != null ) + { + psl.initializeFromMemento( data ); + } + else + { + abort( "Unable to restore C/C++ source locator - invalid format.", null ); + } + return; + } + catch( ParserConfigurationException e ) + { + ex = e; + } + catch( SAXException e ) + { + ex = e; + } + catch( IOException e ) + { + ex = e; + } + abort( "Exception occurred initializing source locator.", ex ); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IPersistableSourceLocator#initializeDefaults(org.eclipse.debug.core.ILaunchConfiguration) + */ + public void initializeDefaults( ILaunchConfiguration configuration ) throws CoreException + { + fSourceLocator = SourceLookupFactory.createSourceLocator( getProject( configuration ) ); + String memento = configuration.getAttribute( ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, "" ); + if ( !isEmpty( memento ) ) + initializeFromMemento( memento ); + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + public Object getAdapter( Class adapter ) + { + if ( fSourceLocator instanceof IAdaptable ) + { + if ( adapter.equals( ICSourceLocator.class ) ) + { + return ((IAdaptable)fSourceLocator).getAdapter( adapter ); + } + if ( adapter.equals( IResourceChangeListener.class ) ) + { + return ((IAdaptable)fSourceLocator).getAdapter( adapter ); + } + if ( adapter.equals( ISourceMode.class ) ) + { + return ((IAdaptable)fSourceLocator).getAdapter( adapter ); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISourceLocator#getSourceElement(org.eclipse.debug.core.model.IStackFrame) + */ + public Object getSourceElement( IStackFrame stackFrame ) + { + Object res = cacheLookup( stackFrame ); + if ( res == null ) + { + res = fSourceLocator.getSourceElement( stackFrame ); + if ( res instanceof List ) + { + List list = (List)res; + if ( list.size() != 0 ) + { + SourceSelectionDialog dialog = createSourceSelectionDialog( list ); + dialog.open(); + Object[] objs = dialog.getResult(); + res = ( objs != null && objs.length > 0 ) ? objs[0] : null; + if ( res != null ) + cacheSourceElement( stackFrame, res, dialog.alwaysMapToSelection() ); + } + else + res = null; + } + } + if ( res == null ) + { + IStackFrameInfo frameInfo = (IStackFrameInfo)stackFrame.getAdapter( IStackFrameInfo.class ); + if ( frameInfo != null && frameInfo.getFile() != null && frameInfo.getFile().length() > 0 ) + { + res = new FileNotFoundElement( stackFrame ); + } + else // don't show in editor + { + res = new NoSymbolOrSourceElement( stackFrame ); + } + } + return res; + } + + public IProject getProject() + { + return fProject; + } + + protected void saveChanges( ILaunchConfiguration configuration, IPersistableSourceLocator locator ) + { + try + { + ILaunchConfigurationWorkingCopy copy = configuration.copy( configuration.getName() ); + copy.setAttribute( ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, locator.getMemento() ); + copy.doSave(); + } + catch( CoreException e ) + { + CDebugUIPlugin.errorDialog( e.getMessage(), (IStatus)null ); + } + } + + private SourceSelectionDialog createSourceSelectionDialog( List list ) + { + SourceSelectionDialog dialog = new SourceSelectionDialog( CDebugUIPlugin.getActiveWorkbenchShell() ); + dialog.setInput( list.toArray() ); + dialog.setContentProvider( new ArrayContentProvider() ); + dialog.setLabelProvider( new SourceElementLabelProvider() ); + dialog.setTitle( "Selection needed" ); + dialog.setMessage( "Debugger has found multiple files with the same name.\nPlease select one associated with the selected stack frame." ); + dialog.setInitialSelections( new Object[] { list.get( 0 ) } ); + return dialog; + } + + private void cacheSourceElement( IStackFrame frame, Object sourceElement, boolean alwaysMapToSelection ) + { + if ( alwaysMapToSelection ) + { + String name = getFileName( frame ); + if ( name != null ) + { + if ( fNamesToSource == null ) + fNamesToSource = new HashMap(); + fNamesToSource.put( name, sourceElement ); + } + } + else + { + if ( fFramesToSource == null ) + fFramesToSource = new HashMap(); + fFramesToSource.put( frame, sourceElement ); + } + } + + private Object cacheLookup( IStackFrame frame ) + { + String name = getFileName( frame ); + if ( name != null && fNamesToSource != null ) + { + Object result = fNamesToSource.get( name ); + if ( result != null ) + return result; + } + return ( fFramesToSource != null ) ? fFramesToSource.get( frame ) : null; + } + + private String getFileName( IStackFrame frame ) + { + IStackFrameInfo frameInfo = (IStackFrameInfo)frame.getAdapter( IStackFrameInfo.class ); + if ( frameInfo != null ) + { + String name = frameInfo.getFile(); + if ( name != null && name.trim().length() > 0 ) + return name.trim(); + } + return null; + } + + private ICSourceLocator getCSourceLocator() + { + return fSourceLocator; + } + + private IPersistableSourceLocator getPersistableSourceLocator() + { + ICSourceLocator sl = getCSourceLocator(); + return ( sl instanceof IPersistableSourceLocator ) ? (IPersistableSourceLocator)sl : null; + } + + /** + * Throws an internal error exception + */ + private void abort( String message, Throwable e ) throws CoreException + { + IStatus s = new Status( IStatus.ERROR, CDebugUIPlugin.getUniqueIdentifier(), 0, message, e ); + throw new CoreException( s ); + } + + private boolean isEmpty( String string ) + { + return string == null || string.length() == 0; + } + + private IProject getProject( ILaunchConfiguration configuration ) throws CoreException + { + String projectName = configuration.getAttribute( ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null ); + if ( !isEmpty( projectName ) ) + { + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject( projectName ); + if ( project.exists() ) + { + return project; + } + } + abort( MessageFormat.format( "Project \"{0}\" does not exist.", new String[] { projectName } ), null ); + return null; + } +}