[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-patch] FIXED 93281- [Open Declaration] the entire operator string shouldn't have to be selected for features to work
|
FIXED 93281- [Open Declaration] the
entire operator string shouldn't have to be selected for features to work
Devin Steffler
IBM's Eclipse CDT
Ottawa (Palladium), Ontario, Canada
Index: ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java,v
retrieving revision 1.27
diff -u -r1.27 AutomatedSuite.java
--- ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java 10 Feb 2005 15:33:59 -0000 1.27
+++ ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java 29 Apr 2005 19:51:45 -0000
@@ -48,6 +48,7 @@
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;
@@ -113,6 +114,10 @@
addTest( ContentAssistTests.suite() );
addTest( RegressionTestsUISuite.suite() );
+
+ // selection tests
+ addTest( SelectionTests.suite() );
+
// Failed Tests
addTest(CompletionFailedTest_MemberReference_Arrow_Prefix2.suite());
}
Index: ui/org/eclipse/cdt/ui/tests/text/selectiontests/SelectionTests.java
===================================================================
RCS file: ui/org/eclipse/cdt/ui/tests/text/selectiontests/SelectionTests.java
diff -N ui/org/eclipse/cdt/ui/tests/text/selectiontests/SelectionTests.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/cdt/ui/tests/text/selectiontests/SelectionTests.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,205 @@
+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.model.ITranslationUnit;
+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.cdt.internal.ui.CHelpProviderManager;
+import org.eclipse.cdt.internal.ui.text.CHelpBookDescriptor;
+import org.eclipse.cdt.ui.tests.text.contentassist.ContentAssistTests;
+import org.eclipse.cdt.ui.text.ICHelpInvocationContext;
+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"); // TODO Devin testing
+ } catch (PartInitException e) {
+ assertFalse(true);
+ }
+
+ if (part instanceof AbstractTextEditor) {
+ ((AbstractTextEditor)part).getSelectionProvider().setSelection(new TextSelection(offset,0));
+
+ final IAction action = ((AbstractTextEditor)part).getAction("OpenDeclarations");
+ 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);
+
+ }
+}
Index: src/org/eclipse/cdt/internal/ui/search/actions/SelectionParseAction.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/SelectionParseAction.java,v
retrieving revision 1.8
diff -u -r1.8 SelectionParseAction.java
--- src/org/eclipse/cdt/internal/ui/search/actions/SelectionParseAction.java 29 Apr 2005 00:56:11 -0000 1.8
+++ src/org/eclipse/cdt/internal/ui/search/actions/SelectionParseAction.java 29 Apr 2005 19:51:20 -0000
@@ -41,6 +41,7 @@
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.texteditor.IDocumentProvider;
@@ -50,7 +51,8 @@
* Created on Jun 2, 2004
*/
public class SelectionParseAction extends Action {
- protected static final String CSEARCH_OPERATION_TOO_MANY_NAMES_MESSAGE = "CSearchOperation.tooManyNames.message"; //$NON-NLS-1$
+ private static final String OPERATOR = "operator"; //$NON-NLS-1$
+ protected static final String CSEARCH_OPERATION_TOO_MANY_NAMES_MESSAGE = "CSearchOperation.tooManyNames.message"; //$NON-NLS-1$
protected static final String CSEARCH_OPERATION_NO_NAMES_SELECTED_MESSAGE = "CSearchOperation.noNamesSelected.message"; //$NON-NLS-1$
protected static final String CSEARCH_OPERATION_OPERATION_UNAVAILABLE_MESSAGE = "CSearchOperation.operationUnavailable.message"; //$NON-NLS-1$
@@ -218,8 +220,27 @@
SelSearchNode sel = new SelSearchNode();
+ boolean selectedOperator=false;
+ if (selectedWord != null && selectedWord.indexOf(OPERATOR) >= 0 && fPos >= fStartPos + selectedWord.indexOf(OPERATOR) && fPos < fStartPos + selectedWord.indexOf(OPERATOR) + OPERATOR.length()) {
+ selectedOperator=true;
+ }
+
+ // if the operator was selected, get its proper bounds
+ if (selectedOperator && fEditor.getEditorInput() instanceof IFileEditorInput &&
+ CoreModel.hasCCNature(((IFileEditorInput)fEditor.getEditorInput()).getFile().getProject())) {
+ int actualStart=fStartPos + selectedWord.indexOf(OPERATOR);
+ int actualEnd=getOperatorActualEnd(doc, fStartPos + selectedWord.indexOf(OPERATOR) + OPERATOR.length());
+
+ actualEnd=(actualEnd>0?actualEnd:fEndPos);
+
+ try {
+ sel.selText = doc.get(actualStart, actualEnd - actualStart);
+ } catch (BadLocationException e) {}
+ sel.selStart = actualStart;
+ sel.selEnd = actualEnd;
+ // TODO Devin this only works for definitions of destructors right now
// if there is a destructor and the cursor is in the destructor name's segment then get the entire destructor
- if (selectedWord != null && selectedWord.indexOf('~') >= 0 && fPos - 2 >= fStartPos + selectedWord.lastIndexOf(new String(Keywords.cpCOLONCOLON))) {
+ } else if (selectedWord != null && selectedWord.indexOf('~') >= 0 && fPos - 2 >= fStartPos + selectedWord.lastIndexOf(new String(Keywords.cpCOLONCOLON))) {
int tildePos = selectedWord.indexOf('~');
int actualStart=fStartPos + tildePos;
int length=0;
@@ -259,6 +280,211 @@
return sel;
}
+ private int getOperatorActualEnd(IDocument doc, int index) {
+ char c1, c2;
+ int actualEnd=-1;
+ boolean multiComment=false;
+ boolean singleComment=false;
+ int possibleEnd=-1;
+ while (actualEnd==-1) {
+ try {
+ c1=doc.getChar(index);
+ c2=doc.getChar(index+1);
+
+ // skip anything within a single-line comment
+ if (singleComment) {
+ char c3=doc.getChar(index-1);
+ if (c3 != '\\' && (c1 == '\n' || c1 == '\r' && c2 == '\n' )) {
+ singleComment=false;
+ }
+ index++;
+ continue;
+ }
+ // skip anything within a multi-line comment
+ if (multiComment) {
+ if (c1 == '*' && c2 == '/') {
+ multiComment=false;
+ index+=2;
+ continue;
+ }
+ index++;
+ continue;
+ }
+
+ switch(c1) {
+ case '+': {
+ switch(c2) {
+ case '=':
+ case '+':
+ actualEnd=index+2;
+ break;
+ default:
+ actualEnd=index+1;
+ break;
+ }
+ break;
+ }
+ case '-': {
+ switch(c2) {
+ case '=':
+ actualEnd=index+2;
+ break;
+ case '-':
+ switch(doc.getChar(index+2)) {
+ case '>': {
+ switch(doc.getChar(index+3)) {
+ case '*':
+ actualEnd=index+4;
+ break;
+ default:
+ actualEnd=index+3;
+ break;
+ }
+ break;
+ }
+ default:
+ actualEnd=index+2;
+ break;
+ }
+ break;
+ default:
+
+ break;
+ }
+ break;
+ }
+ case '|': {
+ switch(c2) {
+ case '=':
+ case '|':
+ actualEnd=index+2;
+ break;
+ default:
+ actualEnd=index+1;
+ break;
+ }
+ break;
+ }
+ case '&': {
+ switch(c2) {
+ case '=':
+ case '&':
+ actualEnd=index+2;
+ break;
+ default:
+ actualEnd=index+1;
+ break;
+ }
+ break;
+ }
+ case '/': {
+ switch(c2) {
+ case '/':
+ singleComment=true;
+ index+=2;
+ break;
+ case '*':
+ multiComment=true;
+ index+=2;
+ break;
+ case '=':
+ actualEnd=index+2;
+ break;
+ default:
+ actualEnd=index+1;
+ break;
+ }
+ break;
+ }
+ case '*':
+ case '%':
+ case '^':
+ case '!':
+ case '=': {
+ switch(c2) {
+ case '=':
+ actualEnd=index+2;
+ break;
+ default:
+ actualEnd=index+1;
+ break;
+ }
+ break;
+ }
+ case '(': {
+ if (possibleEnd > 0)
+ actualEnd = possibleEnd;
+ break;
+ }
+ case ']':
+ case ')':
+ case ',':
+ case '~': {
+ actualEnd=index+1;
+ break;
+ }
+ case '<': {
+ switch(c2) {
+ case '=':
+ case '<':
+ switch(doc.getChar(index+2)) {
+ case '=':
+ actualEnd=index+3;
+ break;
+ default:
+ actualEnd=index+2;
+ break;
+ }
+ break;
+ default:
+ actualEnd=index;
+ break;
+ }
+ break;
+ }
+ case '>': {
+ switch(c2) {
+ case '=':
+ case '>':
+ switch(doc.getChar(index+2)) {
+ case '=':
+ actualEnd=index+3;
+ break;
+ default:
+ actualEnd=index+2;
+ break;
+ }
+ break;
+ default:
+ actualEnd=index;
+ break;
+ }
+ break;
+ }
+ case 'n': { // start of "new"
+ while (doc.getChar(++index) != 'w');
+ possibleEnd=++index;
+ break;
+ }
+ case 'd': { // start of "delete"
+ while (doc.getChar(++index) != 't' && doc.getChar(index+1) != 'e');
+ index+=2;
+ possibleEnd=index;
+ break;
+ }
+ default:
+ index++;
+ break;
+ }
+ } catch (BadLocationException e) {
+ // something went wrong
+ return -1;
+ }
+ }
+
+ return actualEnd;
+ }
+
/**
* Return the selected string from the editor
* @return The string currently selected, or null if there is no valid selection