From 9c8190dd9c7c9f9152cf6d2b17f2feffc879c601 Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Wed, 5 Aug 2026 16:41:43 -0400 Subject: [PATCH] Fix adding old-style javadocs when markdown comments are defaulted - fix JavaDocAutoIndentStrategy to keep track of when an old javadoc comment is created in indentAfterNewline() and pass this info along when creating tags including to CodeGeneration methods so that the choice of using markdown templates is not based on the use markdown preference and is overridden - add new APIs to CodeGeneration and StubUtility to take added boolean - bump up o.e.jdt.core.manipulation minor version - fixes #3100 to --- .../META-INF/MANIFEST.MF | 2 +- .../jdt/core/manipulation/CodeGeneration.java | 55 ++++++++++++++++++- .../core/manipulation/StubUtility.java | 29 +++++++++- .../javadoc/JavaDocAutoIndentStrategy.java | 30 ++++++---- 4 files changed, 101 insertions(+), 15 deletions(-) diff --git a/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF index ec10aa3c980..10332e7da1b 100644 --- a/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Automatic-Module-Name: org.eclipse.jdt.core.manipulation Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.core.manipulation; singleton:=true -Bundle-Version: 1.24.200.qualifier +Bundle-Version: 1.25.0.qualifier Bundle-Vendor: %providerName Bundle-Activator: org.eclipse.jdt.internal.core.manipulation.JavaManipulationPlugin Bundle-Localization: plugin diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/CodeGeneration.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/CodeGeneration.java index 6190c767f85..3b1a50f7d0d 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/CodeGeneration.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/CodeGeneration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2026 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -152,6 +152,21 @@ public static String getTypeComment(ICompilationUnit cu, String typeQualifiedNam return StubUtility.getTypeComment(cu, typeQualifiedName, typeParameterNames, EMPTY, lineDelimiter); } + /** + * Returns the content for a new type comment using the 'type comment' code template. The returned content is unformatted and is not indented. + * @param cu The compilation unit where the type is contained. The compilation unit does not need to exist. + * @param typeQualifiedName The name of the type to which the comment is added. For inner types the name must be qualified and include the outer + * types names (dot separated). See {@link org.eclipse.jdt.core.IType#getTypeQualifiedName(char)}. + * @param typeParameterNames The type parameter names + * @param lineDelimiter The line delimiter to be used. + * @return Returns the new content or null if the code template is undefined or empty. The returned content is unformatted and is not indented. + * @throws CoreException Thrown when the evaluation of the code template fails. + * @since 1.25 + */ + public static String getTypeComment(ICompilationUnit cu, String typeQualifiedName, String[] typeParameterNames, String lineDelimiter, boolean useMarkdown) throws CoreException { + return StubUtility.getTypeComment(cu, typeQualifiedName, typeParameterNames, EMPTY, lineDelimiter, useMarkdown); + } + /** * Returns the content for a new type comment using the 'type comment' code template. The returned content is unformatted and is not indented. * @param cu The compilation unit where the type is contained. The compilation unit does not need to exist. @@ -301,6 +316,30 @@ public static String getMethodComment(IMethod method, IMethod overridden, String method.getElementName(), paramNames, method.getExceptionTypes(), retType, typeParameterNames, overridden, false, lineDelimiter); } + /** + * Returns the comment for a method or constructor using the comment code templates (constructor / method / overriding method). + * null is returned if the template is empty. + *

