diff --git a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF index 56e04276255..734a8662157 100644 --- a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.ui; singleton:=true -Bundle-Version: 6.6.300.qualifier +Bundle-Version: 6.7.0.qualifier Bundle-Activator: org.eclipse.cdt.ui.CUIPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/DefaultMultilineCommentAutoEditStrategy.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/DefaultMultilineCommentAutoEditStrategy.java index 1ccfec16c52..d7e3796c3e5 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/DefaultMultilineCommentAutoEditStrategy.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/DefaultMultilineCommentAutoEditStrategy.java @@ -24,7 +24,9 @@ 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.IASTNodeSelector; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.model.CModelException; @@ -64,6 +66,14 @@ public class DefaultMultilineCommentAutoEditStrategy implements IAutoEditStrateg private static String fgDefaultLineDelim = "\n"; //$NON-NLS-1$ private ICProject fProject; + /** + * @since 6.7 + */ + public interface IDocCustomizer { + StringBuilder customizeForDeclaration(IDocument doc, IASTNode dec, ITypedRegion region, + CustomizeOptions options); + } + public DefaultMultilineCommentAutoEditStrategy() { this(null); } @@ -183,7 +193,7 @@ public class DefaultMultilineCommentAutoEditStrategy implements IAutoEditStrateg buf.append(lineDelim); // as we are auto-closing, the comment becomes eligible for auto-doc'ing - IASTDeclaration dec = null; + IASTNode dec = null; IIndex index = null; ITranslationUnit unit = getTranslationUnitForActiveEditor(); if (unit != null) { @@ -197,22 +207,49 @@ public class DefaultMultilineCommentAutoEditStrategy implements IAutoEditStrateg try { IASTTranslationUnit ast = getAST(unit, index); - 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 (this instanceof IDocCustomizer) { + if (ast != null) { + dec = findNextDocumentNode(ast, offset); + if (dec == null) { + IASTNodeSelector ans = ast.getNodeSelector(ast.getFilePath()); + IASTNode node = ans.findEnclosingNode(offset, 0); + if (node instanceof IASTDeclaration) { + dec = node; + } } } - } - if (dec != null) { - ITypedRegion partition = TextUtilities.getPartition(doc, - ICPartitions.C_PARTITIONING /* this! */, offset, false); - StringBuilder content = customizeAfterNewLineForDeclaration(doc, dec, partition); - buf.append(indent(content, indentation + MULTILINE_MID, lineDelim)); + if (dec != null) { + ITypedRegion partition = TextUtilities.getPartition(doc, + ICPartitions.C_PARTITIONING /* this! */, offset, false); + StringBuilder content = null; + IDocCustomizer customizer = (IDocCustomizer) this; + CustomizeOptions options = new CustomizeOptions(); + content = customizer.customizeForDeclaration(doc, dec, partition, options); + if (!options.addNewLine) { + buf.setLength(buf.length() - MULTILINE_MID.length() - lineDelim.length()); + } + buf.append(indent(content, indentation + MULTILINE_MID, lineDelim)); + } + } else { + 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 = node; + } + } + } + + if (dec != null) { + ITypedRegion partition = TextUtilities.getPartition(doc, + ICPartitions.C_PARTITIONING /* this! */, offset, false); + StringBuilder content = null; + content = customizeAfterNewLineForDeclaration(doc, (IASTDeclaration) dec, partition); + buf.append(indent(content, indentation + MULTILINE_MID, lineDelim)); + } } } finally { if (index != null) { @@ -233,6 +270,28 @@ public class DefaultMultilineCommentAutoEditStrategy implements IAutoEditStrateg } } + /** + * Options set by IDocCustomize + * @since 6.7 + */ + public static class CustomizeOptions { + /** + * Child of IDocCustomize can decide to add a new line + * before their comment body or not. By default a new + * line is added. + */ + public boolean addNewLine; + + public CustomizeOptions() { + addNewLine = true; + } + } + + /** + * @deprecated This class is deprecated, clients should implement IDocCustomizer + * interface instead. + */ + @Deprecated protected StringBuilder customizeAfterNewLineForDeclaration(IDocument doc, IASTDeclaration dec, ITypedRegion region) { return new StringBuilder(); @@ -242,6 +301,102 @@ public class DefaultMultilineCommentAutoEditStrategy implements IAutoEditStrateg * Utilities */ + private static class SearchVisitor extends ASTVisitor { + + public SearchVisitor(int offset) { + shouldVisitTranslationUnit = true; + shouldVisitDeclarations = true; + shouldVisitNamespaces = true; + this.offset = offset; + } + + private int nearestOffset = Integer.MAX_VALUE; + private int offset; + private IASTDeclaration target; + + public int getNearest() { + return nearestOffset; + } + + public IASTDeclaration getTarget() { + return target; + } + + @Override + public int visit(ICPPASTNamespaceDefinition namespace) { + IASTNodeLocation loc = namespace.getFileLocation(); + if (loc != null) { + int candidateOffset = loc.getNodeOffset(); + if (offset <= candidateOffset && candidateOffset <= nearestOffset) { + nearestOffset = candidateOffset; + target = namespace; + return PROCESS_ABORT; + } + } + return PROCESS_CONTINUE; + } + + /** + * Holds the + */ + IASTDeclaration stopWhenLeaving; + + @Override + public int visit(IASTDeclaration declaration) { + IASTNodeLocation loc = declaration.getFileLocation(); + if (loc != null) { + int candidateOffset = loc.getNodeOffset(); + int candidateEndOffset = candidateOffset + loc.getNodeLength(); + + if (offset <= candidateOffset && candidateOffset <= nearestOffset) { + nearestOffset = candidateOffset; + target = declaration; + return PROCESS_ABORT; + } + + boolean candidateEnclosesOffset = (offset >= candidateOffset) && (offset < candidateEndOffset); + if (candidateEnclosesOffset) { + stopWhenLeaving = declaration; + } + } + return PROCESS_CONTINUE; + } + + @Override + public int leave(IASTDeclaration declaration) { + if (declaration == stopWhenLeaving) + return PROCESS_ABORT; + return PROCESS_CONTINUE; + } + } + + /** + * Locates the {@link IASTNode} most immediately following the specified offset + * @param unit the translation unit, or null (in which case the result will also be null) + * @param offset the offset to begin the search from + * @return the {@link IASTNode} most immediately following the specified offset, or null if there + * is no node suitable for documentation, i.e. a declaration or a macro definition + * @since 6.7 + */ + public static IASTNode findNextDocumentNode(IASTTranslationUnit unit, final int offset) { + IASTNode bestNode = null; + if (unit != null) { + IASTPreprocessorMacroDefinition[] macros = unit.getMacroDefinitions(); + SearchVisitor av = new SearchVisitor(offset); + unit.accept(av); + int nearest = av.getNearest(); + bestNode = av.getTarget(); + for (IASTPreprocessorMacroDefinition m : macros) { + if (m.getExpansionLocation() != null && m.getExpansionLocation().getNodeOffset() < nearest + && offset <= m.getExpansionLocation().getNodeOffset()) { + bestNode = m; + nearest = m.getExpansionLocation().getNodeOffset(); + } + } + } + return bestNode; + } + /** * Locates the {@link IASTDeclaration} most immediately following the specified offset * @param unit the translation unit, or null (in which case the result will also be null) @@ -250,48 +405,11 @@ public class DefaultMultilineCommentAutoEditStrategy implements IAutoEditStrateg * is no {@link IASTDeclaration} */ public static IASTDeclaration findFollowingDeclaration(IASTTranslationUnit unit, final int offset) { - final IASTDeclaration[] dec = new IASTDeclaration[1]; - final ASTVisitor av = new ASTVisitor() { - { - shouldVisitTranslationUnit = true; - shouldVisitDeclarations = true; - } - - /** - * Holds the - */ - IASTDeclaration stopWhenLeaving; - - @Override - public int visit(IASTDeclaration declaration) { - IASTNodeLocation loc = declaration.getFileLocation(); - if (loc != null) { - int candidateOffset = loc.getNodeOffset(); - int candidateEndOffset = candidateOffset + loc.getNodeLength(); - - if (offset <= candidateOffset) { - dec[0] = declaration; - return PROCESS_ABORT; - } - - boolean candidateEnclosesOffset = (offset >= candidateOffset) && (offset < candidateEndOffset); - if (candidateEnclosesOffset) { - stopWhenLeaving = declaration; - } - } - return PROCESS_CONTINUE; - } - - @Override - public int leave(IASTDeclaration declaration) { - if (declaration == stopWhenLeaving) - return PROCESS_ABORT; - return PROCESS_CONTINUE; - } - }; - + IASTDeclaration[] dec = new IASTDeclaration[1]; if (unit != null) { + SearchVisitor av = new SearchVisitor(offset); unit.accept(av); + dec[0] = av.getTarget(); } return dec[0]; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenMultilineAutoEditStrategy.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenMultilineAutoEditStrategy.java index 2f978ad1a3c..f99986be07f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenMultilineAutoEditStrategy.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenMultilineAutoEditStrategy.java @@ -26,15 +26,27 @@ import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId; import org.eclipse.cdt.core.parser.IToken; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; +import org.eclipse.cdt.internal.core.model.ASTStringUtil; import org.eclipse.cdt.ui.text.doctools.DefaultMultilineCommentAutoEditStrategy; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IAutoEditStrategy; @@ -49,19 +61,40 @@ import org.eclipse.jface.text.TextUtilities; * @since 5.0 * @noextend This class is not intended to be subclassed by clients. */ -public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAutoEditStrategy { +public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAutoEditStrategy + implements DefaultMultilineCommentAutoEditStrategy.IDocCustomizer { private static final String SINGLELINE_COMMENT_PRECEDING = "//!< "; //$NON-NLS-1$ - private static final String PARAM = "@param "; //$NON-NLS-1$ - private static final String RETURN = "@return"; //$NON-NLS-1$ + private static final String CLASS = "class "; //$NON-NLS-1$ + private static final String ENUM = "enum "; //$NON-NLS-1$ + private static final String THROW = "throw "; //$NON-NLS-1$ + private static final String STRUCT = "struct "; //$NON-NLS-1$ + private static final String UNION = "union "; //$NON-NLS-1$ + private static final String BRIEF = "brief "; //$NON-NLS-1$ + private static final String PARAM = "param "; //$NON-NLS-1$ + private static final String FUNC = "fn "; //$NON-NLS-1$ + private static final String TPARAM = "tparam "; //$NON-NLS-1$ + private static final String RETURN = "return"; //$NON-NLS-1$ + private static final String DEF = "def "; //$NON-NLS-1$ + private static final String NAMESPACE = "namespace "; //$NON-NLS-1$ + private static final String PREFIX_JAVADOC = "@"; //$NON-NLS-1$ + private static final String PREFIX_NO_JAVADOC = "\\"; //$NON-NLS-1$ protected boolean documentPureVirtuals = true; protected boolean documentDeclarations = true; + private boolean javadocStyle = true; + private boolean useStructuralCommands = false; + private boolean useBriefTag = false; + private String fLineDelimiter; public DoxygenMultilineAutoEditStrategy() { } + private String getPrefix() { + return javadocStyle ? PREFIX_JAVADOC : PREFIX_NO_JAVADOC; + } + /** * @since 6.6 */ @@ -73,12 +106,62 @@ public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAut /** * @param decl the function declarator to document * @param ds the function specifier to document + * @param templateParams Template parameters for the function * @return content describing the specified function + * @since 6.7 */ - protected StringBuilder documentFunction(IASTFunctionDeclarator decl, IASTDeclSpecifier ds) { + protected StringBuilder documentComposite(IASTCompositeTypeSpecifier decl, + ICPPASTTemplateParameter[] templateParams) { + StringBuilder result = new StringBuilder(); + if (useStructuralCommands) { + switch (decl.getKey()) { + case ICPPASTCompositeTypeSpecifier.k_class: + result.append(getPrefix()).append(CLASS).append(decl.getName().getSimpleID()) + .append(getLineDelimiter()); + break; + case IASTCompositeTypeSpecifier.k_struct: + result.append(getPrefix()).append(STRUCT).append(decl.getName().getSimpleID()) + .append(getLineDelimiter()); + break; + case IASTCompositeTypeSpecifier.k_union: + result.append(getPrefix()).append(UNION).append(decl.getName().getSimpleID()) + .append(getLineDelimiter()); + break; + } + } + if (useBriefTag) + result.append(getPrefix()).append(BRIEF).append(getLineDelimiter()).append(getLineDelimiter()) + .append(getLineDelimiter()).append(documentTemplateParameters(templateParams)); + return result; + } + + /** + * Document a function/method + * @param decl the function declarator to document + * @param ds the function specifier to document + * @param templateParams Template parameters for the function + * @return content describing the specified function + * @since 6.7 + */ + protected StringBuilder documentFunction(IASTFunctionDeclarator decl, IASTDeclSpecifier ds, + ICPPASTTemplateParameter[] templateParams) { StringBuilder result = new StringBuilder(); + if (useStructuralCommands) { + result.append(getPrefix()).append(FUNC).append(ASTStringUtil.getSignatureString(ds, decl)) + .append(getLineDelimiter()); + } + if (useBriefTag) { + result.append(getPrefix()).append(BRIEF).append(getLineDelimiter()).append(getLineDelimiter()) + .append(getLineDelimiter()).append(documentTemplateParameters(templateParams)); + } + + result.append(documentTemplateParameters(templateParams)); result.append(documentFunctionParameters(getParameterDecls(decl))); + if (decl instanceof ICPPASTFunctionDeclarator) { + ICPPASTFunctionDeclarator cppDecl = (ICPPASTFunctionDeclarator) decl; + result.append(documentExceptions(cppDecl.getExceptionSpecification(), cppDecl.getNoexceptExpression())); + } boolean hasReturn = true; if (ds instanceof IASTSimpleDeclSpecifier) { @@ -95,6 +178,23 @@ public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAut return result; } + /** + * Document template parameters + * @param templateParams The list of template parameters + * @return The built string + * @since 6.7 + */ + protected StringBuilder documentTemplateParameters(ICPPASTTemplateParameter[] templateParams) { + StringBuilder result = new StringBuilder(); + if (templateParams == null || templateParams.length == 0) + return result; + for (ICPPASTTemplateParameter t : templateParams) { + IASTName name = CPPTemplates.getTemplateParameterName(t); + result.append(getPrefix()).append(TPARAM).append(new String(name.getSimpleID())).append(getLineDelimiter()); + } + return result; + } + /** * Returns the comment content to add to the documentation comment. * @param decls The parameter declarations to describe @@ -105,7 +205,7 @@ public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAut StringBuilder result = new StringBuilder(); for (int i = 0; i < decls.length; i++) { if (!isVoidParameter(decls[i])) { - result.append(PARAM).append(getParameterName(decls[i])).append(getLineDelimiter()); + result.append(getPrefix()).append(PARAM).append(getParameterName(decls[i])).append(getLineDelimiter()); } } return result; @@ -156,7 +256,7 @@ public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAut * @return the comment content to describe the return */ protected StringBuilder documentFunctionReturn() { - return new StringBuilder(RETURN).append(getLineDelimiter()); + return new StringBuilder(getPrefix()).append(RETURN).append(getLineDelimiter()); } /** @@ -177,16 +277,14 @@ public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAut return result; } - /* - * @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) + /** + * @since 6.7 */ @Override - protected StringBuilder customizeAfterNewLineForDeclaration(IDocument doc, IASTDeclaration dec, - ITypedRegion partition) { + public StringBuilder customizeForDeclaration(IDocument doc, IASTNode declToDocument, ITypedRegion partition, + CustomizeOptions options) { fLineDelimiter = TextUtilities.getDefaultLineDelimiter(doc); - IASTDeclaration declToDocument = dec; - if (declToDocument instanceof ICPPASTLinkageSpecification) { ICPPASTLinkageSpecification linkageSpecification = (ICPPASTLinkageSpecification) declToDocument; IASTDeclaration[] declarations = linkageSpecification.getDeclarations(); @@ -214,20 +312,35 @@ public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAut } } + if (options != null && (useBriefTag || useStructuralCommands)) + options.addNewLine = false; + + ICPPASTTemplateParameter[] params = null; + if (declToDocument instanceof ICPPASTTemplateDeclaration) { + params = ((ICPPASTTemplateDeclaration) declToDocument).getTemplateParameters(); + } + while (declToDocument instanceof ICPPASTTemplateDeclaration) /* if? */ declToDocument = ((ICPPASTTemplateDeclaration) declToDocument).getDeclaration(); if (declToDocument instanceof IASTFunctionDefinition) { IASTFunctionDefinition fd = (IASTFunctionDefinition) declToDocument; - return documentFunction(fd.getDeclarator(), fd.getDeclSpecifier()); + return documentFunction(fd.getDeclarator(), fd.getDeclSpecifier(), params); + } + + if (declToDocument instanceof IASTPreprocessorMacroDefinition) { + return documentDefine((IASTPreprocessorMacroDefinition) declToDocument); + } + + if (declToDocument instanceof ICPPASTNamespaceDefinition) { + return documentNamespace((ICPPASTNamespaceDefinition) declToDocument); } if (declToDocument instanceof IASTSimpleDeclaration) { IASTSimpleDeclaration sdec = (IASTSimpleDeclaration) declToDocument; - StringBuilder result = new StringBuilder(); if (sdec.getDeclSpecifier() instanceof IASTCompositeTypeSpecifier) { - return result; + return documentComposite((IASTCompositeTypeSpecifier) sdec.getDeclSpecifier(), params); } else { IASTDeclarator[] dcs = sdec.getDeclarators(); if (dcs.length == 1 && dcs[0] instanceof IASTFunctionDeclarator) { @@ -239,25 +352,120 @@ public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAut } if (shouldDocument) { - return documentFunction(fdecl, sdec.getDeclSpecifier()); + return documentFunction(fdecl, sdec.getDeclSpecifier(), params); } } } } + StringBuilder builder = new StringBuilder(); + if (declToDocument instanceof IASTSimpleDeclaration + && ((IASTSimpleDeclaration) declToDocument).getDeclSpecifier() instanceof IASTEnumerationSpecifier) { + builder = documentEnum( + (IASTEnumerationSpecifier) ((IASTSimpleDeclaration) declToDocument).getDeclSpecifier()); + } + try { alterDoc(doc, declToDocument); } catch (BadLocationException ble) { /*ignore*/ } - return new StringBuilder(); + return builder; + } + + /** + * Document preprocessor defines + * @param Macro definition + * @return The built buffer + * @since 6.7 + */ + protected StringBuilder documentDefine(IASTPreprocessorMacroDefinition dec) { + StringBuilder result = new StringBuilder(); + if (useStructuralCommands) + result.append(getPrefix()).append(DEF).append(new String(dec.getName().getSimpleID())) + .append(getLineDelimiter()); + if (useBriefTag) + result.append(getPrefix()).append(BRIEF).append(getLineDelimiter()).append(getLineDelimiter()) + .append(getLineDelimiter()); + return result; + } + + /** + * Document namespaces + * @param dec Namespace definition + * @return The built buffer + * @since 6.7 + */ + protected StringBuilder documentNamespace(ICPPASTNamespaceDefinition dec) { + StringBuilder result = new StringBuilder(); + if (useStructuralCommands) + result.append(getPrefix()).append(NAMESPACE).append(new String(dec.getName().getSimpleID())) + .append(getLineDelimiter()); + if (useBriefTag) + result.append(getPrefix()).append(BRIEF).append(getLineDelimiter()).append(getLineDelimiter()) + .append(getLineDelimiter()); + return result; + } + + /** + * Document enums + * @param dec Enumeration specifier + * @return The built buffer + * @since 6.7 + */ + protected StringBuilder documentEnum(IASTEnumerationSpecifier dec) { + StringBuilder result = new StringBuilder(); + if (useStructuralCommands) + result.append(getPrefix()).append(ENUM).append(new String(dec.getName().getSimpleID())) + .append(getLineDelimiter()); + if (useBriefTag) + result.append(getPrefix()).append(BRIEF).append(getLineDelimiter()).append(getLineDelimiter()) + .append(getLineDelimiter()); + return result; + } + + /** + * Document function exceptions + * @param exceptions A list of exceptions or NO_EXCEPTION_SPECIFICATION if no exceptions are present + * or EMPTY_TYPEID_ARRAY if no exceptions will be thrown. + * @param noexcept Noexcept expression, null if no present, NOEXCEPT_DEFAULT if noexcept has been used + * @return The built string + * @since 6.7 + */ + protected StringBuilder documentExceptions(IASTTypeId[] exceptions, ICPPASTExpression noexcept) { + StringBuilder result = new StringBuilder(); + if (exceptions == ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION + || exceptions == IASTTypeId.EMPTY_TYPEID_ARRAY) { + if (noexcept != null && noexcept != ICPPASTFunctionDeclarator.NOEXCEPT_DEFAULT + && !isNoexceptTrue(noexcept)) { + result.append(getPrefix()).append(THROW).append(getLineDelimiter()); + } + } else { + for (int i = 0; i < exceptions.length; i++) { + result.append(getPrefix()).append(THROW); + if (exceptions[i] instanceof ICPPASTTypeId && ((ICPPASTTypeId) exceptions[i]).isPackExpansion()) { + result.append(getLineDelimiter()); + continue; + } + result.append(ASTStringUtil.getSignatureString(exceptions[i].getAbstractDeclarator())) + .append(getLineDelimiter()); + } + } + return result; + } + + private boolean isNoexceptTrue(ICPPASTExpression expr) { + if (expr instanceof IASTLiteralExpression) { + return ((IASTLiteralExpression) expr).getKind() == IASTLiteralExpression.lk_true; + } + return false; } /* * Add post-declaration comments to enumerators, after initializing a doc-comment on an enumeration */ - private void alterDoc(IDocument doc, IASTDeclaration dec) throws BadLocationException { + private void alterDoc(IDocument doc, IASTNode dec) throws BadLocationException { if (dec instanceof IASTSimpleDeclaration && ((IASTSimpleDeclaration) dec).getDeclSpecifier() instanceof IASTEnumerationSpecifier) { IASTEnumerationSpecifier spc = (IASTEnumerationSpecifier) ((IASTSimpleDeclaration) dec).getDeclSpecifier(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenSingleAutoEditStrategy.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenSingleAutoEditStrategy.java index 7bc93be9459..35f2e521c37 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenSingleAutoEditStrategy.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenSingleAutoEditStrategy.java @@ -152,16 +152,16 @@ public class DoxygenSingleAutoEditStrategy extends DoxygenMultilineAutoEditStrat } private StringBuilder getDeclarationLines(IDocument doc, int offset) throws BadLocationException { - IASTDeclaration dec = null; + IASTNode dec = null; IASTTranslationUnit ast = getAST(); if (ast != null) { - dec = findFollowingDeclaration(ast, offset); + dec = findNextDocumentNode(ast, offset); if (dec == null) { IASTNodeSelector ans = ast.getNodeSelector(ast.getFilePath()); IASTNode node = ans.findEnclosingNode(offset, 0); if (node instanceof IASTDeclaration) { - dec = (IASTDeclaration) node; + dec = node; } } } @@ -169,7 +169,7 @@ public class DoxygenSingleAutoEditStrategy extends DoxygenMultilineAutoEditStrat if (dec != null) { ITypedRegion partition = TextUtilities.getPartition(doc, ICPartitions.C_PARTITIONING /* this! */, offset, false); - return customizeAfterNewLineForDeclaration(doc, dec, partition); + return customizeForDeclaration(doc, dec, partition, null); } return null; }