You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2022/07/19 22:30:21 UTC
[groovy] 02/02: GROOVY-10689: Groovydoc for Groovy 3+ documents classes at too early a phase of compilation
This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 4e81b60eaff3600e7d4be845de0673796eb6d98c
Author: Paul King <pa...@asert.com.au>
AuthorDate: Tue Jul 19 13:51:10 2022 +1000
GROOVY-10689: Groovydoc for Groovy 3+ documents classes at too early a phase of compilation
---
.../org/codehaus/groovy/ast/AnnotationNode.java | 14 +-
.../transform/PackageScopeASTTransformation.java | 1 +
.../java/org/codehaus/groovy/ant/Groovydoc.java | 3 +
.../codehaus/groovy/tools/groovydoc/Main.groovy | 4 +
.../org/apache/groovy/antlr/GroovydocVisitor.java | 23 ++-
.../org/codehaus/groovy/groovydoc/GroovyDoc.java | 2 +
.../tools/groovydoc/ArrayClassDocWrapper.java | 5 +
.../tools/groovydoc/ExternalGroovyClassDoc.java | 5 +
.../tools/groovydoc/GroovyRootDocBuilder.java | 2 +-
.../tools/groovydoc/SimpleGroovyAnnotationRef.java | 10 +-
.../groovy/tools/groovydoc/SimpleGroovyDoc.java | 9 ++
.../tools/groovydoc/antlr4/GroovyDocParser.java | 23 ++-
.../gstringTemplates/classLevel/classDocName.html | 10 +-
.../groovy/tools/groovydoc/GroovyDocToolTest.java | 174 +++++++++++----------
.../groovydoc/testfiles/generics/Groovy.groovy | 17 +-
.../tools/groovydoc/testfiles/generics/Java.java | 18 ++-
16 files changed, 212 insertions(+), 108 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/ast/AnnotationNode.java b/src/main/java/org/codehaus/groovy/ast/AnnotationNode.java
index 5a32327eef..f91724e94c 100644
--- a/src/main/java/org/codehaus/groovy/ast/AnnotationNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/AnnotationNode.java
@@ -19,11 +19,15 @@
package org.codehaus.groovy.ast;
import org.codehaus.groovy.GroovyBugError;
+import org.codehaus.groovy.ast.expr.AnnotationConstantExpression;
import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.ListExpression;
import java.util.Collections;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
import static java.util.Objects.requireNonNull;
@@ -213,7 +217,15 @@ public class AnnotationNode extends ASTNode {
} else {
memberText.append(", ");
}
- memberText.append(next.getKey()).append(": ").append(next.getValue().getText());
+ Expression value = next.getValue();
+ String text;
+ if (value instanceof ListExpression) {
+ List result = ((ListExpression) value).getExpressions().stream().map(exp -> { return exp instanceof AnnotationConstantExpression ? ((ASTNode)((AnnotationConstantExpression)exp).getValue()).getText() : exp.getText(); }).collect(Collectors.toList());
+ text = result.toString();
+ } else {
+ text = value.getText();
+ }
+ memberText.append(next.getKey()).append(": ").append(text);
}
}
return "@" + classNode.getText() + "(" + memberText + ")";
diff --git a/src/main/java/org/codehaus/groovy/transform/PackageScopeASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/PackageScopeASTTransformation.java
index 22ac1a3360..1ee3487ac9 100644
--- a/src/main/java/org/codehaus/groovy/transform/PackageScopeASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/PackageScopeASTTransformation.java
@@ -175,6 +175,7 @@ public class PackageScopeASTTransformation extends AbstractASTTransformation {
private static void revertVisibility(FieldNode fNode) {
fNode.setModifiers(fNode.getModifiers() & ~ACC_PRIVATE);
+ fNode.setSynthetic(false);
}
private static void revertVisibility(MethodNode mNode) {
diff --git a/subprojects/groovy-ant/src/main/java/org/codehaus/groovy/ant/Groovydoc.java b/subprojects/groovy-ant/src/main/java/org/codehaus/groovy/ant/Groovydoc.java
index 98d2fd6046..d9813922cd 100644
--- a/subprojects/groovy-ant/src/main/java/org/codehaus/groovy/ant/Groovydoc.java
+++ b/subprojects/groovy-ant/src/main/java/org/codehaus/groovy/ant/Groovydoc.java
@@ -18,6 +18,7 @@
*/
package org.codehaus.groovy.ant;
+import org.apache.groovy.util.SystemUtil;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Task;
@@ -450,6 +451,8 @@ public class Groovydoc extends Task {
properties.setProperty("fileEncoding", fileEncoding != null ? fileEncoding : "");
properties.setProperty("timestamp", Boolean.valueOf(!noTimestamp).toString());
properties.setProperty("versionStamp", Boolean.valueOf(!noVersionStamp).toString());
+ String phaseOverride = SystemUtil.getSystemPropertySafe("groovydoc.phase.override");
+ if (phaseOverride != null) properties.put("phaseOverride", phaseOverride);
if (sourcePath != null) {
sourceDirs.addExisting(sourcePath);
diff --git a/subprojects/groovy-groovydoc/src/main/groovy/org/codehaus/groovy/tools/groovydoc/Main.groovy b/subprojects/groovy-groovydoc/src/main/groovy/org/codehaus/groovy/tools/groovydoc/Main.groovy
index 5a5bcb88bc..d0079b1a99 100644
--- a/subprojects/groovy-groovydoc/src/main/groovy/org/codehaus/groovy/tools/groovydoc/Main.groovy
+++ b/subprojects/groovy-groovydoc/src/main/groovy/org/codehaus/groovy/tools/groovydoc/Main.groovy
@@ -20,6 +20,7 @@ package org.codehaus.groovy.tools.groovydoc
import groovy.cli.internal.CliBuilderInternal
import groovy.io.FileType
+import org.apache.groovy.util.SystemUtil
import org.codehaus.groovy.tools.groovydoc.gstringTemplates.GroovyDocTemplateInfo
import org.codehaus.groovy.tools.shell.IO
import org.codehaus.groovy.tools.shell.util.Logger
@@ -200,6 +201,9 @@ class Main {
properties.put("timestamp", (!noTimestamp).toString())
properties.put("versionStamp", (!noVersionStamp).toString())
properties.put("overviewFile", overviewFile?.absolutePath ?: "")
+ String phaseOverride = SystemUtil.getSystemPropertySafe("groovydoc.phase.override")
+ if (phaseOverride) properties.put("phaseOverride", phaseOverride)
+
def links = new ArrayList<LinkArgument>();
collectSourceFileNames(remainingArgs, sourcepath, exclusions)
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/apache/groovy/antlr/GroovydocVisitor.java b/subprojects/groovy-groovydoc/src/main/java/org/apache/groovy/antlr/GroovydocVisitor.java
index 02adcdb3b5..f5f0882064 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/apache/groovy/antlr/GroovydocVisitor.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/apache/groovy/antlr/GroovydocVisitor.java
@@ -36,6 +36,7 @@ import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.control.ResolveVisitor;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.groovydoc.GroovyClassDoc;
+import org.codehaus.groovy.groovydoc.GroovyFieldDoc;
import org.codehaus.groovy.groovydoc.GroovyMethodDoc;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import org.codehaus.groovy.tools.groovydoc.LinkArgument;
@@ -116,6 +117,8 @@ public class GroovydocVisitor extends ClassCodeVisitorSupport {
currentClassDoc = new SimpleGroovyClassDoc(withDefaultImports(imports), aliases, name, links);
if (node.isEnum()) {
currentClassDoc.setTokenType(SimpleGroovyDoc.ENUM_DEF);
+ } else if (node.isRecord()) {
+ currentClassDoc.setTokenType(SimpleGroovyDoc.RECORD_DEF);
} else if (node.isAnnotationDefinition()) {
currentClassDoc.setTokenType(SimpleGroovyDoc.ANNOTATION_DEF);
} else if (isTrait(node)) {
@@ -203,6 +206,7 @@ public class GroovydocVisitor extends ClassCodeVisitorSupport {
@Override
public void visitConstructor(ConstructorNode node) {
+ if (node.isSynthetic()) return;
SimpleGroovyConstructorDoc cons = new SimpleGroovyConstructorDoc(currentClassDoc.simpleTypeName(), currentClassDoc);
setConstructorOrMethodCommon(node, cons);
currentClassDoc.add(cons);
@@ -213,6 +217,7 @@ public class GroovydocVisitor extends ClassCodeVisitorSupport {
public void visitMethod(MethodNode node) {
if (currentClassDoc.isEnum() && "$INIT".equals(node.getName()))
return;
+ if (node.isSynthetic()) return;
if ("false".equals(properties.getProperty("includeMainForScripts", "true"))
&& currentClassDoc.isScript() && "main".equals(node.getName()) && node.isStatic() && node.getParameters().length == 1)
return;
@@ -251,6 +256,9 @@ public class GroovydocVisitor extends ClassCodeVisitorSupport {
return;
}
+ for (GroovyFieldDoc field : currentClassDoc.properties()) {
+ if (propName.equals(field.name())) return;
+ }
SimpleGroovyClassDoc classDoc = currentClassDoc;
// TODO: not sure why but groovy.ui.view.BasicContentPane#buildOutputArea classDoc is null
if (classDoc == null) {
@@ -347,21 +355,22 @@ public class GroovydocVisitor extends ClassCodeVisitorSupport {
} else {
if (Modifier.isPublic(mods)) {
element.setPublic(true);
- }
- if (Modifier.isProtected(mods)) {
+ } else if (Modifier.isProtected(mods)) {
element.setProtected(true);
- }
- if (Modifier.isPrivate(mods)) {
+ } else if (Modifier.isPrivate(mods)) {
element.setPrivate(true);
+ } else {
+ element.setPackagePrivate(true);
}
- if (Modifier.isFinal(mods)) {
- element.setFinal(true);
- }
+ }
+ if (Modifier.isFinal(mods)) {
+ element.setFinal(true);
}
}
@Override
public void visitField(FieldNode node) {
+ if (node.isSynthetic()) return;
String name = node.getName();
SimpleGroovyFieldDoc fieldDoc = new SimpleGroovyFieldDoc(name, currentClassDoc);
fieldDoc.setType(new SimpleGroovyType(makeType(node.getType())));
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/groovydoc/GroovyDoc.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/groovydoc/GroovyDoc.java
index fedfc83d6e..508599897f 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/groovydoc/GroovyDoc.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/groovydoc/GroovyDoc.java
@@ -36,6 +36,8 @@ public interface GroovyDoc extends Comparable<GroovyDoc> {
boolean isEnum();
+ boolean isRecord();
+
boolean isEnumConstant();
boolean isError();
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/ArrayClassDocWrapper.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/ArrayClassDocWrapper.java
index c443c630fb..5b357ea77b 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/ArrayClassDocWrapper.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/ArrayClassDocWrapper.java
@@ -304,6 +304,11 @@ public class ArrayClassDocWrapper implements GroovyClassDoc {
return delegate.isError();
}
+ @Override
+ public boolean isRecord() {
+ return delegate.isRecord();
+ }
+
@Override
public boolean isException() {
return delegate.isException();
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/ExternalGroovyClassDoc.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/ExternalGroovyClassDoc.java
index f5c6ac8ad6..d212865730 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/ExternalGroovyClassDoc.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/ExternalGroovyClassDoc.java
@@ -324,6 +324,11 @@ public class ExternalGroovyClassDoc implements GroovyClassDoc {
return false;
}
+ @Override
+ public boolean isRecord() {
+ return false;
+ }
+
@Override
public boolean isEnumConstant() {
return false;
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyRootDocBuilder.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyRootDocBuilder.java
index 52ce41504c..9fb9023772 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyRootDocBuilder.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyRootDocBuilder.java
@@ -66,7 +66,7 @@ public class GroovyRootDocBuilder {
public void buildTree(List<String> filenames) throws IOException {
setOverview();
- List<File> sourcepathFiles = new ArrayList<File>();
+ List<File> sourcepathFiles = new ArrayList<>();
if (sourcepaths != null) {
for (String sourcepath : sourcepaths) {
sourcepathFiles.add(new File(sourcepath).getAbsoluteFile());
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyAnnotationRef.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyAnnotationRef.java
index 885498132e..3b5e120207 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyAnnotationRef.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyAnnotationRef.java
@@ -21,40 +21,32 @@ package org.codehaus.groovy.tools.groovydoc;
import org.codehaus.groovy.groovydoc.GroovyAnnotationRef;
import org.codehaus.groovy.groovydoc.GroovyClassDoc;
import org.codehaus.groovy.runtime.StringGroovyMethods;
-
public class SimpleGroovyAnnotationRef implements GroovyAnnotationRef {
private GroovyClassDoc type;
private final String desc;
private String name;
-
public SimpleGroovyAnnotationRef(String name, String desc) {
this.name = name;
final String params = StringGroovyMethods.minus(desc, "@" + name);
this.desc = "()".equals(params) ? "" : params;
}
-
public void setType(GroovyClassDoc type) {
this.type = type;
}
-
@Override
public GroovyClassDoc type() {
return type;
}
-
public boolean isTypeAvailable() {
- return !(type == null);
+ return type != null;
}
-
@Override
public String name() {
return name;
}
-
public void setName(String name) {
this.name = name;
}
-
@Override
public String description() {
return desc;
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyDoc.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyDoc.java
index 7031daba8f..58b79be0a8 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyDoc.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyDoc.java
@@ -33,6 +33,8 @@ public class SimpleGroovyDoc implements GroovyDoc/*, GroovyTokenTypes*/ {
public static final int CLASS_DEF = 13;
public static final int TRAIT_DEF = 15;
public static final int INTERFACE_DEF = 14;
+
+ public static final int RECORD_DEF = 16;
public static final int ANNOTATION_DEF = 64;
public static final int ENUM_DEF = 61;
private static final Pattern TAG2_PATTERN = Pattern.compile("(?s)([a-z]+)\\s+(.*)");
@@ -174,8 +176,14 @@ public class SimpleGroovyDoc implements GroovyDoc/*, GroovyTokenTypes*/ {
return definitionType == ENUM_DEF;
}
+ @Override
+ public boolean isRecord() {
+ return definitionType == RECORD_DEF;
+ }
+
public String getTypeDescription() {
if (isInterface()) return "Interface";
+ if (isRecord()) return "Record";
if (isTrait()) return "Trait";
if (isAnnotationType()) return "Annotation Type";
if (isEnum()) return "Enum";
@@ -185,6 +193,7 @@ public class SimpleGroovyDoc implements GroovyDoc/*, GroovyTokenTypes*/ {
public String getTypeSourceDescription() {
if (isInterface()) return "interface";
+ if (isRecord()) return "record";
if (isTrait()) return "trait";
if (isAnnotationType()) return "@interface";
if (isEnum()) return "enum";
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/antlr4/GroovyDocParser.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/antlr4/GroovyDocParser.java
index c2ed129406..423e76191e 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/antlr4/GroovyDocParser.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/antlr4/GroovyDocParser.java
@@ -83,10 +83,29 @@ public class GroovyDocParser implements GroovyDocParserI {
CompilationUnit compUnit = new CompilationUnit(config);
SourceUnit unit = new SourceUnit(file, src, config, null, new ErrorCollector(config));
compUnit.addSource(unit);
- compUnit.compile(Phases.CONVERSION);
+ int phase = Phases.CLASS_GENERATION;
+ if (properties.containsKey("phaseOverride")) {
+ String raw = properties.getProperty("phaseOverride");
+ try {
+ phase = Integer.parseInt(raw);
+ } catch(NumberFormatException ignore) {
+ raw = raw.toUpperCase();
+ switch(raw) {
+ // some dup here but kept simple since we may swap Phases to an enum
+ case "CONVERSION": phase = 3; break;
+ case "SEMANTIC_ANALYSIS": phase = 4; break;
+ case "CANONICALIZATION": phase = 5; break;
+ case "INSTRUCTION_SELECTION": phase = 6; break;
+ case "CLASS_GENERATION": phase = 7; break;
+ default:
+ System.err.println("Ignoring unrecognised or unsuitable phase and keeping default");
+ }
+ }
+ }
+ compUnit.compile(phase);
ModuleNode root = unit.getAST();
GroovydocVisitor visitor = new GroovydocVisitor(unit, packagePath, links, properties);
- visitor.visitClass(root.getClasses().get(0));
+ root.getClasses().stream().forEach(clazz -> visitor.visitClass(clazz));
return visitor.getGroovyClassDocs();
}
diff --git a/subprojects/groovy-groovydoc/src/main/resources/org/codehaus/groovy/tools/groovydoc/gstringTemplates/classLevel/classDocName.html b/subprojects/groovy-groovydoc/src/main/resources/org/codehaus/groovy/tools/groovydoc/gstringTemplates/classLevel/classDocName.html
index 9dd33bc3e2..8328fb4292 100644
--- a/subprojects/groovy-groovydoc/src/main/resources/org/codehaus/groovy/tools/groovydoc/gstringTemplates/classLevel/classDocName.html
+++ b/subprojects/groovy-groovydoc/src/main/resources/org/codehaus/groovy/tools/groovydoc/gstringTemplates/classLevel/classDocName.html
@@ -79,7 +79,7 @@
]
def isRequired = { f, v -> def req = f.constantValueExpression() == null; req.toString() == v }
def upcase = { n -> n[0].toUpperCase() + n[1..-1] }
- def paramsOf = { n, boolean brief -> n.parameters().collect{ param -> (brief?'':annotations(param, ' ')) + linkable(param.isTypeAvailable()?param.type():param.typeName()) + (param.vararg()?'... ':' ') + param.name() + (param.defaultValue() ? " = " + param.defaultValue():"") }.join(", ") }
+ def paramsOf = { n, boolean brief -> n.parameters().collect{ param -> (brief?'':annotations(param, '<br>')) + linkable(param.isTypeAvailable()?param.type():param.typeName()) + (param.vararg()?'... ':' ') + param.name() + (param.defaultValue() ? " = " + param.defaultValue():"") }.join(", ") }
def rawType = { n -> def g = n.indexOf("<"); g >= 0 ? n.substring(0, g) : n }
def nameFromParams = { n -> n.name() + '(' + n.parameters().collect{ param -> rawType(param.isTypeAvailable()?param.type().qualifiedTypeName():param.typeName()) }.join(', ') + ')' }
def nameFromJavaParams = { n -> n.getName() + '(' + n.parameterTypes.collect{ param -> param.getName() }.join(', ') + ')' }
@@ -585,7 +585,7 @@ if (classDoc.isInterface() && classDoc.interfaces()) {
<a name="${field.name()}"><!-- --></a>
<ul class="blockListLast">
<li class="blockList">
- <h4>${annotations(field, '\n') + modifiersWithOptions(field, false, false) + linkable(field.type())} <strong>${field.name()}</strong></h4>
+ <h4>${annotations(field, '<br>') + modifiersWithOptions(field, false, false) + linkable(field.type())} <strong>${field.name()}</strong></h4>
<p>${field.commentText()}</p>
</li>
</ul>
@@ -605,7 +605,7 @@ if (classDoc.isInterface() && classDoc.interfaces()) {
<a name="${prop.name()}"><!-- --></a>
<ul class="blockListLast">
<li class="blockList">
- <h4>${annotations(prop, '\n') + modifiers(prop) + linkable(prop.type())} <strong>${prop.name()}</strong></h4>
+ <h4>${annotations(prop, '<br>') + modifiers(prop) + linkable(prop.type())} <strong>${prop.name()}</strong></h4>
<p>${prop.commentText()}</p>
</li>
</ul>
@@ -645,7 +645,7 @@ if (classDoc.isInterface() && classDoc.interfaces()) {
<a name="${nameFromParams(constructor)}"><!-- --></a>
<ul class="blockListLast">
<li class="blockList">
- <h4>${annotations(constructor, '\n') + modifiers(constructor)}<strong>${constructor.name()}</strong>(${paramsOf(constructor, false)})</h4>
+ <h4>${annotations(constructor, '<br>') + modifiers(constructor)}<strong>${constructor.name()}</strong>(${paramsOf(constructor, false)})</h4>
<p>${constructor.commentText()}</p>
</li>
</ul>
@@ -667,7 +667,7 @@ if (classDoc.isInterface() && classDoc.interfaces()) {
<ul class="blockListLast">
<li class="blockList">
<h4>${method.typeParameters() ?
- org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDoc.encodeAngleBrackets(method.typeParameters()) + ' ' : ''}${annotations(method, '\n') + modifiers(method)}${linkable(method.returnType())} <strong>${method.name()}</strong>(${paramsOf(method, false)})</h4>
+ org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDoc.encodeAngleBrackets(method.typeParameters()) + ' ' : ''}${annotations(method, '<br>') + modifiers(method)}${linkable(method.returnType())} <strong>${method.name()}</strong>(${paramsOf(method, false)})</h4>
<p>${method.commentText()}</p>
</li>
</ul>
diff --git a/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/GroovyDocToolTest.java b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/GroovyDocToolTest.java
index 5586f21bb7..b563df8553 100644
--- a/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/GroovyDocToolTest.java
+++ b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/GroovyDocToolTest.java
@@ -32,6 +32,7 @@ import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
public class GroovyDocToolTest extends GroovyTestCase {
private static final String MOCK_DIR = "mock/doc";
@@ -45,25 +46,8 @@ public class GroovyDocToolTest extends GroovyTestCase {
public void setUp() {
plainTool = new GroovyDocTool(new String[]{"src/test/groovy"});
- xmlTool = new GroovyDocTool(
- new FileSystemResourceManager("src"), // template storage
- new String[] {"src/main/java", "../../src/main/java", "src/test/groovy"}, // source file dirs
- new String[]{TEMPLATES_DIR + "/topLevel/rootDocStructuredData.xml"},
- new String[]{TEMPLATES_DIR + "/packageLevel/packageDocStructuredData.xml"},
- new String[]{TEMPLATES_DIR + "/classLevel/classDocStructuredData.xml"},
- new ArrayList<LinkArgument>(),
- new Properties()
- );
-
- xmlToolForTests = new GroovyDocTool(
- new FileSystemResourceManager("src"), // template storage
- new String[] {"src/test/groovy", "src/test/resources", "../../src/test"}, // source file dirs
- new String[]{TEMPLATES_DIR + "/topLevel/rootDocStructuredData.xml"},
- new String[]{TEMPLATES_DIR + "/packageLevel/packageDocStructuredData.xml"},
- new String[]{TEMPLATES_DIR + "/classLevel/classDocStructuredData.xml"},
- new ArrayList<LinkArgument>(),
- new Properties()
- );
+ xmlTool = makeXmlTool(new ArrayList<LinkArgument>(), new Properties());
+ xmlToolForTests = makeXmlTool(new ArrayList<LinkArgument>(), new Properties(), new String[] {"src/test/groovy", "src/test/resources", "../../src/test"});
ArrayList<LinkArgument> links = new ArrayList<LinkArgument>();
LinkArgument link = new LinkArgument();
@@ -74,6 +58,22 @@ public class GroovyDocToolTest extends GroovyTestCase {
htmlTool = makeHtmltool(links, new Properties());
}
+ private GroovyDocTool makeXmlTool(ArrayList<LinkArgument> links, Properties props) {
+ return makeXmlTool(links, props, new String[] {"src/main/java", "../../src/main/java", "src/test/groovy"});
+ }
+
+ private GroovyDocTool makeXmlTool(ArrayList<LinkArgument> links, Properties props, String[] sources) {
+ return new GroovyDocTool(
+ new FileSystemResourceManager("src"), // template storage
+ sources, // source file dirs
+ new String[]{TEMPLATES_DIR + "/topLevel/rootDocStructuredData.xml"},
+ new String[]{TEMPLATES_DIR + "/packageLevel/packageDocStructuredData.xml"},
+ new String[]{TEMPLATES_DIR + "/classLevel/classDocStructuredData.xml"},
+ links,
+ props
+ );
+ }
+
private GroovyDocTool makeHtmltool(ArrayList<LinkArgument> links, Properties props) {
return new GroovyDocTool(
new FileSystemResourceManager("src/main/resources"), // template storage
@@ -610,14 +610,12 @@ public class GroovyDocToolTest extends GroovyTestCase {
GroovyClassDoc classDocDescendantE = getGroovyClassDocByName(root, "DescendantE");
assertNotNull("Expecting to find DescendantE", classDocDescendantE);
GroovyClassDoc base = root.classNamed(classDocDescendantE, "Base");
- // TODO reinstate next two lines or justify why they should be removed
-// assertNotNull("Expecting to find Base in: " + Arrays.stream(root.classes()).map(GroovyClassDoc::getFullPathName).collect(Collectors.joining(", ")), base);
-// assertEquals(fullPathBaseC, base.getFullPathName());
+ assertNotNull("Expecting to find Base in: " + Arrays.stream(root.classes()).map(GroovyClassDoc::getFullPathName).collect(Collectors.joining(", ")), base);
+ assertEquals(fullPathBaseC, base.getFullPathName());
GroovyClassDoc classDocDescendantF = getGroovyClassDocByName(root, "DescendantF");
- assertNotNull("Expecting to find DescendantF", classDocDescendantF);
- // TODO reinstate next line or justify why it should be removed
-// assertEquals(fullPathBaseC, root.classNamed(classDocDescendantF, "Base").getFullPathName());
+ assertNotNull("Expecting to find DescendantF in: " + Arrays.stream(root.classes()).map(GroovyClassDoc::getFullPathName).collect(Collectors.joining(", ")), classDocDescendantF);
+ assertEquals(fullPathBaseC, root.classNamed(classDocDescendantF, "Base").getFullPathName());
}
// GROOVY-5939
@@ -736,7 +734,7 @@ public class GroovyDocToolTest extends GroovyTestCase {
// and that should link to api/Foo.html, not to lib/Foo.html.
final Matcher interfacesAndTraits = Pattern.compile(
"<dt>All Implemented Interfaces and Traits:</dt>\\s*" +
- "<dd><a href='[./]*/org/codehaus/groovy/tools/groovydoc/testfiles/alias/(api|lib)/Foo\\.html'>(Foo|FooImpl)</a></dd>"
+ "<dd><a href='[./]*/org/codehaus/groovy/tools/groovydoc/testfiles/alias/(api|lib)/Foo\\.html'>(Foo|FooImpl)</a>"
).matcher(fooAdapterDoc);
// Constructor is actually "FooAdapter(FooImpl foo)",
@@ -985,22 +983,24 @@ public class GroovyDocToolTest extends GroovyTestCase {
"<pre>" +
"(public )?class (ClassWithMethodComment|DocumentedClass)\n" +
"extends " + object +
+ "(\nimplements groovy.lang.GroovyObject)?" +
"</pre>");
final Pattern derivedClass = Pattern.compile(
"<pre>" +
"(public )?abstract class (Java|Groovy)ClassWithMultipleInterfaces\n" +
"extends " + object + "\n" +
"implements " + interfaces +
+ "(, groovy.lang.GroovyObject)?" +
"</pre>");
assertTrue("The Java base interface declaration header should match", baseInterface.matcher(javaBaseInterface).find());
assertTrue("The Groovy base interface declaration header should match", baseInterface.matcher(groovyBaseInterface).find());
assertTrue("The Java derived interface declaration header should match", derivedInterface.matcher(javaDerivedInterface).find());
assertTrue("The Groovy derived interface declaration header should match", derivedInterface.matcher(groovyDerivedInterface).find());
- assertTrue("The Java base class declaration header should match", baseClass.matcher(javaBaseClass).find());
- assertTrue("The Groovy base class declaration header should match", baseClass.matcher(groovyBaseClass).find());
- assertTrue("The Java derived class declaration header should match", derivedClass.matcher(javaDerivedClass).find());
- assertTrue("The Groovy derived class declaration header should match", derivedClass.matcher(groovyDerivedClass).find());
+ assertTrue("The Java base class declaration header should match in:\n" + javaBaseClass, baseClass.matcher(javaBaseClass).find());
+ assertTrue("The Groovy base class declaration header should match in:\n" + groovyBaseClass, baseClass.matcher(groovyBaseClass).find());
+ assertTrue("The Java derived class declaration header should match in:\n" + javaDerivedClass, derivedClass.matcher(javaDerivedClass).find());
+ assertTrue("The Groovy derived class declaration header should match in:\n" + groovyDerivedClass, derivedClass.matcher(groovyDerivedClass).find());
}
public void testJavaGenericsTitle() throws Exception {
@@ -1033,12 +1033,12 @@ public class GroovyDocToolTest extends GroovyTestCase {
final String groovydoc = output.getText(MOCK_DIR + "/" + base + "/Groovy.html");
- final Matcher title = Pattern.compile(Pattern.quote(
- "<h2 title=\"[Groovy] Trait Groovy<N extends Number & Comparable<? extends Number>>\" class=\"title\">"+
- "[Groovy] Trait Groovy<N extends Number & Comparable<? extends Number>></h2>"
- )).matcher(groovydoc);
+ final Matcher title = Pattern.compile(
+ "<h2 title=\"\\[Groovy] Trait Groovy<N extends (java.lang.)?Number & (java.lang.)?Comparable<\\? extends (java.lang.)?Number>>\" class=\"title\">"+
+ "\\[Groovy] Trait Groovy<N extends (java.lang.)?Number & (java.lang.)?Comparable<\\? extends (java.lang.)?Number>></h2>"
+ ).matcher(groovydoc);
- assertTrue("The title should have the generics information", title.find());
+ assertTrue("The title should have the generics information in:\n" + groovydoc, title.find());
}
public void testParamTagForTypeParams() throws Exception {
@@ -1058,13 +1058,13 @@ public class GroovyDocToolTest extends GroovyTestCase {
"<DL><DT><B>Type Parameters:</B></DT><DD><code>N</code> - Doc.</DD></DL>"
);
final Pattern methodTypeParams = Pattern.compile(
- "<DL><DT><B>Type Parameters:</B></DT><DD><code>A</code> - Doc.</DD><DD><code>B</code> - Doc.</DD></DL>"
+ "<DL><DT><B>Type Parameters:</B></DT><DD><code>C</code> - Doc.</DD><DD><code>D</code> - Doc.</DD></DL>"
);
- assertTrue("The Java class doc should have type parameters definitions", classTypeParams.matcher(javadoc).find());
- assertTrue("The Groovy class doc should have type parameters definitions", classTypeParams.matcher(groovydoc).find());
- assertTrue("The Java method doc should have type parameters definitions", methodTypeParams.matcher(javadoc).find());
- assertTrue("The Groovy method doc should have type parameters definitions", methodTypeParams.matcher(groovydoc).find());
+ assertTrue("The Java class doc should have type parameters definitions in:\n" + javadoc, classTypeParams.matcher(javadoc).find());
+ assertTrue("The Groovy class doc should have type parameters definitions in:\n" + groovydoc, classTypeParams.matcher(groovydoc).find());
+ assertTrue("The Java method doc should have type parameters definitions in:\n" + javadoc, methodTypeParams.matcher(javadoc).find());
+ assertTrue("The Groovy method doc should have type parameters definitions in:\n" + groovydoc, methodTypeParams.matcher(groovydoc).find());
}
public void testMethodTypeParams() throws Exception {
@@ -1081,16 +1081,16 @@ public class GroovyDocToolTest extends GroovyTestCase {
final String groovydoc = output.getText(MOCK_DIR + "/" + base + "/Groovy.html");
final Pattern methodSummaryTypeParams = Pattern.compile(
- "<td class=\"colFirst\"><code><A, B></code></td>"
+ "<td class=\"colFirst\"><code><C, D></code></td>"
);
final Pattern methodDetailsTypeParams = Pattern.compile(
- "<h4><A, B> (public )?static int <strong>compare</strong>"
+ "<h4><C, D> .*int <strong>compare</strong>\\("
);
assertTrue("The Java method summary should have type parameters", methodSummaryTypeParams.matcher(javadoc).find());
assertTrue("The Groovy method summary should have type parameters", methodSummaryTypeParams.matcher(groovydoc).find());
assertTrue("The Java method details should have type parameters", methodDetailsTypeParams.matcher(javadoc).find());
- assertTrue("The Groovy method details should have type parameters", methodDetailsTypeParams.matcher(groovydoc).find());
+ assertTrue("The Groovy method details should have type parameters in:\n" + groovydoc, methodDetailsTypeParams.matcher(groovydoc).find());
}
public void testMethodParamTypeParams() throws Exception {
@@ -1106,31 +1106,31 @@ public class GroovyDocToolTest extends GroovyTestCase {
final String javadoc = output.getText(MOCK_DIR + "/" + base + "/Java.html");
final String groovydoc = output.getText(MOCK_DIR + "/" + base + "/Groovy.html");
- final Pattern methodSummary = Pattern.compile(Pattern.quote(
- "<code><strong><a href=\"#compare(Class, Class)\">compare</a></strong>"
- + "("
- + "<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html' title='Class'>Class</a><A> a, "
- + "<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html' title='Class'>Class</a><B> b"
- + ")"
+ final Pattern methodSummary = Pattern.compile(
+ "<code><strong><a href=\"#compare\\((java.lang.)?Class, (java.lang.)?Class\\)\">compare</a></strong>"
+ + "\\("
+ + "<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html' title='Class'>Class</a><C> c, "
+ + "<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html' title='Class'>Class</a><D> d"
+ + "\\)"
+ "</code>"
- ));
- final Pattern methodDetailAnchor = Pattern.compile(Pattern.quote(
- "<a name=\"compare(Class, Class)\"><!-- --></a>"
- ));
+ );
+ final Pattern methodDetailAnchor = Pattern.compile(
+ "<a name=\"compare\\((java.lang.)?Class, (java.lang.)?Class\\)\"><!-- --></a>"
+ );
final Pattern methodDetailTitle = Pattern.compile(Pattern.quote(
"<strong>compare</strong>" +
"(" +
- "<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html' title='Class'>Class</a><A> a, " +
- "<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html' title='Class'>Class</a><B> b" +
+ "<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html' title='Class'>Class</a><C> c, " +
+ "<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html' title='Class'>Class</a><D> d" +
")"
));
- assertTrue("The Java method summary should include type parameters", methodSummary.matcher(javadoc).find());
- assertTrue("The Java method detail anchor should NOT include type parameters", methodDetailAnchor.matcher(javadoc).find());
- assertTrue("The Java method detail title should include type parameters", methodDetailTitle.matcher(javadoc).find());
- assertTrue("The Groovy method summary should include type parameters", methodSummary.matcher(groovydoc).find());
- assertTrue("The Groovy method detail anchor should NOT include type parameters", methodDetailAnchor.matcher(groovydoc).find());
- assertTrue("The Groovy method detail title should include type parameters", methodDetailTitle.matcher(groovydoc).find());
+ assertTrue("The Java method summary should include type parameters in:\n" + javadoc, methodSummary.matcher(javadoc).find());
+ assertTrue("The Java method detail anchor should NOT include type parameters in:\n" + javadoc, methodDetailAnchor.matcher(javadoc).find());
+ assertTrue("The Java method detail title should include type parameters in:\n" + javadoc, methodDetailTitle.matcher(javadoc).find());
+ assertTrue("The Groovy method summary should include type parameters in:\n" + groovydoc, methodSummary.matcher(groovydoc).find());
+ assertTrue("The Groovy method detail anchor should NOT include type parameters in:\n" + groovydoc, methodDetailAnchor.matcher(groovydoc).find());
+ assertTrue("The Groovy method detail title should include type parameters in:\n" + groovydoc, methodDetailTitle.matcher(groovydoc).find());
}
public void testAnnotations() throws Exception {
@@ -1146,62 +1146,75 @@ public class GroovyDocToolTest extends GroovyTestCase {
final String groovydoc = output.getText(MOCK_DIR + "/" + base + "/Groovy.html");
final String javadoc = output.getText(MOCK_DIR + "/" + base + "/Java.html");
- assertTrue("The Groovy class declaration header should have the annotation", Pattern.compile(Pattern.quote(
+ assertTrue("The Groovy class declaration header should have the annotation in:\n" + groovydoc, Pattern.compile(Pattern.quote(
"<pre>@groovy.transform.EqualsAndHashCode(cache: true)\n" +
"class Groovy"
)).matcher(groovydoc).find());
- assertTrue("The Java class declaration header should have the annotation", Pattern.compile(Pattern.quote(
+ assertTrue("The Java class declaration header should have the annotation in:\n" + javadoc, Pattern.compile(Pattern.quote(
"<pre>@<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Deprecated.html' title='Deprecated'>Deprecated</a>\n" +
"@<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/SuppressWarnings.html' title='SuppressWarnings'>SuppressWarnings</a>(\"foo\")\n" +
"public class Java"
)).matcher(javadoc).find());
- assertTrue("The Groovy field details should have the annotation", Pattern.compile(Pattern.quote(
- "<h4>@groovy.transform.Internal\n" +
+ assertTrue("The Groovy field details should have the annotation in:" + groovydoc, Pattern.compile(Pattern.quote(
+ "<h4>@groovy.transform.Internal<br>" +
"public <a href='https://docs.oracle.com/javase/8/docs/api/java/lang/String.html' title='String'>String</a> " +
"<strong>annotatedField</strong></h4>"
)).matcher(groovydoc).find());
assertTrue("The Java field details should have the annotation", Pattern.compile(Pattern.quote(
- "<h4>@<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Deprecated.html' title='Deprecated'>Deprecated</a>\n" +
+ "<h4>@<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Deprecated.html' title='Deprecated'>Deprecated</a><br>" +
"public <a href='https://docs.oracle.com/javase/8/docs/api/java/lang/String.html' title='String'>String</a> " +
"<strong>annotatedField</strong></h4>"
)).matcher(javadoc).find());
assertTrue("The Groovy property details should have the annotation", Pattern.compile(Pattern.quote(
- "<h4>@<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Deprecated.html' title='Deprecated'>Deprecated</a>\n" +
+ "<h4>@<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Deprecated.html' title='Deprecated'>Deprecated</a><br>" +
"<a href='https://docs.oracle.com/javase/8/docs/api/java/util/List.html' title='List'>List</a> <strong>annotatedProperty</strong></h4>"
)).matcher(groovydoc).find());
// Java doesn't have properties section
- assertTrue("The Groovy ctor details should have the annotation", Pattern.compile(Pattern.quote(
- "<h4>@groovy.transform.NamedVariant\n" +
+ assertTrue("The Groovy ctor details should have the annotation in:\n" + groovydoc, Pattern.compile(Pattern.quote(
+ "<h4>@groovy.transform.NamedVariant<br>" +
"<strong>Groovy</strong>(" +
- "@groovy.transform.NamedParam " +
"<a href='https://docs.oracle.com/javase/8/docs/api/java/util/List.html' title='List'>List</a> ctorParam" +
")</h4>"
)).matcher(groovydoc).find());
+ assertTrue("The Groovy ctor details should have the annotation in:\n" + groovydoc, Pattern.compile(Pattern.quote(
+ "<h4>@groovy.transform.Generated<br>" +
+ "<strong>Groovy</strong>(" +
+ "@groovy.transform.NamedParam(value: ctorParam, type: java.util.List)<br>" +
+ "<a href='https://docs.oracle.com/javase/8/docs/api/java/util/Map.html' title='Map'>Map</a> namedArgs" +
+ ")</h4>"
+ )).matcher(groovydoc).find());
assertTrue("The Java ctor details should have the annotation", Pattern.compile(Pattern.quote(
- "<h4>@<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Deprecated.html' title='Deprecated'>Deprecated</a>\n" +
+ "<h4>@<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Deprecated.html' title='Deprecated'>Deprecated</a><br>" +
"public <strong>Java</strong>()</h4>"
)).matcher(javadoc).find());
// Note also the param annotation
- assertTrue("The Groovy method details should have the annotations", Pattern.compile(Pattern.quote(
- "<h4>@groovy.transform.NamedVariant\n" +
+ assertTrue("The Groovy method details should have the annotations in:\n" + groovydoc, Pattern.compile(Pattern.quote(
+ "<h4>@groovy.transform.NamedVariant<br>" +
"void <strong>annotatedMethod</strong>(" +
- "@groovy.transform.NamedParam(required: true) " +
"<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/String.html' title='String'>String</a> methodParam" +
")</h4>"
)).matcher(groovydoc).find());
+ // Note also the param annotation
+ assertTrue("The Groovy method details should have the annotations in:\n" + groovydoc, Pattern.compile(Pattern.quote(
+ "<h4>@groovy.transform.Generated<br>" +
+ "void <strong>annotatedMethod</strong>(" +
+ "@groovy.transform.NamedParam(required: true, value: methodParam, type: java.lang.String)<br>" +
+ "<a href='https://docs.oracle.com/javase/8/docs/api/java/util/Map.html' title='Map'>Map</a> namedArgs" +
+ ")</h4>"
+ )).matcher(groovydoc).find());
- assertTrue("The Java method details should have the annotations", Pattern.compile(Pattern.quote(
- "<h4>@<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Deprecated.html' title='Deprecated'>Deprecated</a>\n" +
+ assertTrue("The Java method details should have the annotations in:\n" + javadoc, Pattern.compile(Pattern.quote(
+ "<h4>@<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/Deprecated.html' title='Deprecated'>Deprecated</a><br>" +
"public void <strong>annotatedMethod</strong>(" +
- "@CommandLine.Parameters(hidden = true) " +
+ "@CommandLine.Parameters(hidden = true)<br>" +
"<a href='https://docs.oracle.com/javase/8/docs/api/java/lang/String.html' title='String'>String</a> annotatedParam" +
")</h4>"
)).matcher(javadoc).find());
@@ -1337,8 +1350,11 @@ public class GroovyDocToolTest extends GroovyTestCase {
public void testScript() throws Exception {
List<String> srcList = new ArrayList<String>();
srcList.add("org/codehaus/groovy/tools/groovydoc/testfiles/Script.groovy");
- xmlTool.add(srcList);
+ Properties props = new Properties();
+ props.put("packageScope", "true");
+ xmlTool = makeXmlTool(new ArrayList<LinkArgument>(), props);
+ xmlTool.add(srcList);
MockOutputTool output = new MockOutputTool();
xmlTool.renderToOutput(output, MOCK_DIR);
String scriptDoc = output.getText(MOCK_DIR + "/org/codehaus/groovy/tools/groovydoc/testfiles/Script.html");
@@ -1349,7 +1365,7 @@ public class GroovyDocToolTest extends GroovyTestCase {
assertTrue("There should be a reference to method sayGoodbye", containsTagWithName(scriptDoc, "method", "sayGoodbye"));
assertTrue("Expecting bid farewell in:\n" + scriptDoc, scriptDoc.contains("Use this to bid farewell"));
- assertTrue("There should be a reference to property instanceProp in:\n" + scriptDoc, containsTagWithName(scriptDoc, "property", "instanceProp"));
+ assertTrue("There should be a reference to property instanceProp in:\n" + scriptDoc, containsTagWithName(scriptDoc, "field", "instanceProp"));
assertTrue("There should be a reference to field staticField", containsTagWithName(scriptDoc, "field", "staticField"));
diff --git a/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/generics/Groovy.groovy b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/generics/Groovy.groovy
index 3f781ec264..c19bb5ffd5 100644
--- a/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/generics/Groovy.groovy
+++ b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/generics/Groovy.groovy
@@ -26,7 +26,7 @@ package org.codehaus.groovy.tools.groovydoc.testfiles.generics
trait Groovy<N extends Number & Comparable<? extends Number>> {
/**
- * Generic method.
+ * Generic static method.
*
* @param <A> Doc.
* @param <B> Doc.
@@ -34,7 +34,20 @@ trait Groovy<N extends Number & Comparable<? extends Number>> {
* @param b Doc.
* @return Doc.
*/
- static <A, B> int compare(Class<A> a, Class<B> b) {
+ static <A, B> int compareS(Class<A> a, Class<B> b) {
+ 0
+ }
+
+ /**
+ * Generic instance method.
+ *
+ * @param <C> Doc.
+ * @param <D> Doc.
+ * @param c Doc.
+ * @param d Doc.
+ * @return Doc.
+ */
+ <C, D> int compare(Class<C> c, Class<D> d) {
0
}
}
diff --git a/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/generics/Java.java b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/generics/Java.java
index d31944f6da..7368723c7f 100644
--- a/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/generics/Java.java
+++ b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/generics/Java.java
@@ -25,7 +25,7 @@ package org.codehaus.groovy.tools.groovydoc.testfiles.generics;
*/
public abstract class Java<N extends Number & Comparable<? extends Number>> {
/**
- * Generic method.
+ * Generic static method.
*
* @param <A> Doc.
* @param <B> Doc.
@@ -33,7 +33,21 @@ public abstract class Java<N extends Number & Comparable<? extends Number>> {
* @param b Doc.
* @return Doc.
*/
- public static <A, B> int compare(Class<A> a, Class<B> b) {
+ public static <A, B> int compareS(Class<A> a, Class<B> b) {
return 0;
}
+
+ /**
+ * Generic instance method.
+ *
+ * @param <C> Doc.
+ * @param <D> Doc.
+ * @param c Doc.
+ * @param d Doc.
+ * @return Doc.
+ */
+ public <C, D> int compare(Class<C> c, Class<D> d) {
+ return 0;
+ }
+
}