-
Notifications
You must be signed in to change notification settings - Fork 3
Add possibility to check only public coverage #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 2 commits
c117572
6393b85
7ebf9bd
9556f6a
0d0c7d2
68fea80
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,12 @@ | |
*/ | ||
package com.manoelcampos.javadoc.coverage; | ||
|
||
import java.io.File; | ||
import java.io.FileNotFoundException; | ||
import java.io.FileOutputStream; | ||
import java.io.OutputStreamWriter; | ||
import java.io.PrintWriter; | ||
|
||
import com.manoelcampos.javadoc.coverage.exporter.ConsoleExporter; | ||
import com.manoelcampos.javadoc.coverage.exporter.DataExporter; | ||
import com.manoelcampos.javadoc.coverage.exporter.HtmlExporter; | ||
|
@@ -24,8 +30,6 @@ | |
import com.sun.javadoc.RootDoc; | ||
import com.sun.tools.doclets.standard.Standard; | ||
|
||
import java.io.*; | ||
|
||
/** | ||
* A {@link Doclet} that computes coverage of JavaDoc documentation. | ||
* It is the entry point for the JavaDoc Tool, which can be executed | ||
|
@@ -49,12 +53,20 @@ public class CoverageDoclet { | |
*/ | ||
public static final String OUTPUT_NAME_OPTION[] = {"-outputName", "-o"}; | ||
|
||
/** | ||
* A command line parameter to enable coverage reports only for certain visibility modifiers. The first value is the long version of the | ||
* parameter name and the second is the short one. Values for this option are public (only public stuff is used) and private (everything | ||
* is used) | ||
*/ | ||
public static final String COVERAGE_ONLY_FOR_PUBLIC_OPTION[] = { "-modifiers", "-m" }; | ||
|
||
/** | ||
* The {@link DataExporter} object to export the coverage report to a file | ||
* in a specific format. | ||
*/ | ||
private final DataExporter exporter; | ||
private final RootDoc rootDoc; | ||
private final boolean computeOnlyForPublicModifier; | ||
|
||
/** | ||
* Starts the actual parsing or JavaDoc documentation and generation of the coverage report. | ||
|
@@ -75,16 +87,23 @@ public static boolean start(final RootDoc rootDoc) { | |
*/ | ||
public CoverageDoclet(final RootDoc rootDoc) { | ||
this.rootDoc = rootDoc; | ||
computeOnlyForPublicModifier = "public".equals(getOptionValue(COVERAGE_ONLY_FOR_PUBLIC_OPTION)); | ||
|
||
// this needs to be the last part as it already accesses some stuff from the doclet | ||
this.exporter = new HtmlExporter(this); | ||
} | ||
|
||
public final boolean computeOnlyForPublicModifier() { | ||
return computeOnlyForPublicModifier; | ||
} | ||
|
||
/** | ||
* Checks if a given parameter is a valid custom parameter accepted by this doclet. | ||
* @param paramName the name of the parameter to check | ||
* @return true if it's a valid custom parameter, false otherwise | ||
*/ | ||
private static boolean isCustomParameter(final String paramName) { | ||
return isParameter(paramName, OUTPUT_NAME_OPTION); | ||
return isParameter(paramName, OUTPUT_NAME_OPTION) || isParameter(paramName, COVERAGE_ONLY_FOR_PUBLIC_OPTION); | ||
} | ||
|
||
/** | ||
|
@@ -131,7 +150,7 @@ public static boolean validOptions(final String[][] options, final DocErrorRepor | |
*/ | ||
public static int optionLength(final String option) { | ||
/*The custom outputName parameter accepts one argument. | ||
* The name of the param counts as the one argument.*/ | ||
* The name of the param counts as the one argument.*/ | ||
if (isCustomParameter(option)) { | ||
return 2; | ||
} | ||
|
@@ -148,14 +167,14 @@ public static int optionLength(final String option) { | |
* @return the values associated to the option, where the 0th element is the option itself; | ||
* or an empty array if the option is invalid. | ||
*/ | ||
public String[] getOptionValues(final String[] optionNames) { | ||
public String getOptionValue(final String[] optionNames) { | ||
for (final String[] optionValues : rootDoc.options()) { | ||
if (isParameter(optionValues[0], optionNames)) { | ||
return optionValues; | ||
return optionValues[1]; | ||
} | ||
} | ||
|
||
return new String[]{}; | ||
return null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To avoid NulPointerException, I prefer returning an empty String instead of null. We can use String.isEmpty to check if there is a value for a given parameter. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isn't a problem with the new configuration handling any more |
||
} | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,13 +15,17 @@ | |
*/ | ||
package com.manoelcampos.javadoc.coverage.stats; | ||
|
||
import com.manoelcampos.javadoc.coverage.Utils; | ||
import com.sun.javadoc.*; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
import com.manoelcampos.javadoc.coverage.Utils; | ||
import com.sun.javadoc.AnnotationTypeDoc; | ||
import com.sun.javadoc.AnnotationTypeElementDoc; | ||
import com.sun.javadoc.ClassDoc; | ||
import com.sun.javadoc.ConstructorDoc; | ||
import com.sun.javadoc.MethodDoc; | ||
|
||
/** | ||
* Computes statistics about the JavaDocs of a class, inner class, interface or enum | ||
* and its members, such as: fields, methods, constructors and annotations. | ||
|
@@ -46,34 +50,40 @@ public class ClassDocStats extends MembersDocStats { | |
private List<MethodDocStats> methodsStats; | ||
private List<MethodDocStats> constructorsStats; | ||
|
||
public ClassDocStats(final ClassDoc doc) { | ||
public ClassDocStats(final ClassDoc doc, boolean computeOnlyForPublic) { | ||
this.doc = doc; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The config parameter should be stored in a config attribute. This way, you avoid passing the config around several methods of the class. |
||
fieldsStats = new ClassMembersDocStats(doc.fields(false), "Fields"); | ||
enumsStats = new ClassMembersDocStats(doc.enumConstants(), "Enum Consts"); | ||
processMethodsDocsStats(doc); | ||
processConstructorsDocsStats(doc); | ||
processAnnotationsDocsStats(doc); | ||
fieldsStats = new ClassMembersDocStats(doc.fields(false), "Fields", computeOnlyForPublic); | ||
enumsStats = new ClassMembersDocStats(doc.enumConstants(), "Enum Consts", computeOnlyForPublic); | ||
processMethodsDocsStats(doc, computeOnlyForPublic); | ||
processConstructorsDocsStats(doc, computeOnlyForPublic); | ||
processAnnotationsDocsStats(doc, computeOnlyForPublic); | ||
} | ||
|
||
private void processAnnotationsDocsStats(ClassDoc doc) { | ||
private void processAnnotationsDocsStats(ClassDoc doc, boolean computeOnlyForPublic) { | ||
if (doc instanceof AnnotationTypeDoc) { | ||
annotationsStats = new ClassMembersDocStats(((AnnotationTypeDoc) doc).elements(), "Annotations"); | ||
} else annotationsStats = new ClassMembersDocStats(new AnnotationTypeElementDoc[0], "Annotations"); | ||
annotationsStats = new ClassMembersDocStats(((AnnotationTypeDoc) doc).elements(), "Annotations", computeOnlyForPublic); | ||
} else { | ||
annotationsStats = new ClassMembersDocStats(new AnnotationTypeElementDoc[0], "Annotations", computeOnlyForPublic); | ||
} | ||
} | ||
|
||
private void processConstructorsDocsStats(ClassDoc doc) { | ||
private void processConstructorsDocsStats(ClassDoc doc, boolean computeOnlyForPublic) { | ||
final ConstructorDoc[] constructors = doc.constructors(false); | ||
constructorsStats = new ArrayList<>(constructors.length); | ||
constructorsStats = new ArrayList<>(); | ||
for (final ConstructorDoc constructor : constructors) { | ||
constructorsStats.add(new MethodDocStats(constructor)); | ||
if (!computeOnlyForPublic || constructor.isPublic()) { | ||
constructorsStats.add(new MethodDocStats(constructor)); | ||
} | ||
} | ||
} | ||
|
||
private void processMethodsDocsStats(ClassDoc doc) { | ||
private void processMethodsDocsStats(ClassDoc doc, boolean computeOnlyForPublic) { | ||
final MethodDoc[] methods = doc.methods(false); | ||
methodsStats = new ArrayList<>(methods.length); | ||
methodsStats = new ArrayList<>(); | ||
for (final MethodDoc method : methods) { | ||
methodsStats.add(new MethodDocStats(method)); | ||
if (!computeOnlyForPublic || method.isPublic()) { | ||
methodsStats.add(new MethodDocStats(method)); | ||
} | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,11 +15,14 @@ | |
*/ | ||
package com.manoelcampos.javadoc.coverage.stats; | ||
|
||
import com.manoelcampos.javadoc.coverage.Utils; | ||
import com.sun.javadoc.Doc; | ||
|
||
import java.util.Arrays; | ||
import java.util.Objects; | ||
import java.util.function.Predicate; | ||
|
||
import com.manoelcampos.javadoc.coverage.Utils; | ||
import com.sun.javadoc.ClassDoc; | ||
import com.sun.javadoc.Doc; | ||
import com.sun.javadoc.ProgramElementDoc; | ||
|
||
/** | ||
* Computes JavaDoc coverage statistics for specific type of members belonging to an owner. | ||
|
@@ -35,17 +38,22 @@ public class ClassMembersDocStats extends MembersDocStats { | |
*/ | ||
private final Doc[] membersDocs; | ||
private final String membersType; | ||
private final boolean computeOnlyForPublic; | ||
|
||
/** | ||
* Instantiates an object to compute JavaDoc coverage statistics | ||
* for the members of a class, interface or enum. | ||
* Instantiates an object to compute JavaDoc coverage statistics for the members of a class, interface or enum. | ||
* | ||
* @param membersDocs the JavaDoc documentation for the members of the owner. | ||
* @param membersType the type of the members of the owner to compute JavaDoc coverage statistics. | ||
* @param membersDocs | ||
* the JavaDoc documentation for the members of the owner. | ||
* @param membersType | ||
* the type of the members of the owner to compute JavaDoc coverage statistics. | ||
* @param computeOnlyForPublic | ||
* indicates that coverage should only be compute for the public part of the javadoc | ||
*/ | ||
ClassMembersDocStats(final Doc[] membersDocs, final String membersType) { | ||
ClassMembersDocStats(final Doc[] membersDocs, final String membersType, boolean computeOnlyForPublic) { | ||
this.membersDocs = membersDocs; | ||
this.membersType = membersType; | ||
this.computeOnlyForPublic = computeOnlyForPublic; | ||
} | ||
|
||
/** | ||
|
@@ -66,14 +74,31 @@ public long getMembersNumber() { | |
* a class source code) will be computed as undocumented. | ||
*/ | ||
return Arrays.stream(membersDocs) | ||
.filter(filterPublicIfNecessary()) | ||
.map(Doc::position) | ||
.filter(Objects::nonNull) | ||
.count(); | ||
} | ||
|
||
@Override | ||
public long getDocumentedMembers() { | ||
return Arrays.stream(membersDocs).map(Doc::getRawCommentText).filter(Utils::isNotStringEmpty).count(); | ||
return Arrays.stream(membersDocs).filter(filterPublicIfNecessary()).map(Doc::getRawCommentText).filter(Utils::isNotStringEmpty) | ||
.count(); | ||
} | ||
|
||
private Predicate<? super Doc> filterPublicIfNecessary() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You don't need to make the method return a Then, where you have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. changed |
||
return m -> { | ||
if (computeOnlyForPublic) { | ||
if (m instanceof ClassDoc) { | ||
return !computeOnlyForPublic || ((ClassDoc) m).isPublic(); | ||
} else if (m instanceof ProgramElementDoc) { | ||
return !computeOnlyForPublic || ((ProgramElementDoc) m).isPublic(); | ||
} else { | ||
throw new UnsupportedOperationException("unimplemented for type " + m.getClass()); | ||
} | ||
} | ||
return true; | ||
}; | ||
} | ||
|
||
@Override | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that it should be created a new class to define a command line parameter. The class would include the short and long param names and a description. Then, a list of custom parameters could be defined, so that it can be iterated here to avoid changing the method every time a new parameter is included.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that was part of the configuration rework