1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-06 09:16:02 +02:00

allow auto-generation of tags for pure virtual declarations, and between function declarators and comment bodies

This commit is contained in:
Andrew Ferguson 2008-03-13 15:22:23 +00:00
parent 72d5a9c713
commit c6068febf4
4 changed files with 157 additions and 60 deletions

View file

@ -126,8 +126,8 @@ public class DocCommentHighlightingTest extends BaseUITestCase {
} }
} }
protected List/*<Position>*/ findRangesColored(RGB rgb) { protected List<Position> findRangesColored(RGB rgb) {
List result= new ArrayList(); List<Position> result= new ArrayList<Position>();
IEditorPart p= get(); IEditorPart p= get();
ISourceViewer vw= ((CEditor)p).getViewer(); ISourceViewer vw= ((CEditor)p).getViewer();
Accessor a= new Accessor(vw, TextViewer.class); Accessor a= new Accessor(vw, TextViewer.class);
@ -156,8 +156,8 @@ public class DocCommentHighlightingTest extends BaseUITestCase {
return null; return null;
} }
private List/*<Position>*/ mkPositions(int[][] raw) { private List<Position> mkPositions(int[][] raw) {
List result= new ArrayList(); List<Position> result= new ArrayList<Position>();
for(int i=0; i<raw.length; i++) { for(int i=0; i<raw.length; i++) {
Assert.assertEquals(2, raw[i].length); Assert.assertEquals(2, raw[i].length);
result.add(new Position(raw[i][0], raw[i][1])); result.add(new Position(raw[i][0], raw[i][1]));
@ -168,42 +168,42 @@ public class DocCommentHighlightingTest extends BaseUITestCase {
public void testDCOM_A() throws BadLocationException, InterruptedException { public void testDCOM_A() throws BadLocationException, InterruptedException {
DCMAN.setCommentOwner(fCProject.getProject(), DCMAN.getOwner("org.cdt.test.ownerA"), true); DCMAN.setCommentOwner(fCProject.getProject(), DCMAN.getOwner("org.cdt.test.ownerA"), true);
runEventQueue(1000); runEventQueue(1000);
List/*<Position>*/ expected= mkPositions(new int[][] {comment1, scomment1}); List<Position> expected= mkPositions(new int[][] {comment1, scomment1});
assertEquals(expected, findRangesColored(TestGenericTagConfiguration.DEFAULTRGB)); assertEquals(expected, findRangesColored(TestGenericTagConfiguration.DEFAULTRGB));
} }
public void testDCOM_B() throws BadLocationException, InterruptedException { public void testDCOM_B() throws BadLocationException, InterruptedException {
DCMAN.setCommentOwner(fCProject.getProject(), DCMAN.getOwner("org.cdt.test.ownerB"), true); DCMAN.setCommentOwner(fCProject.getProject(), DCMAN.getOwner("org.cdt.test.ownerB"), true);
runEventQueue(1000); runEventQueue(1000);
List/*<Position>*/ expected= mkPositions(new int[][] {comment2, scomment2}); List<Position> expected= mkPositions(new int[][] {comment2, scomment2});
assertEquals(expected, findRangesColored(TestGenericTagConfiguration.DEFAULTRGB)); assertEquals(expected, findRangesColored(TestGenericTagConfiguration.DEFAULTRGB));
} }
public void testDCOM_C() throws BadLocationException, InterruptedException { public void testDCOM_C() throws BadLocationException, InterruptedException {
DCMAN.setCommentOwner(fCProject.getProject(), DCMAN.getOwner("org.cdt.test.ownerC"), true); DCMAN.setCommentOwner(fCProject.getProject(), DCMAN.getOwner("org.cdt.test.ownerC"), true);
runEventQueue(1000); runEventQueue(1000);
List/*<Position>*/ expected= mkPositions(new int[][] {comment3, scomment3}); List<Position> expected= mkPositions(new int[][] {comment3, scomment3});
assertEquals(expected, findRangesColored(TestGenericTagConfiguration.DEFAULTRGB)); assertEquals(expected, findRangesColored(TestGenericTagConfiguration.DEFAULTRGB));
} }
public void testDCOM_ABC() throws BadLocationException, InterruptedException { public void testDCOM_ABC() throws BadLocationException, InterruptedException {
DCMAN.setCommentOwner(fCProject.getProject(), DCMAN.getOwner("org.cdt.test.ownerABC"), true); DCMAN.setCommentOwner(fCProject.getProject(), DCMAN.getOwner("org.cdt.test.ownerABC"), true);
runEventQueue(1000); runEventQueue(1000);
List/*<Position>*/ expected= mkPositions(new int[][] {comment1, comment2, comment3, scomment1, scomment2, scomment3}); List<Position> expected= mkPositions(new int[][] {comment1, comment2, comment3, scomment1, scomment2, scomment3});
assertEquals(expected, findRangesColored(TestGenericTagConfiguration.DEFAULTRGB)); assertEquals(expected, findRangesColored(TestGenericTagConfiguration.DEFAULTRGB));
} }
public void testDCOM_BDFG() throws BadLocationException, InterruptedException { public void testDCOM_BDFG() throws BadLocationException, InterruptedException {
DCMAN.setCommentOwner(fCProject.getProject(), DCMAN.getOwner("org.cdt.test.ownerBDFG"), true); DCMAN.setCommentOwner(fCProject.getProject(), DCMAN.getOwner("org.cdt.test.ownerBDFG"), true);
runEventQueue(1000); runEventQueue(1000);
List/*<Position>*/ expected= mkPositions(new int[][] {comment2, comment4, comment6, comment7, comment8, scomment2}); List<Position> expected= mkPositions(new int[][] {comment2, comment4, comment6, comment7, comment8, scomment2});
assertEquals(expected, findRangesColored(TestGenericTagConfiguration.DEFAULTRGB)); assertEquals(expected, findRangesColored(TestGenericTagConfiguration.DEFAULTRGB));
} }
public void testDCOM_PUNC() throws BadLocationException, InterruptedException { public void testDCOM_PUNC() throws BadLocationException, InterruptedException {
DCMAN.setCommentOwner(fCProject.getProject(), DCMAN.getOwner("org.cdt.test.ownerPUNC"), true); DCMAN.setCommentOwner(fCProject.getProject(), DCMAN.getOwner("org.cdt.test.ownerPUNC"), true);
runEventQueue(1000); runEventQueue(1000);
List/*<Position>*/ expected= mkPositions(new int[][] {comment9, comment10, scomment4, scomment5, comment11, comment12, scomment7}); List<Position> expected= mkPositions(new int[][] {comment9, comment10, scomment4, scomment5, comment11, comment12, scomment7});
assertEquals(expected, findRangesColored(TestGenericTagConfiguration.DEFAULTRGB)); assertEquals(expected, findRangesColored(TestGenericTagConfiguration.DEFAULTRGB));
} }
} }

View file

@ -236,10 +236,43 @@ public class DoxygenCCommentAutoEditStrategyTest extends DefaultCCommentAutoEdit
// * @param x // * @param x
// */ // */
// {} // {}
public void _testAutoDocCommentContent9() throws CoreException { public void testAutoDocCommentContent9() throws CoreException {
assertAutoEditBehaviour();
}
// /**
// *
// */
// void foo_bar(int x)
// /**X
// {}
// /**
// *
// */
// void foo_bar(int x)
// /**
// * X
// * @param x
// */
// {}
public void testAutoDocCommentContent9b() throws CoreException {
assertAutoEditBehaviour();
}
// void foo_bar(int x)
// {
// /**X
// }
// void foo_bar(int x)
// {
// /**
// * X
// */
// }
public void testAutoDocCommentContent9c() throws CoreException {
assertAutoEditBehaviour(); assertAutoEditBehaviour();
// TODO - desired behaviour when there is a comment preceding the declaration
// needs defining
} }
// void foo_bar(int x) // void foo_bar(int x)
@ -352,6 +385,41 @@ public class DoxygenCCommentAutoEditStrategyTest extends DefaultCCommentAutoEdit
assertAutoEditBehaviour(); assertAutoEditBehaviour();
} }
// class D {
// public:
// /**X
// virtual void foo(D x) = 0;
// };
// class D {
// public:
// /**
// * X
// * @param x
// */
// virtual void foo(D x) = 0;
// };
public void testAutoDocCommentContent18() throws CoreException {
assertAutoEditBehaviour();
}
// class D {
// public:
// /**X
// virtual void foo(D x);
// };
// class D {
// public:
// /**
// * X
// */
// virtual void foo(D x);
// };
public void testAutoDocCommentContent19() throws CoreException {
assertAutoEditBehaviour();
}
protected void assertAutoEditBehaviour() throws CoreException { protected void assertAutoEditBehaviour() throws CoreException {
CTextTools textTools = CUIPlugin.getDefault().getTextTools(); CTextTools textTools = CUIPlugin.getDefault().getTextTools();
final IDocument doc = new Document(); final IDocument doc = new Document();

View file

@ -34,7 +34,9 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
@ -109,7 +111,7 @@ public class DefaultMultilineCommentAutoEditStrategy implements IAutoEditStrateg
if (offset == -1 || doc.getLength() == 0) if (offset == -1 || doc.getLength() == 0)
return; return;
final StringBuffer buf= new StringBuffer(c.text); final StringBuilder buf= new StringBuilder(c.text);
try { try {
// find start of line // find start of line
IRegion line= doc.getLineInformationOfOffset(c.offset); IRegion line= doc.getLineInformationOfOffset(c.offset);
@ -134,17 +136,25 @@ public class DefaultMultilineCommentAutoEditStrategy implements IAutoEditStrateg
try { try {
doc.replace(c.offset, 0, indentation+" "+MULTILINE_END); // close the comment in order to parse //$NON-NLS-1$ doc.replace(c.offset, 0, indentation+" "+MULTILINE_END); // close the comment in order to parse //$NON-NLS-1$
buf.append("\n"); //$NON-NLS-1$ buf.append("\n"); //$NON-NLS-1$
// as we are auto-closing, the comment becomes eligible for auto-doc'ing // as we are auto-closing, the comment becomes eligible for auto-doc'ing
IASTDeclaration dec= findFollowingDeclaration(getAST(), offset); IASTDeclaration dec= null;
IASTTranslationUnit ast= getAST();
// TODO - it is also needed to support auto-tagging when closing a comment
// within a function declaration. See DoxygenCCommentAutoEditStrategyTest._testAutoDocCommentContent9()
// and DoxygenCCommentAutoEditStrategyTest._testAutoDocCommentContent10()
if(ast != null) {
dec= findFollowingDeclaration(ast, offset);
if(dec == null) {
IASTNodeSelector ans= ast.getNodeSelector(ast.getFilePath());
IASTNode node= ans.findEnclosingNode(offset, 0);
if(node instanceof IASTDeclaration) {
dec= (IASTDeclaration) node;
}
}
}
if(dec!=null) { if(dec!=null) {
ITypedRegion partition= TextUtilities.getPartition(doc, ICPartitions.C_PARTITIONING /* this! */, offset, false); ITypedRegion partition= TextUtilities.getPartition(doc, ICPartitions.C_PARTITIONING /* this! */, offset, false);
StringBuffer content= customizeAfterNewLineForDeclaration(doc, dec, partition); StringBuilder content= customizeAfterNewLineForDeclaration(doc, dec, partition);
buf.append(indent(content, indentation + MULTILINE_MID)); buf.append(indent(content, indentation + MULTILINE_MID));
} }
@ -160,8 +170,8 @@ public class DefaultMultilineCommentAutoEditStrategy implements IAutoEditStrateg
} }
} }
protected StringBuffer customizeAfterNewLineForDeclaration(IDocument doc, IASTDeclaration dec, ITypedRegion region) { protected StringBuilder customizeAfterNewLineForDeclaration(IDocument doc, IASTDeclaration dec, ITypedRegion region) {
return new StringBuffer(); return new StringBuilder();
} }
/* /*
@ -307,8 +317,8 @@ public class DefaultMultilineCommentAutoEditStrategy implements IAutoEditStrateg
* @param buffer * @param buffer
* @param indent * @param indent
*/ */
protected static final StringBuffer indent(StringBuffer buffer, String indent) { protected static final StringBuilder indent(StringBuilder buffer, String indent) {
StringBuffer result= new StringBuffer(); StringBuilder result= new StringBuilder();
BufferedReader br= new BufferedReader(new StringReader(buffer.toString())); BufferedReader br= new BufferedReader(new StringReader(buffer.toString()));
try { try {
for(String line= br.readLine(); line!=null; line= br.readLine()) { for(String line= br.readLine(); line!=null; line= br.readLine()) {

View file

@ -31,6 +31,8 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.ui.text.doctools.DefaultMultilineCommentAutoEditStrategy; import org.eclipse.cdt.ui.text.doctools.DefaultMultilineCommentAutoEditStrategy;
@ -45,11 +47,33 @@ public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAut
private static final String PARAM = "@param "; //$NON-NLS-1$ private static final String PARAM = "@param "; //$NON-NLS-1$
private static final String RETURN = "@return\n"; //$NON-NLS-1$ private static final String RETURN = "@return\n"; //$NON-NLS-1$
/** protected boolean documentPureVirtuals= true;
* Default constructor
*/
public DoxygenMultilineAutoEditStrategy() {
public DoxygenMultilineAutoEditStrategy() {
}
/**
* @param decl the function declarator to document
* @param ds the function specifier to document
* @return content describing the specified function
*/
protected StringBuilder documentFunction(IASTFunctionDeclarator decl, IASTDeclSpecifier ds) {
StringBuilder result= new StringBuilder();
result.append(documentFunctionParameters(getParameterDecls(decl)));
boolean hasReturn= true;
if(ds instanceof IASTSimpleDeclSpecifier) {
IASTSimpleDeclSpecifier sds= (IASTSimpleDeclSpecifier) ds;
if(sds.getType()==IASTSimpleDeclSpecifier.t_void) {
hasReturn= false;
}
}
if(hasReturn) {
result.append(documentFunctionReturn());
}
return result;
} }
/** /**
@ -58,7 +82,7 @@ public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAut
* @return a buffer containing the comment content to generate to describe the parameters of * @return a buffer containing the comment content to generate to describe the parameters of
* the specified {@link IASTParameterDeclaration} objects. * the specified {@link IASTParameterDeclaration} objects.
*/ */
protected StringBuffer paramTags(IASTParameterDeclaration[] decls) { protected StringBuffer documentFunctionParameters(IASTParameterDeclaration[] decls) {
StringBuffer result= new StringBuffer(); StringBuffer result= new StringBuffer();
for(int i=0; i<decls.length; i++) { for(int i=0; i<decls.length; i++) {
IASTDeclarator dtor= decls[i].getDeclarator(); IASTDeclarator dtor= decls[i].getDeclarator();
@ -68,19 +92,18 @@ public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAut
} }
/** /**
* @return the comment content to describe the return tag * @return the comment content to describe the return
*/ */
protected StringBuffer returnTag() { protected StringBuffer documentFunctionReturn() {
return new StringBuffer(RETURN); return new StringBuffer(RETURN);
} }
/** /**
* @param def the function definition to analyze * @param decl the function declarator to analyze
* @return the parameter declarations for the specified function definition * @return the parameter declarations for the specified function definition
*/ */
protected IASTParameterDeclaration[] getParameterDecls(IASTFunctionDefinition def) { protected IASTParameterDeclaration[] getParameterDecls(IASTFunctionDeclarator decl) {
IASTParameterDeclaration[] result; IASTParameterDeclaration[] result;
IASTFunctionDeclarator decl= def.getDeclarator();
if (decl instanceof IASTStandardFunctionDeclarator) { if (decl instanceof IASTStandardFunctionDeclarator) {
IASTStandardFunctionDeclarator standardFunctionDecl= (IASTStandardFunctionDeclarator)decl; IASTStandardFunctionDeclarator standardFunctionDecl= (IASTStandardFunctionDeclarator)decl;
result= standardFunctionDecl.getParameters(); result= standardFunctionDecl.getParameters();
@ -96,33 +119,31 @@ public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAut
/* /*
* @see org.eclipse.cdt.ui.text.doctools.DefaultMultilineCommentAutoEditStrategy#customizeAfterNewLineForDeclaration(org.eclipse.jface.text.IDocument, org.eclipse.cdt.core.dom.ast.IASTDeclaration, org.eclipse.jface.text.ITypedRegion) * @see org.eclipse.cdt.ui.text.doctools.DefaultMultilineCommentAutoEditStrategy#customizeAfterNewLineForDeclaration(org.eclipse.jface.text.IDocument, org.eclipse.cdt.core.dom.ast.IASTDeclaration, org.eclipse.jface.text.ITypedRegion)
*/ */
public StringBuffer customizeAfterNewLineForDeclaration(IDocument doc, IASTDeclaration dec, ITypedRegion partition) { protected StringBuilder customizeAfterNewLineForDeclaration(IDocument doc, IASTDeclaration dec, ITypedRegion partition) {
StringBuffer result= new StringBuffer();
while(dec instanceof ICPPASTTemplateDeclaration) /* if? */ while(dec instanceof ICPPASTTemplateDeclaration) /* if? */
dec= ((ICPPASTTemplateDeclaration)dec).getDeclaration(); dec= ((ICPPASTTemplateDeclaration)dec).getDeclaration();
if(dec instanceof IASTFunctionDefinition) { if(dec instanceof IASTFunctionDefinition) {
IASTFunctionDefinition fd= (IASTFunctionDefinition) dec; IASTFunctionDefinition fd= (IASTFunctionDefinition) dec;
result.append(paramTags(getParameterDecls(fd))); return documentFunction(fd.getDeclarator(), fd.getDeclSpecifier());
IASTDeclSpecifier ds= fd.getDeclSpecifier();
boolean hasReturn= true;
if(ds instanceof IASTSimpleDeclSpecifier) {
IASTSimpleDeclSpecifier sds= (IASTSimpleDeclSpecifier) ds;
if(sds.getType()==IASTSimpleDeclSpecifier.t_void) {
hasReturn= false;
}
}
if(hasReturn) {
result.append(returnTag());
}
return result;
} }
if(dec instanceof IASTSimpleDeclaration && ((IASTSimpleDeclaration)dec).getDeclSpecifier() instanceof IASTCompositeTypeSpecifier) { if(dec instanceof IASTSimpleDeclaration) {
return result; IASTSimpleDeclaration sdec= (IASTSimpleDeclaration) dec;
StringBuilder result= new StringBuilder();
if(sdec.getDeclSpecifier() instanceof IASTCompositeTypeSpecifier) {
return result;
} else if(documentPureVirtuals && sdec.getDeclSpecifier() instanceof ICPPASTDeclSpecifier) {
IASTDeclarator[] dcs= sdec.getDeclarators();
if(dcs.length == 1) {
ICPPASTFunctionDeclarator fdecl= (ICPPASTFunctionDeclarator) sdec.getDeclarators()[0];
if(fdecl.isPureVirtual()) {
return documentFunction(fdecl, sdec.getDeclSpecifier());
}
}
}
} }
try { try {
@ -131,7 +152,7 @@ public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAut
/*ignore*/ /*ignore*/
} }
return new StringBuffer(); return new StringBuilder();
} }
/* /*
@ -167,16 +188,14 @@ public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAut
boolean noCollisions= true; boolean noCollisions= true;
LinkedHashSet<Entry> entries= new LinkedHashSet<Entry>(); LinkedHashSet<Entry> entries= new LinkedHashSet<Entry>();
for(IASTEnumerator enumerator : enms) { for(IASTEnumerator enumerator : enms) {
IASTNodeLocation[] locs= enumerator.getName().getNodeLocations(); IASTNodeLocation loc= enumerator.getName().getFileLocation();
if(locs.length==1) { if(loc != null) {
int nodeOffset= locs[0].getNodeOffset()+locs[0].getNodeLength(); int nodeOffset= loc.getNodeOffset()+loc.getNodeLength();
String cmt= SINGLELINE_COMMENT_PRECEDING+enumerator.getName(); String cmt= SINGLELINE_COMMENT_PRECEDING+enumerator.getName();
IRegion line= doc.getLineInformationOfOffset(nodeOffset); IRegion line= doc.getLineInformationOfOffset(nodeOffset);
if(!doc.get(line.getOffset(), line.getLength()).contains("//")) { //$NON-NLS-1$ if(!doc.get(line.getOffset(), line.getLength()).contains("//")) { //$NON-NLS-1$
noCollisions &= entries.add(new Entry(line.getOffset(),line.getLength(), cmt)); noCollisions &= entries.add(new Entry(line.getOffset(),line.getLength(), cmt));
} }
} else {
// TODO
} }
} }