/******************************************************************************* * Copyright (c) 2004, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.ui.tests.text.selection; import java.io.ByteArrayInputStream; import java.io.File; import java.io.InputStream; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; 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.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jface.text.ITextSelection; 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; import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.FileManager; import org.eclipse.cdt.ui.testplugin.EditorTestHelper; import org.eclipse.cdt.ui.tests.BaseUITestCase; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable; import org.eclipse.cdt.internal.core.parser.ParserException; import org.eclipse.cdt.internal.ui.editor.ASTProvider; import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.search.actions.OpenDeclarationsAction; /** * 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 BaseUITestCase { 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; void initProject() { if (project != null) { return; } //(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset(); monitor = new NullProgressMonitor(); workspace = ResourcesPlugin.getWorkspace(); try { cPrj = CProjectHelper.createCProject("CSelectionTestsNoIndexerProject", "bin", IPDOMManager.ID_NO_INDEXER); //$NON-NLS-1$ //$NON-NLS-2$ project = cPrj.getProject(); } 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; } @Override protected void setUp() throws Exception { super.setUp(); OpenDeclarationsAction.sIsJUnitTest= true; initProject(); } public void cleanupProject() throws Exception { try { closeAllEditors(); CProjectHelper.delete(cPrj); project= null; } finally { project= null; } } @Override protected void tearDown() throws Exception { if (project == null || !project.exists()) return; closeAllEditors(); IResource [] members = project.members(); for (IResource member : members) { if (member.getName().equals(".project") || member.getName().equals(".cproject")) //$NON-NLS-1$ //$NON-NLS-2$ continue; if (member.getName().equals(".settings")) continue; try { member.delete(true, 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 IFile importFileWithLink(String fileName, String contents) throws Exception{ //Obtain file handle IFile file = project.getProject().getFile(fileName); IPath location = new Path(project.getLocation().removeLastSegments(1).toOSString() + File.separator + fileName); File linkFile = new File(location.toOSString()); if (!linkFile.exists()) { linkFile.createNewFile(); } file.createLink(location, IResource.ALLOW_MISSING_LOCAL, null); 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 IFile importFileInsideLinkedFolder(String fileName, String contents, String folderName) throws Exception{ IFolder linkedFolder = project.getFolder(folderName); IPath folderLocation = new Path(project.getLocation().toOSString() + File.separator + folderName + "_this_is_linked"); //$NON-NLS-1$ IFolder actualFolder = project.getFolder(folderName + "_this_is_linked"); //$NON-NLS-1$ if (!actualFolder.exists()) actualFolder.create(true, true, monitor); linkedFolder.createLink(folderLocation, IResource.NONE, monitor); actualFolder.delete(true, false, monitor); IFile file = linkedFolder.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 IFile importFileWithLink(String fileName, String contents, IFolder folder) throws Exception{ if (!folder.exists()) folder.create(true, true, null); //Obtain file handle IFile file = project.getProject().getFile(fileName); IPath location = new Path(folder.getLocation().toOSString() + File.separator + fileName); File linkFile = new File(location.toOSString()); if (!linkFile.exists()) { linkFile.createNewFile(); } file.createLink(location, IResource.ALLOW_MISSING_LOCAL, null); 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 IFolder importFolder(String folderName) throws Exception { IFolder folder = project.getProject().getFolder(folderName); //Create file input stream if (!folder.exists()) folder.create(false, false, monitor); return folder; } protected IASTNode testF3(IFile file, int offset) throws ParserException, CoreException { return testF3(file, offset, 0); } protected IASTNode testF3(IFile file, int offset, int length) throws ParserException, CoreException { 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 CEditor) { CEditor editor= (CEditor) part; EditorTestHelper.joinReconciler(EditorTestHelper.getSourceViewer(editor), 100, 5000, 10); editor.getSelectionProvider().setSelection(new TextSelection(offset,length)); final OpenDeclarationsAction action = (OpenDeclarationsAction) editor.getAction("OpenDeclarations"); //$NON-NLS-1$ action.runSync(); // 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(); final IASTName[] result= {null}; if (sel instanceof ITextSelection) { final ITextSelection textSel = (ITextSelection)sel; ITranslationUnit tu = (ITranslationUnit) editor.getInputCElement(); IStatus ok= ASTProvider.getASTProvider().runOnAST(tu, ASTProvider.WAIT_IF_OPEN, monitor, new ASTRunnable() { public IStatus runOnAST(ILanguage language, IASTTranslationUnit ast) throws CoreException { result[0]= ast.getNodeSelector(null).findName(textSel.getOffset(), textSel.getLength()); return Status.OK_STATUS; } }); assertTrue(ok.isOK()); return result[0]; } } return null; } public void testBasicDefinition() throws Exception { StringBuffer buffer = new StringBuffer(); buffer.append("extern int MyInt; // def is in another file \n"); //$NON-NLS-1$ buffer.append("extern const int MyConst; // def 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(" \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") + 2; //$NON-NLS-1$ int defOffset = code.indexOf("MyInt", offset) + 2; //$NON-NLS-1$ IASTNode def = testF3(file, offset); IASTNode decl = testF3(file, defOffset); assertTrue(def instanceof IASTName); assertTrue(decl instanceof IASTName); assertEquals("MyInt", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(11, ((ASTNode) decl).getOffset()); assertEquals(5, ((ASTNode) decl).getLength()); assertEquals("MyInt", ((IASTName) def).toString()); //$NON-NLS-1$ assertEquals(330, ((ASTNode) def).getOffset()); assertEquals(5, ((ASTNode) def).getLength()); offset= code.indexOf("MyConst") + 2; defOffset= code.indexOf("MyConst", offset) + 2; def = testF3(file, offset); decl = testF3(file, defOffset); assertTrue(def instanceof IASTName); assertTrue(decl instanceof IASTName); assertEquals("MyConst", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(69, ((ASTNode) decl).getOffset()); assertEquals(7, ((ASTNode) decl).getLength()); assertEquals("MyConst", ((IASTName) def).toString()); //$NON-NLS-1$ assertEquals(354, ((ASTNode) def).getOffset()); assertEquals(7, ((ASTNode) def).getLength()); offset= code.indexOf("MyFunc") + 2; defOffset= code.indexOf("MyFunc", offset) + 2; def = testF3(file, offset); decl = testF3(file, defOffset); assertTrue(def instanceof IASTName); assertTrue(decl instanceof IASTName); assertEquals("MyFunc", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(115, ((ASTNode) decl).getOffset()); assertEquals(6, ((ASTNode) decl).getLength()); assertEquals("MyFunc", ((IASTName) def).toString()); //$NON-NLS-1$ assertEquals(373, ((ASTNode) def).getOffset()); assertEquals(6, ((ASTNode) def).getLength()); offset= code.indexOf("MyStruct") + 2; defOffset= code.indexOf("MyStruct", offset) + 2; def = testF3(file, offset); decl = testF3(file, defOffset); assertTrue(def instanceof IASTName); assertTrue(decl instanceof IASTName); assertEquals("MyStruct", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(417, ((ASTNode) decl).getOffset()); assertEquals(8, ((ASTNode) decl).getLength()); assertEquals("MyStruct", ((IASTName) def).toString()); //$NON-NLS-1$ assertEquals(417, ((ASTNode) def).getOffset()); assertEquals(8, ((ASTNode) def).getLength()); } // 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(" \n"); //$NON-NLS-1$ buffer.append("};\n"); //$NON-NLS-1$ buffer.append(" "); //$NON-NLS-1$ buffer.append("enum { up, down }; // defines up and down\n"); //$NON-NLS-1$ buffer.append(" \n"); //$NON-NLS-1$ buffer.append(" \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 y); // declar 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 decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("a", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(512, ((ASTNode) decl).getOffset()); assertEquals(1, ((ASTNode) decl).getLength()); offset = code.indexOf("c = 1; // defines c"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("c", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(546, ((ASTNode) decl).getOffset()); assertEquals(1, ((ASTNode) decl).getLength()); offset = code.indexOf("f(int x) { return x+a; } // defines f and defines x"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("f", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(567, ((ASTNode) decl).getOffset()); assertEquals(1, ((ASTNode) decl).getLength()); offset = code.indexOf("x) { return x+a; } // defines f and defines x"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("x", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(67, ((ASTNode) decl).getOffset()); assertEquals(1, ((ASTNode) decl).getLength()); offset = code.indexOf("x+a; } // defines f and defines x"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("x", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(67, ((ASTNode) decl).getOffset()); assertEquals(1, ((ASTNode) decl).getLength()); offset = code.indexOf("x+a; } // defines f and defines x"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("x", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(67, ((ASTNode) decl).getOffset()); assertEquals(1, ((ASTNode) decl).getLength()); offset = code.indexOf("a; } // defines f and defines x"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("a", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(4, ((ASTNode) decl).getOffset()); assertEquals(1, ((ASTNode) decl).getLength()); offset = code.indexOf("S { int a; int b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("S", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(120, ((ASTNode) decl).getOffset()); assertEquals(1, ((ASTNode) decl).getLength()); offset = code.indexOf("a; int b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("a", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(128, ((ASTNode) decl).getOffset()); assertEquals(1, ((ASTNode) decl).getLength()); offset = code.indexOf("b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("b", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(135, ((ASTNode) decl).getOffset()); assertEquals(1, ((ASTNode) decl).getLength()); offset = code.indexOf("X { // defines X"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("X", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(177, ((ASTNode) decl).getOffset()); assertEquals(1, ((ASTNode) decl).getLength()); offset = code.indexOf("x; // defines nonstatic data member x"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("x", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(198, ((ASTNode) decl).getOffset()); assertEquals(1, ((ASTNode) decl).getLength()); offset = code.indexOf("up, down }; // defines up and down"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("up", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(367, ((ASTNode) decl).getOffset()); assertEquals(2, ((ASTNode) decl).getLength()); offset = code.indexOf("down }; // defines up and down"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("down", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(371, ((ASTNode) decl).getOffset()); assertEquals(4, ((ASTNode) decl).getLength()); IASTNode def; offset = code.indexOf("X anX; // defines anX"); //$NON-NLS-1$ def = testF3(file, offset); assertTrue(def instanceof IASTName); assertEquals("X", ((IASTName) def).toString()); //$NON-NLS-1$ assertEquals(177, ((ASTNode) def).getOffset()); assertEquals(1, ((ASTNode) def).getLength()); offset = code.indexOf("anX; // defines anX"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("anX", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(481, ((ASTNode) decl).getOffset()); assertEquals(3, ((ASTNode) decl).getLength()); offset = code.indexOf("a; // declares a"); //$NON-NLS-1$ def = testF3(file, offset); assertTrue(def instanceof IASTName); assertEquals("a", ((IASTName) def).toString()); //$NON-NLS-1$ assertEquals(4, ((ASTNode) def).getOffset()); assertEquals(1, ((ASTNode) def).getLength()); offset = code.indexOf("c; // declares c"); //$NON-NLS-1$ def = testF3(file, offset); assertTrue(def instanceof IASTName); assertEquals("c", ((IASTName) def).toString()); //$NON-NLS-1$ assertEquals(37, ((ASTNode) def).getOffset()); assertEquals(1, ((ASTNode) def).getLength()); offset = code.indexOf("f(int y); // declar f"); //$NON-NLS-1$ def = testF3(file, offset); assertTrue(def instanceof IASTName); assertEquals("f", ((IASTName) def).toString()); //$NON-NLS-1$ assertEquals(61, ((ASTNode) def).getOffset()); assertEquals(1, ((ASTNode) def).getLength()); offset = code.indexOf("S; // declares S"); //$NON-NLS-1$ def = testF3(file, offset); assertTrue(def instanceof IASTName); assertEquals("S", ((IASTName) def).toString()); //$NON-NLS-1$ assertEquals(120, ((ASTNode) def).getOffset()); assertEquals(1, ((ASTNode) def).getLength()); offset = code.indexOf("Int; // declares Int"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("Int", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(625, ((ASTNode) decl).getOffset()); assertEquals(3, ((ASTNode) decl).getLength()); offset = code.indexOf("X anotherX; // declares anotherX"); //$NON-NLS-1$ def = testF3(file, offset); assertTrue(def instanceof IASTName); assertEquals("X", ((IASTName) def).toString()); //$NON-NLS-1$ assertEquals(177, ((ASTNode) def).getOffset()); assertEquals(1, ((ASTNode) def).getLength()); offset = code.indexOf("anotherX; // declares anotherX"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("anotherX", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(662, ((ASTNode) decl).getOffset()); assertEquals(8, ((ASTNode) decl).getLength()); } 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 decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("a1", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(11, ((ASTNode) decl).getOffset()); assertEquals(2, ((ASTNode) decl).getLength()); offset = code.indexOf("c1; // declares c"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("c1", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(46, ((ASTNode) decl).getOffset()); assertEquals(2, ((ASTNode) decl).getLength()); offset = code.indexOf("f1(int); // declares f"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("f1", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(68, ((ASTNode) decl).getOffset()); assertEquals(2, ((ASTNode) decl).getLength()); offset = code.indexOf("S1; // declares S"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("S1", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(98, ((ASTNode) decl).getOffset()); assertEquals(2, ((ASTNode) decl).getLength()); offset = code.indexOf("Int; // declares Int"); //$NON-NLS-1$ decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("Int", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(128, ((ASTNode) decl).getOffset()); assertEquals(3, ((ASTNode) decl).getLength()); } public void testBug103697() throws Exception { StringBuffer buffer = new StringBuffer(); buffer.append("int x;\n"); //$NON-NLS-1$ buffer.append("int foo() {\n"); //$NON-NLS-1$ buffer.append(" return x;\n"); //$NON-NLS-1$ buffer.append("}\n"); //$NON-NLS-1$ String code = buffer.toString(); IFile file = importFileWithLink("testBug103697.cpp", code); //$NON-NLS-1$ int offset = code.indexOf("return x;\n") + "return ".length(); //$NON-NLS-1$ //$NON-NLS-2$ IASTNode decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("x", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(4, ((ASTNode) decl).getOffset()); assertEquals(1, ((ASTNode) decl).getLength()); } public void testBug76043() throws Exception { StringBuffer buffer = new StringBuffer(); buffer.append("int x;\n"); //$NON-NLS-1$ buffer.append("int foo() {\n"); //$NON-NLS-1$ buffer.append(" return x;\n"); //$NON-NLS-1$ buffer.append("}\n"); //$NON-NLS-1$ String code = buffer.toString(); IFile file = importFileInsideLinkedFolder("testBug76043.c", code, "folder"); //$NON-NLS-1$ //$NON-NLS-2$ assertFalse(file.isLinked()); // I'm not sure why the IResource#isLinked() returns false if it's contained within a linked folder int offset = code.indexOf("return x;\n") + "return ".length(); //$NON-NLS-1$ //$NON-NLS-2$ IASTNode decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("x", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(4, ((ASTNode) decl).getOffset()); assertEquals(1, ((ASTNode) decl).getLength()); } public void testBug78354() throws Exception { StringBuffer buffer = new StringBuffer(); buffer.append("typedef int TestTypeOne;\n"); //$NON-NLS-1$ buffer.append("typedef int TestTypeTwo;\n"); //$NON-NLS-1$ buffer.append("int main()\n"); //$NON-NLS-1$ buffer.append("{\n"); //$NON-NLS-1$ buffer.append("TestTypeOne myFirstLink = 5;\n"); //$NON-NLS-1$ buffer.append("TestTypeTwo mySecondLink = 6;\n"); //$NON-NLS-1$ buffer.append("return 0;\n"); //$NON-NLS-1$ buffer.append("}\n"); //$NON-NLS-1$ String code = buffer.toString(); IFile file = importFileWithLink("testBug78354.cpp", code); //$NON-NLS-1$ int offset = code.indexOf("TestTypeOne myFirstLink = 5;"); //$NON-NLS-1$ IASTNode decl = testF3(file, offset); assertTrue(decl instanceof IASTName); assertEquals("TestTypeOne", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals(12, ((ASTNode) decl).getOffset()); assertEquals(11, ((ASTNode) decl).getLength()); } // int myFunc(var) // int var; // { // return var; // } // // int main(void) // { // return myFunc(0); // } public void testKRstyleFunctions_Bug221635() throws Exception { String code= getContentsForTest(1)[0].toString(); IFile file = importFile("source.c", code); int offset= code.indexOf("myFunc(0)"); IASTNode decl= testF3(file, offset); assertTrue(decl instanceof IASTName); final IASTName name = (IASTName) decl; assertTrue(name.isDefinition()); assertEquals("myFunc", name.toString()); } }