The returned string is unformatted and not indented. + * + * @param method The method to be documented. The method must exist. + * @param overridden The method that will be overridden by the created method or + * null for non-overriding methods. If not null, the method must exist. + * @param lineDelimiter The line delimiter to be used. + * @param useMarkdown True if markdown templates should be used, false if regular javadoc templates + * @return Returns the constructed comment or null if + * the comment code template is empty. The returned string is unformatted and and has no indent (formatting required). + * @throws CoreException Thrown when the evaluation of the code template fails. + * @since 1.25 + */ + public static String getMethodComment(IMethod method, IMethod overridden, String lineDelimiter, boolean useMarkdown) throws CoreException { + String retType= method.isConstructor() ? null : method.getReturnType(); + String[] paramNames= method.getParameterNames(); + String[] typeParameterNames= StubUtility.getTypeParameterNames(method.getTypeParameters()); + + return StubUtility.getMethodComment(method.getCompilationUnit(), method.getDeclaringType().getElementName(), + method.getElementName(), paramNames, method.getExceptionTypes(), retType, typeParameterNames, overridden, false, lineDelimiter, useMarkdown); + } + /** * Returns the comment for a method or constructor using the comment code templates (constructor / method / overriding method). * null is returned if the template is empty. @@ -360,6 +399,20 @@ public static String getModuleComment(ICompilationUnit cu, IModuleDescription de return StubUtility.getModuleComment(cu, desc.getElementName(), desc.getProvidedServiceNames(), desc.getUsedServiceNames(), lineDelimiter); } + /** + * Returns the comment for a module based on code templates + * + * @param cu The compilation unit for the module + * @param desc The module description + * @param lineDelimiter The line delimiter to use + * @return Module comment + * @throws CoreException Thrown when the evaluation of the code template fails + * @since 1.25 + */ + public static String getModuleComment(ICompilationUnit cu, IModuleDescription desc, String lineDelimiter, boolean useMarkdown) throws CoreException { + return StubUtility.getModuleComment(cu, desc.getElementName(), desc.getProvidedServiceNames(), desc.getUsedServiceNames(), lineDelimiter, useMarkdown); + } + /** * Returns the content of the body for a method or constructor using the method body templates. * null is returned if the template is empty. diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/core/manipulation/StubUtility.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/core/manipulation/StubUtility.java index 19bb56dd895..e5d3d1ce1fa 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/core/manipulation/StubUtility.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/core/manipulation/StubUtility.java @@ -288,10 +288,19 @@ public static String getFileComment(ICompilationUnit cu, String lineDelimiter) t /* * Don't use this method directly, use CodeGeneration. - * @see CodeGeneration#getTypeComment(ICompilationUnit, String, String[], String) + * @see CodeGeneration#getTypeComment(ICompilationUnit, String, String[], String, boolean) */ public static String getTypeComment(ICompilationUnit cu, String typeQualifiedName, String[] typeParameterNames, String[] params, String lineDelim) throws CoreException { boolean useMarkdown= useMarkdown(cu.getJavaProject()); + return getTypeComment(cu, typeQualifiedName, typeParameterNames, params, lineDelim, useMarkdown); + } + + /* + * Don't use this method directly, use CodeGeneration. + * @see CodeGeneration#getTypeComment(ICompilationUnit, String, String[], String) + */ + public static String getTypeComment(ICompilationUnit cu, String typeQualifiedName, String[] typeParameterNames, String[] params, + String lineDelim, boolean useMarkdown) throws CoreException { Template template= getCodeTemplate(useMarkdown ? CodeTemplateContextType.MARKDOWNTYPECOMMENT_ID : CodeTemplateContextType.TYPECOMMENT_ID, cu.getJavaProject()); if (template == null) { return null; @@ -442,6 +451,15 @@ public static String getTypeBody(String templateID, ICompilationUnit cu, String public static String getMethodComment(ICompilationUnit cu, String typeName, String methodName, String[] paramNames, String[] excTypeSig, String retTypeSig, String[] typeParameterNames, IMethod target, boolean delegate, String lineDelimiter) throws CoreException { boolean useMarkdown= useMarkdown(cu.getJavaProject()); + return getMethodComment(cu, typeName, methodName, paramNames, excTypeSig, retTypeSig, typeParameterNames, target, delegate, lineDelimiter, useMarkdown); + } + + /* + * Don't use this method directly, use CodeGeneration. + * @see CodeGeneration#getMethodComment(ICompilationUnit, String, String, String[], String[], String, String[], IMethod, String) + */ + public static String getMethodComment(ICompilationUnit cu, String typeName, String methodName, String[] paramNames, String[] excTypeSig, String retTypeSig, String[] typeParameterNames, + IMethod target, boolean delegate, String lineDelimiter, boolean useMarkdown) throws CoreException { String templateName= useMarkdown ? CodeTemplateContextType.MARKDOWNMETHODCOMMENT_ID : CodeTemplateContextType.METHODCOMMENT_ID; if (retTypeSig == null) { templateName= useMarkdown ? CodeTemplateContextType.MARKDOWNCONSTRUCTORCOMMENT_ID : CodeTemplateContextType.CONSTRUCTORCOMMENT_ID; @@ -540,6 +558,15 @@ private static String fixEmptyVariables(TemplateBuffer buffer, String[] variable public static String getModuleComment(ICompilationUnit cu, String moduleName, String[] providesNames, String[] usesNames, String lineDelimiter) throws CoreException { boolean useMarkdown= useMarkdown(cu.getJavaProject()); + return getModuleComment(cu, moduleName, providesNames, usesNames, lineDelimiter, useMarkdown); + } + + /* + * Don't use this method directly, use CodeGeneration. + * @see CodeGeneration#getModuleComment(IJavaProject, String, String, String[], String[], String[], String[], String[], String) + */ + public static String getModuleComment(ICompilationUnit cu, String moduleName, String[] providesNames, + String[] usesNames, String lineDelimiter, boolean useMarkdown) throws CoreException { String templateName= useMarkdown ? CodeTemplateContextType.MARKDOWNMODULECOMMENT_ID : CodeTemplateContextType.MODULECOMMENT_ID; Template template= getCodeTemplate(templateName, cu.getJavaProject()); if (template == null) { diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/javadoc/JavaDocAutoIndentStrategy.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/javadoc/JavaDocAutoIndentStrategy.java index 278645c2a22..bfaae18e861 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/javadoc/JavaDocAutoIndentStrategy.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/javadoc/JavaDocAutoIndentStrategy.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2025 IBM Corporation and others. + * Copyright (c) 2000, 2026 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -103,10 +103,12 @@ private void indentAfterNewLine(IDocument d, DocumentCommand c) { buf.append(indentation.substring(0, lengthToAdd)); if (firstNonWS < offset) { + boolean useMarkdown= false; if (d.getChar(firstNonWS) == '/') { // Javadoc/markdown started on this line if (d.getChar(firstNonWS+1) == '/') { buf.append("/// "); //$NON-NLS-1$ + useMarkdown= true; if (handleMarkdownCodeFence(d, c, lineOffset, offset, indentation, buf)) return; } else { @@ -134,7 +136,7 @@ private void indentAfterNewLine(IDocument d, DocumentCommand c) { if (unit != null) { try { JavaModelUtil.reconcile(unit); - String string= createJavaDocTags(d, c, indentation, lineDelimiter, unit); + String string= createJavaDocTags(d, c, indentation, lineDelimiter, unit, useMarkdown); buf.append(restOfLine); // only add tags if they are non-empty - the empty line has already been added above. if (string != null && !"*".equals(string.trim())) //$NON-NLS-1$ @@ -251,7 +253,8 @@ private IRegion findPrefixRange(IDocument document, IRegion line) throws BadLoca * @throws CoreException if accessing the Java model fails * @throws BadLocationException if accessing the document fails */ - private String createJavaDocTags(IDocument document, DocumentCommand command, String indentation, String lineDelimiter, ICompilationUnit unit) + private String createJavaDocTags(IDocument document, DocumentCommand command, String indentation, + String lineDelimiter, ICompilationUnit unit, boolean useMarkdown) throws CoreException, BadLocationException { IJavaElement element= unit.getElementAt(command.offset); @@ -260,13 +263,13 @@ private String createJavaDocTags(IDocument document, DocumentCommand command, St switch (element.getElementType()) { case IJavaElement.TYPE: - return createTypeTags(document, command, indentation, lineDelimiter, (IType) element); + return createTypeTags(document, command, indentation, lineDelimiter, (IType) element, useMarkdown); case IJavaElement.METHOD: - return createMethodTags(document, command, indentation, lineDelimiter, (IMethod) element); + return createMethodTags(document, command, indentation, lineDelimiter, (IMethod) element, useMarkdown); case IJavaElement.JAVA_MODULE: - return createModuleTags(document, command, indentation, lineDelimiter, (IModuleDescription) element); + return createModuleTags(document, command, indentation, lineDelimiter, (IModuleDescription) element, useMarkdown); default: return null; @@ -305,11 +308,12 @@ private String prepareTemplateComment(String comment, String indentation, IJavaP return Strings.changeIndent(comment, 0, project, indentation, lineDelimiter); } - private String createTypeTags(IDocument document, DocumentCommand command, String indentation, String lineDelimiter, IType type) + private String createTypeTags(IDocument document, DocumentCommand command, String indentation, + String lineDelimiter, IType type, boolean useMarkdown) throws CoreException, BadLocationException { String[] typeParamNames= StubUtility.getTypeParameterNames(type.getTypeParameters()); - String comment= CodeGeneration.getTypeComment(type.getCompilationUnit(), type.getTypeQualifiedName('.'), typeParamNames, lineDelimiter); + String comment= CodeGeneration.getTypeComment(type.getCompilationUnit(), type.getTypeQualifiedName('.'), typeParamNames, lineDelimiter, useMarkdown); if (comment != null) { boolean javadocComment= comment.startsWith("/**"); //$NON-NLS-1$ if (!isFirstComment(document, command, type, javadocComment)) @@ -319,10 +323,11 @@ private String createTypeTags(IDocument document, DocumentCommand command, Strin return null; } - private String createModuleTags(IDocument document, DocumentCommand command, String indentation, String lineDelimiter, IModuleDescription module) + private String createModuleTags(IDocument document, DocumentCommand command, String indentation, + String lineDelimiter, IModuleDescription module, boolean useMarkdown) throws CoreException, BadLocationException { - String comment= CodeGeneration.getModuleComment(module.getCompilationUnit(), module, lineDelimiter); + String comment= CodeGeneration.getModuleComment(module.getCompilationUnit(), module, lineDelimiter, useMarkdown); if (comment != null) { boolean javadocComment= comment.startsWith("/**"); //$NON-NLS-1$ if (!isFirstComment(document, command, module, javadocComment)) @@ -332,12 +337,13 @@ private String createModuleTags(IDocument document, DocumentCommand command, Str return null; } - private String createMethodTags(IDocument document, DocumentCommand command, String indentation, String lineDelimiter, IMethod method) + private String createMethodTags(IDocument document, DocumentCommand command, String indentation, + String lineDelimiter, IMethod method, boolean useMarkdown) throws CoreException, BadLocationException { IRegion partition= TextUtilities.getPartition(document, fPartitioning, command.offset, false); IMethod inheritedMethod= getInheritedMethod(method); - String comment= CodeGeneration.getMethodComment(method, inheritedMethod, lineDelimiter); + String comment= CodeGeneration.getMethodComment(method, inheritedMethod, lineDelimiter, useMarkdown); if (comment != null) { comment= comment.trim(); boolean javadocComment= comment.startsWith("/**"); //$NON-NLS-1$