1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Patch for Devin Steffler.

FIXED 86993- [Selection] CPPASTLinkageSpecification with bad offset due to macro expansion causes selection to fail in CPP
FIXED 93167- [Open Declaration] on destructor requires the entire word to be selected
FIXED 92632- [IBinding] CPPClassInstance binding has no declaration
FIXED - prevent DOM AST View from showing internal interfaces
This commit is contained in:
John Camelon 2005-04-29 00:56:11 +00:00
parent 99aff8d4bd
commit 5e0e6d7eb2
10 changed files with 177 additions and 55 deletions

View file

@ -12,6 +12,7 @@ package org.eclipse.cdt.core.parser.tests.ast2;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.search.DOMSearchUtil;
import org.eclipse.cdt.core.search.ICSearchConstants;
import org.eclipse.core.resources.IFile;
/**
@ -65,10 +66,10 @@ public class DOMSelectionParseBaseTest extends DOMFileBasePluginTest {
}
protected IASTName[] getDeclarationOffTU(IASTName name) {
return name.getTranslationUnit().getDeclarations(name.resolveBinding());
return DOMSearchUtil.getNamesFromDOM(name, ICSearchConstants.DECLARATIONS);
}
protected IASTName[] getReferencesOffTU(IASTName name) {
return name.getTranslationUnit().getReferences(name.resolveBinding());
return DOMSearchUtil.getNamesFromDOM(name, ICSearchConstants.REFERENCES);
}
}

View file

@ -24,12 +24,15 @@ import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.c.ICExternalBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
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.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.model.CProject;
@ -1674,6 +1677,65 @@ public class DOMSelectionParseTest extends DOMSelectionParseBaseTest {
assertEquals( ((ASTNode)decls[0]).getOffset(), 38);
assertEquals( ((ASTNode)decls[0]).getLength(), 9);
}
public void testBug86993() throws Exception
{
StringBuffer buffer = new StringBuffer();
buffer.append("#define _BEGIN_STD_C extern \"C\" {\n"); //$NON-NLS-1$
buffer.append("#define _END_STD_C }\n"); //$NON-NLS-1$
buffer.append("_BEGIN_STD_C\n"); //$NON-NLS-1$
buffer.append("char c; // selection on this fails because offset for \n"); //$NON-NLS-1$
buffer.append("_END_STD_C\n"); //$NON-NLS-1$
buffer.append("char foo() {\n"); //$NON-NLS-1$
buffer.append("return c; \n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
String code = buffer.toString();
int index = code.indexOf("return c;"); //$NON-NLS-1$
IASTNode node = parse( code, index + 7, index + 8, true );
assertNotNull( node );
assertTrue( node instanceof IASTName );
assertTrue( ((IASTName)node).resolveBinding() instanceof ICPPVariable );
assertEquals( ((IASTName)node).toString(), "c" ); //$NON-NLS-1$
IASTName[] decls = getDeclarationOffTU((IASTName)node);
assertEquals(decls.length, 1);
assertEquals( decls[0].toString(), "c" ); //$NON-NLS-1$
assertEquals( ((ASTNode)decls[0]).getOffset(), 86);
assertEquals( ((ASTNode)decls[0]).getLength(), 1);
index = code.indexOf("char c"); //$NON-NLS-1$
node = parse( code, index + 5, index + 6, true );
assertNotNull( node );
assertTrue( node instanceof IASTName );
assertTrue( ((IASTName)node).resolveBinding() instanceof ICPPVariable );
IASTName[] refs = getReferencesOffTU((IASTName)node);
assertEquals(refs.length, 1);
assertEquals( refs[0].toString(), "c" ); //$NON-NLS-1$
assertEquals( ((ASTNode)refs[0]).getOffset(), 168);
assertEquals( ((ASTNode)decls[0]).getLength(), 1);
}
public void testBug92632() throws Exception
{
StringBuffer buffer = new StringBuffer();
buffer.append("namespace N{ \n"); //$NON-NLS-1$
buffer.append(" template < class T > class AAA { T _t; };\n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
buffer.append("N::AAA<int> a; \n"); //$NON-NLS-1$
String code = buffer.toString();
int index = code.indexOf("AAA<int>"); //$NON-NLS-1$
IASTNode node = parse( code, index, index + 8, true );
assertNotNull( node );
assertTrue( node instanceof IASTName );
assertTrue( ((IASTName)node).resolveBinding() instanceof ICPPTemplateInstance );
assertEquals( ((IASTName)node).toString(), "AAA" ); //$NON-NLS-1$
IASTName[] decls = getDeclarationOffTU((IASTName)node);
assertEquals(decls.length, 1);
assertEquals( decls[0].toString(), "AAA" ); //$NON-NLS-1$
assertEquals( ((ASTNode)decls[0]).getOffset(), 53);
assertEquals( ((ASTNode)decls[0]).getLength(), 3);
}
}

View file

@ -39,6 +39,7 @@ 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;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.filetype.ICFileType;
import org.eclipse.cdt.core.filetype.ICFileTypeConstants;
import org.eclipse.cdt.core.parser.ParseError;
@ -211,32 +212,32 @@ public class DOMSearchUtil {
if (node instanceof IASTName) {
IASTName[] results = new IASTName[1];
results[0] = (IASTName)node;
return results;
} else {
ASTVisitor collector = null;
if (getLanguageFromFile(file) == ParserLanguage.CPP) {
collector = new CPPNameCollector();
} else {
collector = new CNameCollector();
}
node.accept( collector );
List names = null;
if (collector instanceof CPPNameCollector) {
names = ((CPPNameCollector)collector).nameList;
} else {
names = ((CNameCollector)collector).nameList;
}
IASTName[] results = new IASTName[names.size()];
for(int i=0; i<names.size(); i++) {
if (names.get(i) instanceof IASTName)
results[i] = (IASTName)names.get(i);
}
return results;
}
ASTVisitor collector = null;
if (getLanguageFromFile(file) == ParserLanguage.CPP) {
collector = new CPPNameCollector();
} else {
collector = new CNameCollector();
}
node.accept( collector );
List names = null;
if (collector instanceof CPPNameCollector) {
names = ((CPPNameCollector)collector).nameList;
} else {
names = ((CNameCollector)collector).nameList;
}
IASTName[] results = new IASTName[names.size()];
for(int i=0; i<names.size(); i++) {
if (names.get(i) instanceof IASTName)
results[i] = (IASTName)names.get(i);
}
return results;
}
/**
@ -272,13 +273,20 @@ public class DOMSearchUtil {
return BLANK_NAME_ARRAY;
}
// fix for 92632
IBinding binding = searchName.resolveBinding();
if (binding instanceof ICPPTemplateInstance) {
if (((ICPPTemplateInstance)binding).getOriginalBinding() != null)
binding = ((ICPPTemplateInstance)binding).getOriginalBinding();
}
if (limitTo == ICSearchConstants.DECLARATIONS) {
names = tu.getDeclarations(searchName.resolveBinding());
names = tu.getDeclarations(binding);
} else if (limitTo == ICSearchConstants.REFERENCES) {
names = tu.getReferences(searchName.resolveBinding());
names = tu.getReferences(binding);
} else { // assume ALL
names = tu.getDeclarations(searchName.resolveBinding());
names = (IASTName[])ArrayUtil.addAll(IASTName.class, names, tu.getReferences(searchName.resolveBinding()));
names = tu.getDeclarations(binding);
names = (IASTName[])ArrayUtil.addAll(IASTName.class, names, tu.getReferences(binding));
}
return names;

View file

@ -56,7 +56,8 @@ import org.eclipse.ui.views.properties.TextPropertyDescriptor;
* @author dsteffle
*/
public class DOMASTNodeLeaf implements IAdaptable {
private static final String VARIABLE_SIZED_ = "* "; //$NON-NLS-1$
private static final String INTERNAL = "internal"; //$NON-NLS-1$
private static final String VARIABLE_SIZED_ = "* "; //$NON-NLS-1$
private static final String VOLATILE_ = "volatile "; //$NON-NLS-1$
private static final String STATIC_ = "static "; //$NON-NLS-1$
private static final String RESTRICT_ = "restrict "; //$NON-NLS-1$
@ -114,10 +115,15 @@ public class DOMASTNodeLeaf implements IAdaptable {
Class[] classes = node.getClass().getInterfaces();
for(int i=0; i<classes.length; i++) {
if (classes[i].getPackage().toString().indexOf(INTERNAL) >= 0)
continue;
String interfaceName = classes[i].getName().substring(classes[i].getName().lastIndexOf(PERIOD) + 1);
if (hasProperPrefix(interfaceName)) {
buffer.append(interfaceName);
if (i+1 < classes.length && hasProperPrefix(classes[i+1].getName().substring(classes[i+1].getName().lastIndexOf(PERIOD) + 1)))
if (i+1 < classes.length &&
hasProperPrefix(classes[i+1].getName().substring(classes[i+1].getName().lastIndexOf(PERIOD) + 1)) &&
classes[i+1].getPackage().toString().indexOf(INTERNAL) < 0)
buffer.append(LIST_SEPARATOR);
}
}

View file

@ -196,10 +196,10 @@ public abstract class FindAction extends SelectionParseAction {
// TODO Devin should be able to implement this somehow, see PR 78118
operationNotAvailable(CSEARCH_OPERATION_OPERATION_UNAVAILABLE_MESSAGE);
return;
} else {
resourceFile = fEditor.getInputFile();
}
resourceFile = fEditor.getInputFile();
IASTTranslationUnit tu = null;
IASTNode foundNode = null;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* 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 v0.5
* which accompanies this distribution, and is available at

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* 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 v0.5
* which accompanies this distribution, and is available at
@ -24,7 +24,7 @@ import org.eclipse.ui.IWorkingSet;
public class FindDeclarationsInWorkingSetAction extends FindAction {
private IWorkingSet[] fWorkingSet;
private String scopeDescription = "";
private String scopeDescription = ""; //$NON-NLS-1$
/**
* @param site
*/

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* 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 v0.5
* which accompanies this distribution, and is available at

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* 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 v0.5
* which accompanies this distribution, and is available at
@ -24,7 +24,7 @@ import org.eclipse.ui.IWorkingSet;
public class FindRefsInWorkingSetAction extends FindAction {
private IWorkingSet[] fWorkingSet;
private String scopeDescription = "";
private String scopeDescription = ""; //$NON-NLS-1$
public FindRefsInWorkingSetAction(CEditor editor, IWorkingSet[] workingSets) {
this(editor,

View file

@ -20,6 +20,7 @@ import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IParser;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.core.parser.NullSourceElementRequestor;
import org.eclipse.cdt.core.parser.ParserFactory;
import org.eclipse.cdt.core.parser.ParserFactoryError;
@ -168,7 +169,7 @@ public class SelectionParseAction extends Action {
//TODO: Change this to work with qualified identifiers
public SelSearchNode getSelection( int fPos ) {
IDocumentProvider prov = ( fEditor != null ) ? fEditor.getDocumentProvider() : null;
IDocumentProvider prov = ( fEditor != null ) ? fEditor.getDocumentProvider() : null;
IDocument doc = ( prov != null ) ? prov.getDocument(fEditor.getEditorInput()) : null;
if( doc == null )
@ -177,6 +178,7 @@ public class SelectionParseAction extends Action {
int pos= fPos;
char c;
int fStartPos =0, fEndPos=0;
int nonJavaStart=-1, nonJavaEnd=-1;
String selectedWord=null;
try{
@ -185,7 +187,11 @@ public class SelectionParseAction extends Action {
// TODO this logic needs to be improved
// ex: ~destr[cursor]uctors, p2->ope[cursor]rator=(zero), etc
if (!Character.isJavaIdentifierPart(c))
if (nonJavaStart == -1 && !Character.isJavaIdentifierPart(c)) {
nonJavaStart=pos+1;
}
if (Character.isWhitespace(c))
break;
--pos;
@ -196,22 +202,61 @@ public class SelectionParseAction extends Action {
int length= doc.getLength();
while (pos < length) {
c= doc.getChar(pos);
if (!Character.isJavaIdentifierPart(c))
break;
if (nonJavaEnd == -1 && !Character.isJavaIdentifierPart(c)) {
nonJavaEnd=pos;
}
if (Character.isWhitespace(c))
break;
++pos;
}
fEndPos= pos;
selectedWord = doc.get(fStartPos, (fEndPos - fStartPos));
}
catch(BadLocationException e){
}
SelSearchNode sel = new SelSearchNode();
sel.selText = selectedWord;
sel.selStart = fStartPos;
sel.selEnd = fEndPos;
return sel;
}
catch(BadLocationException e){
}
SelSearchNode sel = new SelSearchNode();
// 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))) {
int tildePos = selectedWord.indexOf('~');
int actualStart=fStartPos + tildePos;
int length=0;
char temp;
char[] lastSegment = selectedWord.substring(tildePos).toCharArray();
for(int i=1; i<lastSegment.length; i++) {
temp = lastSegment[i];
if (!Character.isJavaIdentifierPart(temp)) {
length=i;
break;
}
}
// if the cursor is after the destructor name then use the regular boundaries
if (fPos >= actualStart + length) {
try {
sel.selText = doc.get(nonJavaStart, (nonJavaEnd - nonJavaStart));
} catch (BadLocationException e) {}
sel.selStart = nonJavaStart;
sel.selEnd = nonJavaEnd;
} else {
try {
sel.selText = doc.get(actualStart, length);
} catch (BadLocationException e) {}
sel.selStart = actualStart;
sel.selEnd = actualStart + length;
}
} else {
// otherwise use the non-java identifier parts as boundaries for the selection
try {
sel.selText = doc.get(nonJavaStart, (nonJavaEnd - nonJavaStart));
} catch (BadLocationException e) {}
sel.selStart = nonJavaStart;
sel.selEnd = nonJavaEnd;
}
return sel;
}
/**