From ada5f6bb241671c3f099bc783ad87157da636f30 Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Tue, 10 May 2005 20:31:02 +0000 Subject: [PATCH] patch from Devin Steffler RE Open Declaration/Definition bugs 86829, 93589, 94360 --- .../tests/ast2/AST2SelectionParseTest.java | 25 - .../core/dom/parser/c/CASTDeclarator.java | 36 +- .../dom/parser/cpp/CPPASTNamespaceAlias.java | 2 +- .../cdt/core/search/DOMSearchUtil.java | 85 +- .../eclipse/cdt/ui/tests/DOMAST/DOMAST.java | 2 + .../eclipse/cdt/ui/tests/AutomatedSuite.java | 10 +- .../CPPSelectionTestsNoIndexer.java | 960 ++++++++++++++++++ .../CSelectionTestsNoIndexer.java | 672 ++++++++++++ .../text/selectiontests/SelectionTests.java | 311 ------ 9 files changed, 1721 insertions(+), 382 deletions(-) create mode 100644 core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selectiontests/CPPSelectionTestsNoIndexer.java create mode 100644 core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selectiontests/CSelectionTestsNoIndexer.java delete mode 100644 core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selectiontests/SelectionTests.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SelectionParseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SelectionParseTest.java index b4910515d83..732f83aac6b 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SelectionParseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SelectionParseTest.java @@ -751,31 +751,6 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest { assertEquals(((ICPPClassType)name.resolveBinding()).getName(), "A"); //$NON-NLS-1$ } - // TODO no template support yet for new AST? -// public void testBug72814() throws Exception{ -// Writer writer = new StringWriter(); -// writer.write( "namespace N{ \n"); //$NON-NLS-1$ -// writer.write( " template < class T > class AAA { T _t };\n"); //$NON-NLS-1$ -// writer.write( "} \n"); //$NON-NLS-1$ -// writer.write( "N::AAA a; \n"); //$NON-NLS-1$ -// -// String code = writer.toString(); -// int startIndex = code.indexOf( "AAA" ); //$NON-NLS-1$ -// int length = "AAA".length(); //$NON-NLS-1$ -// IASTNode node = parse( code, ParserLanguage.CPP, startIndex, length ); -// assertNotNull(node); -// -//// assertTrue( node instanceof IASTClassSpecifier ); -//// assertEquals( ((IASTClassSpecifier)node).getName(), "AAA" ); //$NON-NLS-1$ -// -// length = "AAA".length(); //$NON-NLS-1$ -// node = parse( code, ParserLanguage.CPP, startIndex, length ); -// assertNotNull(node); -// -//// assertTrue( node instanceof IASTClassSpecifier ); -//// assertEquals( ((IASTClassSpecifier)node).getName(), "AAA" ); //$NON-NLS-1$ -// } - public void testBug72710() throws Exception { Writer writer = new StringWriter(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTDeclarator.java index c787d5c05a4..ec69e8541ff 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTDeclarator.java @@ -13,10 +13,12 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTypeId; @@ -127,19 +129,26 @@ public class CASTDeclarator extends CASTNode implements IASTDeclarator { if( n == this.name ) { IASTNode getParent = getParent(); + boolean fnDtor = ( this instanceof IASTFunctionDeclarator ); if( getParent instanceof IASTDeclaration ) { if( getParent instanceof IASTFunctionDefinition ) return r_definition; if( getParent instanceof IASTSimpleDeclaration ) { - IASTSimpleDeclaration sd = (IASTSimpleDeclaration) getParent; - if( sd.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_extern ) - return r_declaration; - if( getInitializer() == null ) - return r_declaration; + IASTSimpleDeclaration sd = (IASTSimpleDeclaration) getParent; + int storage = sd.getDeclSpecifier().getStorageClass(); + if( getInitializer() != null || storage == IASTDeclSpecifier.sc_typedef ) + return r_definition; + + if( storage == IASTDeclSpecifier.sc_extern || + storage == IASTDeclSpecifier.sc_static ) + { + return r_declaration; + } + + return fnDtor ? r_declaration : r_definition; } - return r_definition; } if( getParent instanceof IASTTypeId ) return r_reference; @@ -154,17 +163,22 @@ public class CASTDeclarator extends CASTNode implements IASTDeclarator { return r_definition; if( getParent instanceof IASTSimpleDeclaration ) { - IASTSimpleDeclaration sd = (IASTSimpleDeclaration) getParent; - if( sd.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_extern ) - return r_declaration; - if( getInitializer() != null ) + if( getInitializer() != null ) return r_definition; + IASTSimpleDeclaration sd = (IASTSimpleDeclaration) getParent; + int storage = sd.getDeclSpecifier().getStorageClass(); + if( storage == IASTDeclSpecifier.sc_extern || + storage == IASTDeclSpecifier.sc_static) + return r_declaration; } - return r_definition; + return fnDtor ? r_declaration : r_definition; } if( t instanceof IASTTypeId ) return r_reference; } + + if( getParent instanceof IASTParameterDeclaration ) + return ( n.toCharArray().length > 0 ) ? r_definition : r_declaration; } return r_unclear; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNamespaceAlias.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNamespaceAlias.java index b006725f2a7..cf0da64b4e5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNamespaceAlias.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNamespaceAlias.java @@ -69,7 +69,7 @@ public class CPPASTNamespaceAlias extends CPPASTNode implements * @see org.eclipse.cdt.core.dom.ast.IASTNameOwner#getRoleForName(org.eclipse.cdt.core.dom.ast.IASTName) */ public int getRoleForName(IASTName n) { - if( alias == n ) return r_declaration; + if( alias == n ) return r_definition; if( qualifiedName == n ) return r_reference; return r_unclear; } diff --git a/core/org.eclipse.cdt.core/search/org/eclipse/cdt/core/search/DOMSearchUtil.java b/core/org.eclipse.cdt.core/search/org/eclipse/cdt/core/search/DOMSearchUtil.java index d4d3556e049..83812fc899c 100644 --- a/core/org.eclipse.cdt.core/search/org/eclipse/cdt/core/search/DOMSearchUtil.java +++ b/core/org.eclipse.cdt.core/search/org/eclipse/cdt/core/search/DOMSearchUtil.java @@ -34,7 +34,9 @@ import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.c.CASTVisitor; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; @@ -47,6 +49,7 @@ import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.search.ICSearchConstants.LimitTo; import org.eclipse.cdt.core.search.ICSearchConstants.SearchFor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitMethod; import org.eclipse.cdt.internal.core.search.matching.CSearchPattern; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -88,6 +91,9 @@ public class DOMSearchUtil { } private static CSearchPattern createPattern( IBinding binding, LimitTo limitTo, boolean caseSensitive) { + if (binding == null) + return null; + // build the SearchFor/pattern based on the IBinding SearchFor searchFor = createSearchFor(binding); if (binding instanceof IFunction) { @@ -187,7 +193,7 @@ public class DOMSearchUtil { public static IASTName[] getSelectedNamesFrom(IASTTranslationUnit tu, int offset, int length, ParserLanguage lang) { IASTNode node = null; try{ - node = tu.selectNodeForLocation(tu.getFilePath(), offset, length); // TODO Devin untested tu.getContainingFilename() ... + node = tu.selectNodeForLocation(tu.getFilePath(), offset, length); } catch (ParseError er){} catch ( VirtualMachineError vmErr){ @@ -335,36 +341,55 @@ public class DOMSearchUtil { * @return IASTName[] declarations, references, or both depending on limitTo that correspond to the IASTName searchName searched for */ public static IASTName[] getNamesFromDOM(IASTName searchName, LimitTo limitTo) { - IASTName[] names = null; - IASTTranslationUnit tu = searchName.getTranslationUnit(); - - if (tu == null) { - return BLANK_NAME_ARRAY; - } - - // fix for 92632 - IBinding binding = searchName.resolveBinding(); - if (binding instanceof ICPPTemplateInstance) { - if (((ICPPTemplateInstance)binding).getTemplateDefinition() != null) - binding = ((ICPPTemplateInstance)binding).getTemplateDefinition(); - } - - if (limitTo == ICSearchConstants.DECLARATIONS) { - names = tu.getDeclarations(binding); - } else if (limitTo == ICSearchConstants.REFERENCES) { - names = tu.getReferences(binding); - } else if (limitTo == ICSearchConstants.DEFINITIONS) { - names = tu.getDefinitions(binding); - } else if (limitTo == ICSearchConstants.ALL_OCCURRENCES){ - names = tu.getDeclarations(binding); - names = (IASTName[])ArrayUtil.addAll(IASTName.class, names, tu.getReferences(binding)); - } else { // assume ALL - names = tu.getDeclarations(binding); - names = (IASTName[])ArrayUtil.addAll(IASTName.class, names, tu.getReferences(binding)); - } - - return names; + IASTName[] names = null; + IASTTranslationUnit tu = searchName.getTranslationUnit(); + + if (tu == null) { + return BLANK_NAME_ARRAY; + } + + IBinding binding = searchName.resolveBinding(); + names = getNames(tu, binding, limitTo); + + if (names == null || names.length == 0) { // try alternate strategies + // fix for 92632 + if (binding instanceof ICPPTemplateInstance) { + if (((ICPPTemplateInstance)binding).getTemplateDefinition() != null) { + binding = ((ICPPTemplateInstance)binding).getTemplateDefinition(); + names = getNames(tu, binding, limitTo); + } + } + + // fix for 86829 + try { + if (binding instanceof ICPPConstructor && binding.getScope() instanceof ICPPClassScope) { + binding = ((ICPPClassScope)binding.getScope()).getClassType(); + names = getNames(tu, binding, limitTo); + } + } catch (DOMException e) {} + } + + return names; } + + private static IASTName[] getNames(IASTTranslationUnit tu, IBinding binding, LimitTo limitTo) { + IASTName[] names = null; + if (limitTo == ICSearchConstants.DECLARATIONS) { + names = tu.getDeclarations(binding); + } else if (limitTo == ICSearchConstants.REFERENCES) { + names = tu.getReferences(binding); + } else if (limitTo == ICSearchConstants.DEFINITIONS) { + names = tu.getDefinitions(binding); + } else if (limitTo == ICSearchConstants.ALL_OCCURRENCES){ + names = tu.getDeclarations(binding); + names = (IASTName[])ArrayUtil.addAll(IASTName.class, names, tu.getReferences(binding)); + } else { // assume ALL + names = tu.getDeclarations(binding); + names = (IASTName[])ArrayUtil.addAll(IASTName.class, names, tu.getReferences(binding)); + } + + return names; + } /** * The CPPNameCollector used to get IASTNames from an IASTNode. diff --git a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java index 362ec79b3ad..3832ef761e1 100644 --- a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java +++ b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java @@ -473,6 +473,7 @@ public class DOMAST extends ViewPart { * @see java.lang.Runnable#run() */ public void run() { + if (view == null) return; view.refresh(); if (view.getTree().getItems().length > 0) { @@ -684,6 +685,7 @@ public class DOMAST extends ViewPart { } public void setContentProvider(ViewContentProvider vcp) { + if (viewer == null) return; viewer.setContentProvider(vcp); } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java index d79d6067c2c..2d181dafbdd 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java @@ -48,7 +48,8 @@ import org.eclipse.cdt.ui.tests.text.contentassist.CompletionTest_VariableType_N import org.eclipse.cdt.ui.tests.text.contentassist.CompletionTest_VariableType_NoPrefix; import org.eclipse.cdt.ui.tests.text.contentassist.CompletionTest_VariableType_Prefix; import org.eclipse.cdt.ui.tests.text.contentassist.ContentAssistTests; -import org.eclipse.cdt.ui.tests.text.selectiontests.SelectionTests; +import org.eclipse.cdt.ui.tests.text.selectiontests.CPPSelectionTestsNoIndexer; +import org.eclipse.cdt.ui.tests.text.selectiontests.CSelectionTestsNoIndexer; @@ -115,11 +116,12 @@ public class AutomatedSuite extends TestSuite { addTest( ContentAssistTests.suite() ); addTest( RegressionTestsUISuite.suite() ); - // selection tests - addTest( SelectionTests.suite() ); - // Failed Tests addTest(CompletionFailedTest_MemberReference_Arrow_Prefix2.suite()); + + // selection tests with no indexer + addTest( CPPSelectionTestsNoIndexer.suite() ); + addTest( CSelectionTestsNoIndexer.suite() ); } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selectiontests/CPPSelectionTestsNoIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selectiontests/CPPSelectionTestsNoIndexer.java new file mode 100644 index 00000000000..6f0994d3fe1 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selectiontests/CPPSelectionTestsNoIndexer.java @@ -0,0 +1,960 @@ +/********************************************************************** + * Copyright (c) 2004, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.ui.tests.text.selectiontests; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.InputStream; +import java.io.StringWriter; +import java.io.Writer; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.search.DOMSearchUtil; +import org.eclipse.cdt.core.testplugin.CProjectHelper; +import org.eclipse.cdt.core.testplugin.FileManager; +import org.eclipse.cdt.internal.core.dom.parser.ASTNode; +import org.eclipse.cdt.internal.core.parser.ParserException; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.texteditor.AbstractTextEditor; + +/** + * It is required to test the selection performance independent of the indexer to make sure that the DOM is functioning properly. + * + * Indexer bugs can drastically influence the correctness of these tests so the indexer has to be off when performing them. + * + * @author dsteffle + */ +public class CPPSelectionTestsNoIndexer extends TestCase { + + private static final String INDEX_FILE_ID = "2946365241"; //$NON-NLS-1$ + static NullProgressMonitor monitor; + static IWorkspace workspace; + static IProject project; + static ICProject cPrj; + static FileManager fileManager; + static boolean disabledHelpContributions = false; + { + //(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset(); + monitor = new NullProgressMonitor(); + + workspace = ResourcesPlugin.getWorkspace(); + + try { + cPrj = CProjectHelper.createCCProject("CPPSelectionTestsNoIndexer", "bin"); //$NON-NLS-1$ //$NON-NLS-2$ + + project = cPrj.getProject(); + + IPath pathLoc = CCorePlugin.getDefault().getStateLocation(); + File indexFile = new File(pathLoc.append(INDEX_FILE_ID + ".index").toOSString()); //$NON-NLS-1$ + if (indexFile.exists()) + indexFile.delete(); + } catch ( CoreException e ) { + /*boo*/ + } + if (project == null) + fail("Unable to create project"); //$NON-NLS-1$ + + //Create file manager + fileManager = new FileManager(); + } + public CPPSelectionTestsNoIndexer() + { + super(); + } + /** + * @param name + */ + public CPPSelectionTestsNoIndexer(String name) + { + super(name); + } + + public static Test suite() { + TestSuite suite = new TestSuite( CPPSelectionTestsNoIndexer.class ); + suite.addTest( new CPPSelectionTestsNoIndexer("cleanupProject") ); //$NON-NLS-1$ + return suite; + } + + public void cleanupProject() throws Exception { + try{ + project.delete( true, false, monitor ); + project = null; + } catch( Throwable e ){ + /*boo*/ + } + } + + protected void tearDown() throws Exception { + if( project == null || !project.exists() ) + return; + + IResource [] members = project.members(); + for( int i = 0; i < members.length; i++ ){ + if( members[i].getName().equals( ".project" ) || members[i].getName().equals( ".cdtproject" ) ) //$NON-NLS-1$ //$NON-NLS-2$ + continue; + try{ + members[i].delete( false, monitor ); + } catch( Throwable e ){ + /*boo*/ + } + } + } + + protected IFile importFile(String fileName, String contents ) throws Exception{ + //Obtain file handle + IFile file = project.getProject().getFile(fileName); + + InputStream stream = new ByteArrayInputStream( contents.getBytes() ); + //Create file input stream + if( file.exists() ) + file.setContents( stream, false, false, monitor ); + else + file.create( stream, false, monitor ); + + fileManager.addFile(file); + + return file; + } + + protected IASTNode testF3(IFile file, int offset) throws ParserException { + return testF3(file, offset, 0); + } + + protected IASTNode testF3(IFile file, int offset, int length) throws ParserException { + disableIndex(); + + if (offset < 0) + throw new ParserException("offset can not be less than 0 and was " + offset); //$NON-NLS-1$ + + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IEditorPart part = null; + try { + part = page.openEditor(new FileEditorInput(file), "org.eclipse.cdt.ui.editor.CEditor"); //$NON-NLS-1$ + } catch (PartInitException e) { + assertFalse(true); + } + + if (part instanceof AbstractTextEditor) { + ((AbstractTextEditor)part).getSelectionProvider().setSelection(new TextSelection(offset,length)); + + final IAction action = ((AbstractTextEditor)part).getAction("OpenDeclarations"); //$NON-NLS-1$ + action.run(); + + // the action above should highlight the declaration, so now retrieve it and use that selection to get the IASTName selected on the TU + ISelection sel = ((AbstractTextEditor)part).getSelectionProvider().getSelection(); + + if (sel instanceof TextSelection) { + IASTName[] names = DOMSearchUtil.getSelectedNamesFrom(file, ((TextSelection)sel).getOffset(), ((TextSelection)sel).getLength()); + + if (names.length == 0) { + assertFalse(true); + } else { + return names[0]; + } + } + } + + return null; + } + + protected IASTNode testF2(IFile file, int offset) throws ParserException { + return testF2(file, offset, 0); + } + + protected IASTNode testF2(IFile file, int offset, int length) throws ParserException { + disableIndex(); + + if (offset < 0) + throw new ParserException("offset can not be less than 0 and was " + offset); //$NON-NLS-1$ + + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IEditorPart part = null; + try { + part = page.openEditor(new FileEditorInput(file), "org.eclipse.cdt.ui.editor.CEditor"); //$NON-NLS-1$ + } catch (PartInitException e) { + assertFalse(true); + } + + if (part instanceof AbstractTextEditor) { + ((AbstractTextEditor)part).getSelectionProvider().setSelection(new TextSelection(offset,length)); + + final IAction action = ((AbstractTextEditor)part).getAction("OpenDefinition"); //$NON-NLS-1$ + action.run(); + + // the action above should highlight the declaration, so now retrieve it and use that selection to get the IASTName selected on the TU + ISelection sel = ((AbstractTextEditor)part).getSelectionProvider().getSelection(); + + if (sel instanceof TextSelection) { + IASTName[] names = DOMSearchUtil.getSelectedNamesFrom(file, ((TextSelection)sel).getOffset(), ((TextSelection)sel).getLength()); + + if (names == null || names.length == 0) + return null; + + return names[0]; + } + } + + return null; + } + + private void disableIndex() { + IPath pathLoc = CCorePlugin.getDefault().getStateLocation(); + File indexFile = new File(pathLoc.append(INDEX_FILE_ID + ".index").toOSString()); //$NON-NLS-1$ + if (indexFile.exists()) + indexFile.delete(); + } + + public void testBug93281() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("class Point{ \n"); //$NON-NLS-1$ + buffer.append("public: \n"); //$NON-NLS-1$ + buffer.append("Point(): xCoord(0){} \n"); //$NON-NLS-1$ + buffer.append("Point& operator=(const Point &rhs){return *this;} // line A\n"); //$NON-NLS-1$ + buffer.append("void* operator new [ ] (unsigned int);\n"); //$NON-NLS-1$ + buffer.append("private: \n"); //$NON-NLS-1$ + buffer.append("int xCoord; \n"); //$NON-NLS-1$ + buffer.append("}; \n"); //$NON-NLS-1$ + buffer.append("static const Point zero;\n"); //$NON-NLS-1$ + buffer.append("int main(int argc, char **argv) { \n"); //$NON-NLS-1$ + buffer.append("Point *p2 = new Point(); \n"); //$NON-NLS-1$ + buffer.append("p2-> operator // /* operator */ // F3 in the middle \n"); //$NON-NLS-1$ + buffer.append("//of \"operator\" should work\n"); //$NON-NLS-1$ + buffer.append("// \\n"); //$NON-NLS-1$ + buffer.append("/* */\n"); //$NON-NLS-1$ + buffer.append("=(zero); // line B\n"); //$NON-NLS-1$ + buffer.append("p2->operator /* oh yeah */ new // F3 in the middle of \"operator\"\n"); //$NON-NLS-1$ + buffer.append("// should work\n"); //$NON-NLS-1$ + buffer.append("//\n"); //$NON-NLS-1$ + buffer.append("[ /* sweet */ ] //\n"); //$NON-NLS-1$ + buffer.append("(2);\n"); //$NON-NLS-1$ + buffer.append("return (0); \n"); //$NON-NLS-1$ + buffer.append("}\n"); //$NON-NLS-1$ + + String code = buffer.toString(); + IFile file = importFile("test93281.cpp", code); //$NON-NLS-1$ + + int offset = code.indexOf("p2->operator") + 6; //$NON-NLS-1$ + IASTNode node = testF3(file, offset); + + assertTrue(node instanceof IASTName); + assertEquals(((IASTName)node).toString(), "operator new[]"); //$NON-NLS-1$ + assertEquals(((ASTNode)node).getOffset(), 183); + assertEquals(((ASTNode)node).getLength(), 16); + + offset = code.indexOf("p2-> operator") + 11; //$NON-NLS-1$ + node = testF3(file, offset); + + assertTrue(node instanceof IASTName); + assertEquals(((IASTName)node).toString(), "operator ="); //$NON-NLS-1$ + assertEquals(((ASTNode)node).getOffset(), 121); + assertEquals(((ASTNode)node).getLength(), 9); + + } + + public void testBasicDefinition() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("extern int MyInt; // MyInt is in another file\n"); //$NON-NLS-1$ + buffer.append("extern const int MyConst; // MyConst is in another file\n"); //$NON-NLS-1$ + buffer.append("void MyFunc(int); // often used in header files\n"); //$NON-NLS-1$ + buffer.append("struct MyStruct; // often used in header files\n"); //$NON-NLS-1$ + buffer.append("typedef int NewInt; // a normal typedef statement\n"); //$NON-NLS-1$ + buffer.append("class MyClass; // often used in header files\n"); //$NON-NLS-1$ + buffer.append("int MyInt;\n"); //$NON-NLS-1$ + buffer.append("extern const int MyConst = 42;\n"); //$NON-NLS-1$ + buffer.append("void MyFunc(int a) { cout << a << endl; }\n"); //$NON-NLS-1$ + buffer.append("struct MyStruct { int Member1; int Member2; };\n"); //$NON-NLS-1$ + buffer.append("class MyClass { int MemberVar; };\n"); //$NON-NLS-1$ + + String code = buffer.toString(); + IFile file = importFile("testBasicDefinition.cpp", code); //$NON-NLS-1$ + + int offset = code.indexOf("MyInt;\n") + 2; //$NON-NLS-1$ + IASTNode def = testF2(file, offset); + IASTNode decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "MyInt"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 11); + assertEquals(((ASTNode)decl).getLength(), 5); + assertEquals(((IASTName)def).toString(), "MyInt"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 330); + assertEquals(((ASTNode)def).getLength(), 5); + + offset = code.indexOf("MyConst = 42") + 2; //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "MyConst"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 69); + assertEquals(((ASTNode)decl).getLength(), 7); + assertEquals(((IASTName)def).toString(), "MyConst"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 354); + assertEquals(((ASTNode)def).getLength(), 7); + + offset = code.indexOf("MyFunc(int a)") + 2; //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "MyFunc"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 115); + assertEquals(((ASTNode)decl).getLength(), 6); + assertEquals(((IASTName)def).toString(), "MyFunc"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 373); + assertEquals(((ASTNode)def).getLength(), 6); + + offset = code.indexOf("MyStruct {") + 2; //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "MyStruct"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 171); + assertEquals(((ASTNode)decl).getLength(), 8); + assertEquals(((IASTName)def).toString(), "MyStruct"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 417); + assertEquals(((ASTNode)def).getLength(), 8); + + offset = code.indexOf("MyClass {") + 2; //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "MyClass"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 278); + assertEquals(((ASTNode)decl).getLength(), 7); + assertEquals(((IASTName)def).toString(), "MyClass"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 463); + assertEquals(((ASTNode)def).getLength(), 7); + } + + public void testBasicTemplateInstance() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "namespace N{ \n"); //$NON-NLS-1$ + writer.write( " template < class T > class AAA { T _t; };\n"); //$NON-NLS-1$ + writer.write( "}; \n"); //$NON-NLS-1$ + writer.write( "N::AAA a; \n"); //$NON-NLS-1$ + + String code = writer.toString(); + IFile file = importFile("testBasicTemplateInstance.cpp", code); //$NON-NLS-1$ + + int offset = code.indexOf("AAA"); //$NON-NLS-1$ + IASTNode def1 = testF2(file, offset, 3); + IASTNode decl1 = testF3(file, offset, 3); + assertTrue(def1 instanceof IASTName); + assertTrue(decl1 instanceof IASTName); + assertEquals(((IASTName)decl1).toString(), "AAA"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl1).getOffset(), 74); + assertEquals(((ASTNode)decl1).getLength(), 3); + assertEquals(((IASTName)def1).toString(), "AAA"); //$NON-NLS-1$ + assertEquals(((ASTNode)def1).getOffset(), 74); + assertEquals(((ASTNode)def1).getLength(), 3); + + IASTNode def2 = testF2(file, offset, 8); + IASTNode decl2 = testF3(file, offset, 8); + assertTrue(def2 instanceof IASTName); + assertTrue(decl2 instanceof IASTName); + assertEquals(((IASTName)decl2).toString(), "AAA"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl2).getOffset(), 74); + assertEquals(((ASTNode)decl2).getLength(), 3); + assertEquals(((IASTName)def2).toString(), "AAA"); //$NON-NLS-1$ + assertEquals(((ASTNode)def2).getOffset(), 74); + assertEquals(((ASTNode)def2).getLength(), 3); + } + + public void testBug86829A() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("class X {\n"); //$NON-NLS-1$ + buffer.append("public:\n"); //$NON-NLS-1$ + buffer.append("X(int); // openReferences fails to find the constructor in g()\n"); //$NON-NLS-1$ + buffer.append("};\n"); //$NON-NLS-1$ + buffer.append("X f(X);\n"); //$NON-NLS-1$ + buffer.append("void g()\n"); //$NON-NLS-1$ + buffer.append("{\n"); //$NON-NLS-1$ + buffer.append("X b = f(X(2)); // openDeclarations on X(int) finds the class and not \n"); //$NON-NLS-1$ + buffer.append("}\n"); //$NON-NLS-1$ + + String code = buffer.toString(); + IFile file = importFile("testBug86829A.cpp", code); //$NON-NLS-1$ + + int offset = code.indexOf("X(2)"); //$NON-NLS-1$ + IASTNode decl = testF3(file, offset); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 18); + assertEquals(((ASTNode)decl).getLength(), 1); + } + + public void testBug86829B() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("class X {\n"); //$NON-NLS-1$ + buffer.append("public:\n"); //$NON-NLS-1$ + buffer.append("operator int();\n"); //$NON-NLS-1$ + buffer.append("};\n"); //$NON-NLS-1$ + buffer.append("class Y {\n"); //$NON-NLS-1$ + buffer.append("public:\n"); //$NON-NLS-1$ + buffer.append("operator X();\n"); //$NON-NLS-1$ + buffer.append("};\n"); //$NON-NLS-1$ + buffer.append("Y a;\n"); //$NON-NLS-1$ + buffer.append("int c = X(a); // OK: a.operator X().operator int()\n"); //$NON-NLS-1$ + + String code = buffer.toString(); + IFile file = importFile("testBug86829B.cpp", code); //$NON-NLS-1$ + + int offset = code.indexOf("X(a);"); //$NON-NLS-1$ + IASTNode def = testF2(file, offset); + IASTNode decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 6); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 6); + assertEquals(((ASTNode)def).getLength(), 1); + } + + // taken from C++ spec 3.1-3: + /* + // all but one of the following are definitions: + int a; // defines a + extern const int c = 1; // defines c + int f(int x) { return x+a; } // defines f and defines x + struct S { int a; int b; }; // defines S, S::a, and S::b + struct X { // defines X + int x; // defines nonstatic data member x + static int y; // declares static data member y + X(): x(0) { } // defines a constructor of X + }; + int X::y = 1; // defines X::y + enum { up, down }; // defines up and down + namespace N { int d; } // defines N and N::d + namespace N1 = N; // defines N1 + X anX; // defines anX + // whereas these are just declarations: + extern int a; // declares a + extern const int c; // declares c + int f(int); // declares f + struct S; // declares S + typedef int Int; // declares Int + extern X anotherX; // declares anotherX + using N::d; // declares N::d + */ + public void testCPPSpecDeclsDefs() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("int a; // defines a\n"); //$NON-NLS-1$ + buffer.append("extern const int c = 1; // defines c\n"); //$NON-NLS-1$ + buffer.append("int f(int x) { return x+a; } // defines f and defines x\n"); //$NON-NLS-1$ + buffer.append("struct S { int a; int b; }; // defines S, S::a, and S::b\n"); //$NON-NLS-1$ + buffer.append("struct X { // defines X\n"); //$NON-NLS-1$ + buffer.append("int x; // defines nonstatic data member x\n"); //$NON-NLS-1$ + buffer.append("static int y; // declares static data member y\n"); //$NON-NLS-1$ + buffer.append("X(): x(0) { } // defines a constructor of X\n"); //$NON-NLS-1$ + buffer.append("};\n"); //$NON-NLS-1$ + buffer.append("int X::y = 1; // defines X::y\n"); //$NON-NLS-1$ + buffer.append("enum { up, down }; // defines up and down\n"); //$NON-NLS-1$ + buffer.append("namespace N { int d; } // defines N and N::d\n"); //$NON-NLS-1$ + buffer.append("namespace N1 = N; // defines N1\n"); //$NON-NLS-1$ + buffer.append("X anX; // defines anX\n"); //$NON-NLS-1$ + buffer.append("extern int a; // declares a\n"); //$NON-NLS-1$ + buffer.append("extern const int c; // declares c\n"); //$NON-NLS-1$ + buffer.append("int f(int); // declares f\n"); //$NON-NLS-1$ + buffer.append("struct S; // declares S\n"); //$NON-NLS-1$ + buffer.append("typedef int Int; // declares Int\n"); //$NON-NLS-1$ + buffer.append("extern X anotherX; // declares anotherX\n"); //$NON-NLS-1$ + buffer.append("using N::d; // declares N::d\n"); //$NON-NLS-1$ + + String code = buffer.toString(); + IFile file = importFile("testCPPSpecDeclsDefs.cpp", code); //$NON-NLS-1$ + + int offset = code.indexOf("a; // defines a"); //$NON-NLS-1$ + IASTNode def = testF2(file, offset); + IASTNode decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 4); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 4); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("c = 1; // defines c"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "c"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 37); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "c"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 37); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("f(int x) { return x+a; } // defines f and defines x"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "f"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 61); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "f"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 61); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("x) { return x+a; } // defines f and defines x"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 67); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 67); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("x+a; } // defines f and defines x"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 67); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 67); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("x+a; } // defines f and defines x"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 67); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 67); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("a; } // defines f and defines x"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 4); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 4); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("S { int a; int b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "S"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 120); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "S"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 120); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("a; int b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 128); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 128); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "b"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 135); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "b"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 135); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("X { // defines X"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 177); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 177); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("x; // defines nonstatic data member x"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 198); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 198); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("y; // declares static data member y"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "y"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 247); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "y"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 337); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("X(): x(0) { } // defines a constructor of X"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 283); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 283); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("x(0) { } // defines a constructor of X"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 198); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 198); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("X::y = 1; // defines X::y"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 177); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 177); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("y = 1; // defines X::y"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "y"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 247); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "y"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 337); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("up, down }; // defines up and down"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "up"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 367); + assertEquals(((ASTNode)decl).getLength(), 2); + assertEquals(((IASTName)def).toString(), "up"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 367); + assertEquals(((ASTNode)def).getLength(), 2); + + offset = code.indexOf("down }; // defines up and down"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "down"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 371); + assertEquals(((ASTNode)decl).getLength(), 4); + assertEquals(((IASTName)def).toString(), "down"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 371); + assertEquals(((ASTNode)def).getLength(), 4); + + offset = code.indexOf("N { int d; } // defines N and N::d"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "N"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 412); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "N"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 412); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("d; } // defines N and N::d"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "d"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 420); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "d"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 420); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("N1 = N; // defines N1"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "N1"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 457); + assertEquals(((ASTNode)decl).getLength(), 2); + assertEquals(((IASTName)def).toString(), "N1"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 457); + assertEquals(((ASTNode)def).getLength(), 2); + + offset = code.indexOf("N; // defines N1"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "N"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 412); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "N"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 412); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("X anX; // defines anX"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 177); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 177); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("anX; // defines anX"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "anX"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 481); + assertEquals(((ASTNode)decl).getLength(), 3); + assertEquals(((IASTName)def).toString(), "anX"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 481); + assertEquals(((ASTNode)def).getLength(), 3); + + offset = code.indexOf("a; // declares a"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 4); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 4); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("c; // declares c"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "c"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 37); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "c"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 37); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("f(int); // declares f"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "f"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 61); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "f"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 61); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("S; // declares S"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "S"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 120); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "S"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 120); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("Int; // declares Int"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertNull(def); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "Int"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 625); + assertEquals(((ASTNode)decl).getLength(), 3); + + offset = code.indexOf("X anotherX; // declares anotherX"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 177); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 177); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("anotherX; // declares anotherX"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertNull(def); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "anotherX"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 655); + assertEquals(((ASTNode)decl).getLength(), 8); + + offset = code.indexOf("N::d; // declares N::d"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "N"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 412); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "N"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 412); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("d; // declares N::d"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "d"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 420); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "d"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 420); + assertEquals(((ASTNode)def).getLength(), 1); + } + + public void testNoDefinitions() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("extern int a1; // declares a\n"); //$NON-NLS-1$ + buffer.append("extern const int c1; // declares c\n"); //$NON-NLS-1$ + buffer.append("int f1(int); // declares f\n"); //$NON-NLS-1$ + buffer.append("struct S1; // declares S\n"); //$NON-NLS-1$ + buffer.append("typedef int Int; // declares Int\n"); //$NON-NLS-1$ + + String code = buffer.toString(); + IFile file = importFile("testNoDefinitions.cpp", code); //$NON-NLS-1$ + + int offset = code.indexOf("a1; // declares a"); //$NON-NLS-1$ + IASTNode def = testF2(file, offset); + IASTNode decl = testF3(file, offset); + assertNull(def); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "a1"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 11); + assertEquals(((ASTNode)decl).getLength(), 2); + + offset = code.indexOf("c1; // declares c"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertNull(def); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "c1"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 46); + assertEquals(((ASTNode)decl).getLength(), 2); + + offset = code.indexOf("f1(int); // declares f"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertNull(def); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "f1"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 68); + assertEquals(((ASTNode)decl).getLength(), 2); + + offset = code.indexOf("S1; // declares S"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertNull(def); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "S1"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 98); + assertEquals(((ASTNode)decl).getLength(), 2); + + offset = code.indexOf("Int; // declares Int"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertNull(def); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "Int"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 128); + assertEquals(((ASTNode)decl).getLength(), 3); + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selectiontests/CSelectionTestsNoIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selectiontests/CSelectionTestsNoIndexer.java new file mode 100644 index 00000000000..e897f413554 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selectiontests/CSelectionTestsNoIndexer.java @@ -0,0 +1,672 @@ +/********************************************************************** + * Copyright (c) 2004, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.ui.tests.text.selectiontests; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.InputStream; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.search.DOMSearchUtil; +import org.eclipse.cdt.core.testplugin.CProjectHelper; +import org.eclipse.cdt.core.testplugin.FileManager; +import org.eclipse.cdt.internal.core.dom.parser.ASTNode; +import org.eclipse.cdt.internal.core.parser.ParserException; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.texteditor.AbstractTextEditor; + +/** + * It is required to test the selection performance independent of the indexer to make sure that the DOM is functioning properly. + * + * Indexer bugs can drastically influence the correctness of these tests so the indexer has to be off when performing them. + * + * @author dsteffle + */ +public class CSelectionTestsNoIndexer extends TestCase { + + private static final String INDEX_FILE_ID = "2324852323"; //$NON-NLS-1$ + static NullProgressMonitor monitor; + static IWorkspace workspace; + static IProject project; + static ICProject cPrj; + static FileManager fileManager; + static boolean disabledHelpContributions = false; + { + //(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset(); + monitor = new NullProgressMonitor(); + + workspace = ResourcesPlugin.getWorkspace(); + + try { + cPrj = CProjectHelper.createCProject("CSelectionTestsNoIndexerProject", "bin"); //$NON-NLS-1$ //$NON-NLS-2$ + + project = cPrj.getProject(); + + IPath pathLoc = CCorePlugin.getDefault().getStateLocation(); + File indexFile = new File(pathLoc.append(INDEX_FILE_ID + ".index").toOSString()); //$NON-NLS-1$ + if (indexFile.exists()) + indexFile.delete(); + } catch ( CoreException e ) { + /*boo*/ + } + if (project == null) + fail("Unable to create project"); //$NON-NLS-1$ + + //Create file manager + fileManager = new FileManager(); + } + public CSelectionTestsNoIndexer() + { + super(); + } + /** + * @param name + */ + public CSelectionTestsNoIndexer(String name) + { + super(name); + } + + public static Test suite() { + TestSuite suite = new TestSuite( CSelectionTestsNoIndexer.class ); + suite.addTest( new CSelectionTestsNoIndexer("cleanupProject") ); //$NON-NLS-1$ + return suite; + } + + public void cleanupProject() throws Exception { + try{ + project.delete( true, false, monitor ); + project = null; + } catch( Throwable e ){ + /*boo*/ + } + } + + protected void tearDown() throws Exception { + if( project == null || !project.exists() ) + return; + + IResource [] members = project.members(); + for( int i = 0; i < members.length; i++ ){ + if( members[i].getName().equals( ".project" ) || members[i].getName().equals( ".cdtproject" ) ) //$NON-NLS-1$ //$NON-NLS-2$ + continue; + try{ + members[i].delete( false, monitor ); + } catch( Throwable e ){ + /*boo*/ + } + } + } + + protected IFile importFile(String fileName, String contents ) throws Exception{ + //Obtain file handle + IFile file = project.getProject().getFile(fileName); + + InputStream stream = new ByteArrayInputStream( contents.getBytes() ); + //Create file input stream + if( file.exists() ) + file.setContents( stream, false, false, monitor ); + else + file.create( stream, false, monitor ); + + fileManager.addFile(file); + + return file; + } + + protected IASTNode testF3(IFile file, int offset) throws ParserException { + return testF3(file, offset, 0); + } + + protected IASTNode testF3(IFile file, int offset, int length) throws ParserException { + disableIndex(); + + if (offset < 0) + throw new ParserException("offset can not be less than 0 and was " + offset); //$NON-NLS-1$ + + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IEditorPart part = null; + try { + part = page.openEditor(new FileEditorInput(file), "org.eclipse.cdt.ui.editor.CEditor"); //$NON-NLS-1$ + } catch (PartInitException e) { + assertFalse(true); + } + + if (part instanceof AbstractTextEditor) { + ((AbstractTextEditor)part).getSelectionProvider().setSelection(new TextSelection(offset,length)); + + final IAction action = ((AbstractTextEditor)part).getAction("OpenDeclarations"); //$NON-NLS-1$ + action.run(); + + // the action above should highlight the declaration, so now retrieve it and use that selection to get the IASTName selected on the TU + ISelection sel = ((AbstractTextEditor)part).getSelectionProvider().getSelection(); + + if (sel instanceof TextSelection) { + IASTName[] names = DOMSearchUtil.getSelectedNamesFrom(file, ((TextSelection)sel).getOffset(), ((TextSelection)sel).getLength()); + + if (names == null || names.length == 0) + return null; + + return names[0]; + } + } + + return null; + } + + protected IASTNode testF2(IFile file, int offset) throws ParserException { + return testF2(file, offset, 0); + } + + protected IASTNode testF2(IFile file, int offset, int length) throws ParserException { + disableIndex(); + + if (offset < 0) + throw new ParserException("offset can not be less than 0 and was " + offset); //$NON-NLS-1$ + + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IEditorPart part = null; + try { + part = page.openEditor(new FileEditorInput(file), "org.eclipse.cdt.ui.editor.CEditor"); //$NON-NLS-1$ + } catch (PartInitException e) { + assertFalse(true); + } + + if (part instanceof AbstractTextEditor) { + ((AbstractTextEditor)part).getSelectionProvider().setSelection(new TextSelection(offset,length)); + + final IAction action = ((AbstractTextEditor)part).getAction("OpenDefinition"); //$NON-NLS-1$ + action.run(); + + // the action above should highlight the declaration, so now retrieve it and use that selection to get the IASTName selected on the TU + ISelection sel = ((AbstractTextEditor)part).getSelectionProvider().getSelection(); + + if (sel instanceof TextSelection) { + IASTName[] names = DOMSearchUtil.getSelectedNamesFrom(file, ((TextSelection)sel).getOffset(), ((TextSelection)sel).getLength()); + + if (names == null || names.length == 0) + return null; + + return names[0]; + } + } + + return null; + } + + private void disableIndex() { + IPath pathLoc = CCorePlugin.getDefault().getStateLocation(); + File indexFile = new File(pathLoc.append(INDEX_FILE_ID + ".index").toOSString()); //$NON-NLS-1$ + if (indexFile.exists()) + indexFile.delete(); + } + + public void testBasicDefinition() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("extern int MyInt; // MyInt is in another file\n"); //$NON-NLS-1$ + buffer.append("extern const int MyConst; // MyConst is in another file\n"); //$NON-NLS-1$ + buffer.append("void MyFunc(int); // often used in header files\n"); //$NON-NLS-1$ + buffer.append("struct MyStruct; // often used in header files\n"); //$NON-NLS-1$ + buffer.append("typedef int NewInt; // a normal typedef statement\n"); //$NON-NLS-1$ + buffer.append("int MyInt;\n"); //$NON-NLS-1$ + buffer.append("extern const int MyConst = 42;\n"); //$NON-NLS-1$ + buffer.append("void MyFunc(int a) { cout << a << endl; }\n"); //$NON-NLS-1$ + buffer.append("struct MyStruct { int Member1; int Member2; };\n"); //$NON-NLS-1$ + + String code = buffer.toString(); + IFile file = importFile("testBasicDefinition.c", code); //$NON-NLS-1$ + + int offset = code.indexOf("MyInt;\n") + 2; //$NON-NLS-1$ + IASTNode def = testF2(file, offset); + IASTNode decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "MyInt"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 11); + assertEquals(((ASTNode)decl).getLength(), 5); + assertEquals(((IASTName)def).toString(), "MyInt"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 276); + assertEquals(((ASTNode)def).getLength(), 5); + + offset = code.indexOf("MyConst = 42") + 2; //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "MyConst"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 69); + assertEquals(((ASTNode)decl).getLength(), 7); + assertEquals(((IASTName)def).toString(), "MyConst"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 300); + assertEquals(((ASTNode)def).getLength(), 7); + + offset = code.indexOf("MyFunc(int a)") + 2; //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "MyFunc"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 115); + assertEquals(((ASTNode)decl).getLength(), 6); + assertEquals(((IASTName)def).toString(), "MyFunc"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 319); + assertEquals(((ASTNode)def).getLength(), 6); + + offset = code.indexOf("MyStruct {") + 2; //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "MyStruct"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 171); + assertEquals(((ASTNode)decl).getLength(), 8); + assertEquals(((IASTName)def).toString(), "MyStruct"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 363); + assertEquals(((ASTNode)def).getLength(), 8); + } + + // taken from C++ spec 3.1-3: + /* + // all but one of the following are definitions: + int a; // defines a + extern const int c = 1; // defines c + int f(int x) { return x+a; } // defines f and defines x + struct S { int a; int b; }; // defines S, S::a, and S::b + struct X { // defines X + int x; // defines nonstatic data member x + }; + enum { up, down }; // defines up and down + struct X anX; // defines anX + // whereas these are just declarations: + extern int a; // declares a + extern const int c; // declares c + int f(int); // declares f + struct S; // declares S + typedef int Int; // declares Int + extern struct X anotherX; // declares anotherX + */ + public void testCPPSpecDeclsDefs() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("int a; // defines a\n"); //$NON-NLS-1$ + buffer.append("extern const int c = 1; // defines c\n"); //$NON-NLS-1$ + buffer.append("int f(int x) { return x+a; } // defines f and defines x\n"); //$NON-NLS-1$ + buffer.append("struct S { int a; int b; }; // defines S, S::a, and S::b\n"); //$NON-NLS-1$ + buffer.append("struct X { // defines X\n"); //$NON-NLS-1$ + buffer.append("int x; // defines nonstatic data member x\n"); //$NON-NLS-1$ + buffer.append("};\n"); //$NON-NLS-1$ + buffer.append("enum { up, down }; // defines up and down\n"); //$NON-NLS-1$ + buffer.append("struct X anX; // defines anX\n"); //$NON-NLS-1$ + buffer.append("extern int a; // declares a\n"); //$NON-NLS-1$ + buffer.append("extern const int c; // declares c\n"); //$NON-NLS-1$ + buffer.append("int f(int); // declares f\n"); //$NON-NLS-1$ + buffer.append("struct S; // declares S\n"); //$NON-NLS-1$ + buffer.append("typedef int Int; // declares Int\n"); //$NON-NLS-1$ + buffer.append("extern struct X anotherX; // declares anotherX\n"); //$NON-NLS-1$ + + String code = buffer.toString(); + IFile file = importFile("testCPPSpecDeclsDefs.c", code); //$NON-NLS-1$ + + int offset = code.indexOf("a; // defines a"); //$NON-NLS-1$ + IASTNode def = testF2(file, offset); + IASTNode decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 4); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 4); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("c = 1; // defines c"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "c"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 37); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "c"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 37); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("f(int x) { return x+a; } // defines f and defines x"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "f"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 61); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "f"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 61); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("x) { return x+a; } // defines f and defines x"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 67); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 67); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("x+a; } // defines f and defines x"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 67); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 67); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("x+a; } // defines f and defines x"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 67); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 67); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("a; } // defines f and defines x"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 4); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 4); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("S { int a; int b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "S"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 120); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "S"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 120); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("a; int b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 128); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 128); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "b"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 135); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "b"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 135); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("X { // defines X"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 177); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 177); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("x; // defines nonstatic data member x"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 198); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 198); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("up, down }; // defines up and down"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "up"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 246); + assertEquals(((ASTNode)decl).getLength(), 2); + assertEquals(((IASTName)def).toString(), "up"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 246); + assertEquals(((ASTNode)def).getLength(), 2); + + offset = code.indexOf("down }; // defines up and down"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "down"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 250); + assertEquals(((ASTNode)decl).getLength(), 4); + assertEquals(((IASTName)def).toString(), "down"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 250); + assertEquals(((ASTNode)def).getLength(), 4); + + offset = code.indexOf("X anX; // defines anX"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 177); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 177); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("anX; // defines anX"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "anX"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 290); + assertEquals(((ASTNode)decl).getLength(), 3); + assertEquals(((IASTName)def).toString(), "anX"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 290); + assertEquals(((ASTNode)def).getLength(), 3); + + offset = code.indexOf("a; // declares a"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 4); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 4); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("c; // declares c"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "c"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 37); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "c"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 37); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("f(int); // declares f"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "f"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 61); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "f"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 61); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("S; // declares S"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "S"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 120); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "S"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 120); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("Int; // declares Int"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "Int"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 434); + assertEquals(((ASTNode)decl).getLength(), 3); + assertEquals(((IASTName)def).toString(), "Int"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 434); + assertEquals(((ASTNode)def).getLength(), 3); + + offset = code.indexOf("X anotherX; // declares anotherX"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 177); + assertEquals(((ASTNode)decl).getLength(), 1); + assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 177); + assertEquals(((ASTNode)def).getLength(), 1); + + offset = code.indexOf("anotherX; // declares anotherX"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertNull(def); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "anotherX"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 471); + assertEquals(((ASTNode)decl).getLength(), 8); + } + + public void testNoDefinitions() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("extern int a1; // declares a\n"); //$NON-NLS-1$ + buffer.append("extern const int c1; // declares c\n"); //$NON-NLS-1$ + buffer.append("int f1(int); // declares f\n"); //$NON-NLS-1$ + buffer.append("struct S1; // declares S\n"); //$NON-NLS-1$ + buffer.append("typedef int Int; // declares Int\n"); //$NON-NLS-1$ + + String code = buffer.toString(); + IFile file = importFile("testNoDefinitions.c", code); //$NON-NLS-1$ + + int offset = code.indexOf("a1; // declares a"); //$NON-NLS-1$ + IASTNode def = testF2(file, offset); + IASTNode decl = testF3(file, offset); + assertNull(def); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "a1"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 11); + assertEquals(((ASTNode)decl).getLength(), 2); + + offset = code.indexOf("c1; // declares c"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertNull(def); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "c1"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 46); + assertEquals(((ASTNode)decl).getLength(), 2); + + offset = code.indexOf("f1(int); // declares f"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertNull(def); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "f1"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 68); + assertEquals(((ASTNode)decl).getLength(), 2); + + offset = code.indexOf("S1; // declares S"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertNull(def); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "S1"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 98); + assertEquals(((ASTNode)decl).getLength(), 2); + + offset = code.indexOf("Int; // declares Int"); //$NON-NLS-1$ + def = testF2(file, offset); + decl = testF3(file, offset); + assertTrue(def instanceof IASTName); + assertTrue(decl instanceof IASTName); + assertEquals(((IASTName)decl).toString(), "Int"); //$NON-NLS-1$ + assertEquals(((ASTNode)decl).getOffset(), 128); + assertEquals(((ASTNode)decl).getLength(), 3); + assertEquals(((IASTName)def).toString(), "Int"); //$NON-NLS-1$ + assertEquals(((ASTNode)def).getOffset(), 128); + assertEquals(((ASTNode)def).getLength(), 3); + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selectiontests/SelectionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selectiontests/SelectionTests.java deleted file mode 100644 index 43c62971fce..00000000000 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selectiontests/SelectionTests.java +++ /dev/null @@ -1,311 +0,0 @@ -package org.eclipse.cdt.ui.tests.text.selectiontests; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.eclipse.cdt.core.dom.ast.IASTName; -import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.model.ICProject; -import org.eclipse.cdt.core.search.DOMSearchUtil; -import org.eclipse.cdt.core.testplugin.CProjectHelper; -import org.eclipse.cdt.core.testplugin.FileManager; -import org.eclipse.cdt.internal.core.dom.parser.ASTNode; -import org.eclipse.cdt.internal.core.index.sourceindexer.SourceIndexer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.text.TextSelection; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.part.FileEditorInput; -import org.eclipse.ui.texteditor.AbstractTextEditor; - -public class SelectionTests extends TestCase { - - static NullProgressMonitor monitor; - static IWorkspace workspace; - static IProject project; - static FileManager fileManager; - static boolean disabledHelpContributions = false; - { - //(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset(); - monitor = new NullProgressMonitor(); - - workspace = ResourcesPlugin.getWorkspace(); - - ICProject cPrj; - try { - cPrj = CProjectHelper.createCCProject("SelectionTestProject", "bin"); //$NON-NLS-1$ //$NON-NLS-2$ - - project = cPrj.getProject(); - project.setSessionProperty(SourceIndexer.activationKey,new Boolean(false)); - } catch ( CoreException e ) { - /*boo*/ - } - if (project == null) - fail("Unable to create project"); //$NON-NLS-1$ - - //Create file manager - fileManager = new FileManager(); - } - public SelectionTests() - { - super(); - } - /** - * @param name - */ - public SelectionTests(String name) - { - super(name); - } - - public static Test suite() { - TestSuite suite = new TestSuite( SelectionTests.class ); - suite.addTest( new SelectionTests("cleanupProject") ); //$NON-NLS-1$ - return suite; - } - - public void cleanupProject() throws Exception { - try{ - project.delete( true, false, monitor ); - project = null; - } catch( Throwable e ){ - /*boo*/ - } - } - - protected void tearDown() throws Exception { - if( project == null || !project.exists() ) - return; - - IResource [] members = project.members(); - for( int i = 0; i < members.length; i++ ){ - if( members[i].getName().equals( ".project" ) || members[i].getName().equals( ".cdtproject" ) ) //$NON-NLS-1$ //$NON-NLS-2$ - continue; - try{ - members[i].delete( false, monitor ); - } catch( Throwable e ){ - /*boo*/ - } - } - } - - protected IFile importFile(String fileName, String contents ) throws Exception{ - //Obtain file handle - IFile file = project.getProject().getFile(fileName); - - InputStream stream = new ByteArrayInputStream( contents.getBytes() ); - //Create file input stream - if( file.exists() ) - file.setContents( stream, false, false, monitor ); - else - file.create( stream, false, monitor ); - - fileManager.addFile(file); - - return file; - } - - protected IASTNode testF3(IFile file, int offset) { - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IEditorPart part = null; - try { - part = page.openEditor(new FileEditorInput(file), "org.eclipse.cdt.ui.editor.CEditor"); //$NON-NLS-1$ - } catch (PartInitException e) { - assertFalse(true); - } - - if (part instanceof AbstractTextEditor) { - ((AbstractTextEditor)part).getSelectionProvider().setSelection(new TextSelection(offset,0)); - - final IAction action = ((AbstractTextEditor)part).getAction("OpenDeclarations"); //$NON-NLS-1$ - action.run(); - - // the action above should highlight the declaration, so now retrieve it and use that selection to get the IASTName selected on the TU - ISelection sel = ((AbstractTextEditor)part).getSelectionProvider().getSelection(); - - if (sel instanceof TextSelection) { - IASTName[] names = DOMSearchUtil.getSelectedNamesFrom(file, ((TextSelection)sel).getOffset(), ((TextSelection)sel).getLength()); - - if (names.length == 0) { - assertFalse(true); - } else { - return names[0]; - } - } - } - - return null; - } - - protected IASTNode testF2(IFile file, int offset) { - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IEditorPart part = null; - try { - part = page.openEditor(new FileEditorInput(file), "org.eclipse.cdt.ui.editor.CEditor"); //$NON-NLS-1$ - } catch (PartInitException e) { - assertFalse(true); - } - - if (part instanceof AbstractTextEditor) { - ((AbstractTextEditor)part).getSelectionProvider().setSelection(new TextSelection(offset,0)); - - final IAction action = ((AbstractTextEditor)part).getAction("OpenDefinition"); //$NON-NLS-1$ - action.run(); - - // the action above should highlight the declaration, so now retrieve it and use that selection to get the IASTName selected on the TU - ISelection sel = ((AbstractTextEditor)part).getSelectionProvider().getSelection(); - - if (sel instanceof TextSelection) { - IASTName[] names = DOMSearchUtil.getSelectedNamesFrom(file, ((TextSelection)sel).getOffset(), ((TextSelection)sel).getLength()); - - if (names.length == 0) { - assertFalse(true); - } else { - return names[0]; - } - } - } - - return null; - } - - public void testBug93281() throws Exception { - StringBuffer buffer = new StringBuffer(); - buffer.append("class Point{ \n"); //$NON-NLS-1$ - buffer.append("public: \n"); //$NON-NLS-1$ - buffer.append("Point(): xCoord(0){} \n"); //$NON-NLS-1$ - buffer.append("Point& operator=(const Point &rhs){return *this;} // line A\n"); //$NON-NLS-1$ - buffer.append("void* operator new [ ] (unsigned int);\n"); //$NON-NLS-1$ - buffer.append("private: \n"); //$NON-NLS-1$ - buffer.append("int xCoord; \n"); //$NON-NLS-1$ - buffer.append("}; \n"); //$NON-NLS-1$ - buffer.append("static const Point zero;\n"); //$NON-NLS-1$ - buffer.append("int main(int argc, char **argv) { \n"); //$NON-NLS-1$ - buffer.append("Point *p2 = new Point(); \n"); //$NON-NLS-1$ - buffer.append("p2-> operator // /* operator */ // F3 in the middle \n"); //$NON-NLS-1$ - buffer.append("//of \"operator\" should work\n"); //$NON-NLS-1$ - buffer.append("// \\n"); //$NON-NLS-1$ - buffer.append("/* */\n"); //$NON-NLS-1$ - buffer.append("=(zero); // line B\n"); //$NON-NLS-1$ - buffer.append("p2->operator /* oh yeah */ new // F3 in the middle of \"operator\"\n"); //$NON-NLS-1$ - buffer.append("// should work\n"); //$NON-NLS-1$ - buffer.append("//\n"); //$NON-NLS-1$ - buffer.append("[ /* sweet */ ] //\n"); //$NON-NLS-1$ - buffer.append("(2);\n"); //$NON-NLS-1$ - buffer.append("return (0); \n"); //$NON-NLS-1$ - buffer.append("}\n"); //$NON-NLS-1$ - - String code = buffer.toString(); - IFile file = importFile("test93281.cpp", code); //$NON-NLS-1$ - - int offset = code.indexOf("p2->operator") + 6; //$NON-NLS-1$ - IASTNode node = testF3(file, offset); - - assertTrue(node instanceof IASTName); - assertEquals(((IASTName)node).toString(), "operator new[]"); //$NON-NLS-1$ - assertEquals(((ASTNode)node).getOffset(), 183); - assertEquals(((ASTNode)node).getLength(), 16); - - offset = code.indexOf("p2-> operator") + 11; //$NON-NLS-1$ - node = testF3(file, offset); - - assertTrue(node instanceof IASTName); - assertEquals(((IASTName)node).toString(), "operator ="); //$NON-NLS-1$ - assertEquals(((ASTNode)node).getOffset(), 121); - assertEquals(((ASTNode)node).getLength(), 9); - - } - - public void testBasicDefinition() throws Exception { - StringBuffer buffer = new StringBuffer(); - buffer.append("extern int MyInt; // MyInt is in another file\n"); //$NON-NLS-1$ - buffer.append("extern const int MyConst; // MyConst is in another file\n"); //$NON-NLS-1$ - buffer.append("void MyFunc(int); // often used in header files\n"); //$NON-NLS-1$ - buffer.append("struct MyStruct; // often used in header files\n"); //$NON-NLS-1$ - buffer.append("typedef int NewInt; // a normal typedef statement\n"); //$NON-NLS-1$ - buffer.append("class MyClass; // often used in header files\n"); //$NON-NLS-1$ - buffer.append("int MyInt;\n"); //$NON-NLS-1$ - buffer.append("extern const int MyConst = 42;\n"); //$NON-NLS-1$ - buffer.append("void MyFunc(int a) { cout << a << endl; }\n"); //$NON-NLS-1$ - buffer.append("struct MyStruct { int Member1; int Member2; };\n"); //$NON-NLS-1$ - buffer.append("class MyClass { int MemberVar; };\n"); //$NON-NLS-1$ - - String code = buffer.toString(); - IFile file = importFile("testBasicDefinition.cpp", code); //$NON-NLS-1$ - - int offset = code.indexOf("MyInt;\n") + 2; //$NON-NLS-1$ - IASTNode def = testF2(file, offset); - IASTNode decl = testF3(file, offset); - assertTrue(def instanceof IASTName); - assertTrue(decl instanceof IASTName); - assertEquals(((IASTName)decl).toString(), "MyInt"); //$NON-NLS-1$ - assertEquals(((ASTNode)decl).getOffset(), 11); - assertEquals(((ASTNode)decl).getLength(), 5); - assertEquals(((IASTName)def).toString(), "MyInt"); //$NON-NLS-1$ - assertEquals(((ASTNode)def).getOffset(), 330); - assertEquals(((ASTNode)def).getLength(), 5); - - offset = code.indexOf("MyConst = 42") + 2; //$NON-NLS-1$ - def = testF2(file, offset); - decl = testF3(file, offset); - assertTrue(def instanceof IASTName); - assertTrue(decl instanceof IASTName); - assertEquals(((IASTName)decl).toString(), "MyConst"); //$NON-NLS-1$ - assertEquals(((ASTNode)decl).getOffset(), 69); - assertEquals(((ASTNode)decl).getLength(), 7); - assertEquals(((IASTName)def).toString(), "MyConst"); //$NON-NLS-1$ - assertEquals(((ASTNode)def).getOffset(), 354); - assertEquals(((ASTNode)def).getLength(), 7); - - offset = code.indexOf("MyFunc(int a)") + 2; //$NON-NLS-1$ - def = testF2(file, offset); - decl = testF3(file, offset); - assertTrue(def instanceof IASTName); - assertTrue(decl instanceof IASTName); - assertEquals(((IASTName)decl).toString(), "MyFunc"); //$NON-NLS-1$ - assertEquals(((ASTNode)decl).getOffset(), 115); - assertEquals(((ASTNode)decl).getLength(), 6); - assertEquals(((IASTName)def).toString(), "MyFunc"); //$NON-NLS-1$ - assertEquals(((ASTNode)def).getOffset(), 373); - assertEquals(((ASTNode)def).getLength(), 6); - - offset = code.indexOf("MyStruct {") + 2; //$NON-NLS-1$ - def = testF2(file, offset); - decl = testF3(file, offset); - assertTrue(def instanceof IASTName); - assertTrue(decl instanceof IASTName); - assertEquals(((IASTName)decl).toString(), "MyStruct"); //$NON-NLS-1$ - assertEquals(((ASTNode)decl).getOffset(), 171); - assertEquals(((ASTNode)decl).getLength(), 8); - assertEquals(((IASTName)def).toString(), "MyStruct"); //$NON-NLS-1$ - assertEquals(((ASTNode)def).getOffset(), 417); - assertEquals(((ASTNode)def).getLength(), 8); - - offset = code.indexOf("MyClass {") + 2; //$NON-NLS-1$ - def = testF2(file, offset); - decl = testF3(file, offset); - assertTrue(def instanceof IASTName); - assertTrue(decl instanceof IASTName); - assertEquals(((IASTName)decl).toString(), "MyClass"); //$NON-NLS-1$ - assertEquals(((ASTNode)decl).getOffset(), 278); - assertEquals(((ASTNode)decl).getLength(), 7); - assertEquals(((IASTName)def).toString(), "MyClass"); //$NON-NLS-1$ - assertEquals(((ASTNode)def).getOffset(), 463); - assertEquals(((ASTNode)def).getLength(), 7); - } - -} \ No newline at end of file