Skip to content

Commit

Permalink
Java: Replace usage of toString() for Javadoc queries; add more Javad…
Browse files Browse the repository at this point in the history
…oc tags
  • Loading branch information
Marcono1234 committed Apr 30, 2021
1 parent b2c0259 commit 6b86a91
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import java

private predicate isDeprecatedCallable(Callable c) {
c.getAnAnnotation() instanceof DeprecatedAnnotation or
exists(c.getDoc().getJavadoc().getATag("@deprecated"))
exists(c.getDoc().getJavadoc().getATag().(DeprecatedTag))
}

from Call ca, Callable c
Expand Down
23 changes: 11 additions & 12 deletions java/ql/src/Advisory/Documentation/JavadocCommon.qll
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@ import java
/** Holds if the given `Javadoc` contains a minimum of a few characters of text. */
private predicate acceptableDocText(Javadoc j) {
// Require minimum combined length of all non-tag elements.
sum(JavadocElement e, int toSum |
e = j.getAChild() and
not e = j.getATag(_) and
toSum = e.toString().length()
sum(JavadocText t, int toSum |
t = j.getATextElement() and
toSum = t.getText().length()
|
toSum
) >= 5
}

/** Holds if the given `JavadocTag` contains a minimum of a few characters of text. */
private predicate acceptableTag(JavadocTag t) {
sum(JavadocElement e, int toSum |
e = t.getAChild() and
toSum = e.toString().length()
sum(JavadocText text, int toSum |
text = t.getATextElement() and
toSum = text.getText().length()
|
toSum
) >= 5
Expand Down Expand Up @@ -72,7 +71,7 @@ class DocuParam extends Parameter {
/** Holds if this parameter has a non-trivial `@param` tag. */
predicate hasAcceptableParamTag() {
exists(ParamTag t |
t = this.getCallable().getDoc().getJavadoc().getATag("@param") and
t = this.getCallable().getDoc().getJavadoc().getATag() and
t.getParamName() = this.getName() and
acceptableTag(t)
)
Expand All @@ -90,7 +89,7 @@ class DocuReturn extends DocuCallable {

/** Holds if this callable's `Javadoc` has a non-trivial `@return` tag. */
predicate hasAcceptableReturnTag() {
acceptableTag(this.getDoc().getJavadoc().getATag("@return"))
acceptableTag(this.getDoc().getJavadoc().getATag().(ReturnTag))
}
}

Expand All @@ -111,9 +110,9 @@ class DocuThrows extends DocuCallable {
predicate hasAcceptableThrowsTag(Exception e) {
exists(Javadoc j |
j = this.getDoc().getJavadoc() and
exists(JavadocTag t |
(t = j.getATag("@throws") or t = j.getATag("@exception")) and
t.getChild(0).toString() = e.getName() and
exists(ThrowsTag t |
t = j.getATag() and
t.getExceptionName() = e.getName() and
acceptableTag(t)
)
)
Expand Down
61 changes: 49 additions & 12 deletions java/ql/src/semmle/code/java/Javadoc.qll
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,19 @@ class JavadocParent extends @javadocParent, Top {
/** Gets the number of documentation elements attached to this parent. */
int getNumChild() { result = count(getAChild()) }

/** Gets a documentation element with the specified Javadoc tag name. */
JavadocTag getATag(string name) { result = this.getAChild() and result.getTagName() = name }
/**
* DEPRECATED: Only `Javadoc` can have tag elements; `JavadocTag` (which also extends
* `JavadocParent`) cannot have nested tag elements. Therefore this predicate has been
* moved to `Javadoc`.
*
* Gets a documentation element with the specified Javadoc tag name.
*/
deprecated JavadocTag getATag(string name) {
result = this.getAChild() and result.getTagName() = name
}

/** Gets a text documentation element which is a direct child of this. */
JavadocText getATextElement() { result = this.getAChild() }

/*abstract*/ override string toString() { result = "Javadoc" }
}
Expand All @@ -27,11 +38,19 @@ class Javadoc extends JavadocParent, @javadoc {
/** Gets the number of lines in this Javadoc comment. */
int getNumberOfLines() { result = this.getLocation().getNumberOfCommentLines() }

/** Gets a documentation element with the specified Javadoc tag name. */
override JavadocTag getATag(string name) {
result = this.getATag() and result.getTagName() = name
}

/** Gets a Javadoc tag documentation element. */
JavadocTag getATag() { result = getAChild() }

/** Gets the value of the `@version` tag, if any. */
string getVersion() { result = this.getATag("@version").getChild(0).toString() }
string getVersion() { result = getATag().(VersionTag).getVersion() }

/** Gets the value of the `@author` tag, if any. */
string getAuthor() { result = this.getATag("@author").getChild(0).toString() }
string getAuthor() { result = getATag().(AuthorTag).getAuthorName() }

override string toString() { result = toStringPrefix() + getChild(0) + toStringPostfix() }

Expand Down Expand Up @@ -90,7 +109,7 @@ class JavadocTag extends JavadocElement, JavadocParent, @javadocTag {
override string toString() { result = this.getTagName() }

/** Gets the text associated with this Javadoc tag. */
override string getText() { result = this.getChild(0).toString() }
override string getText() { result = this.getChild(0).(JavadocText).getText() }

override string getAPrimaryQlClass() { result = "JavadocTag" }
}
Expand All @@ -100,37 +119,55 @@ class ParamTag extends JavadocTag {
ParamTag() { this.getTagName() = "@param" }

/** Gets the name of the parameter. */
string getParamName() { result = this.getChild(0).toString() }
string getParamName() { result = this.getChild(0).(JavadocText).getText() }

/** Gets the documentation for the parameter. */
override string getText() { result = this.getChild(1).toString() }
override string getText() { result = this.getChild(1).(JavadocText).getText() }
}

/** A Javadoc `@return` tag. */
class ReturnTag extends JavadocTag {
ReturnTag() { this.getTagName() = "@return" }
}

/** A Javadoc `@throws` or `@exception` tag. */
class ThrowsTag extends JavadocTag {
ThrowsTag() { this.getTagName() = "@throws" or this.getTagName() = "@exception" }
ThrowsTag() { this.getTagName() = ["@throws", "@exception"] }

/** Gets the name of the exception. */
string getExceptionName() { result = this.getChild(0).toString() }
string getExceptionName() { result = this.getChild(0).(JavadocText).getText() }

/** Gets the documentation for the exception. */
override string getText() { result = this.getChild(1).toString() }
override string getText() { result = this.getChild(1).(JavadocText).getText() }
}

/** A Javadoc `@see` tag. */
class SeeTag extends JavadocTag {
SeeTag() { getTagName() = "@see" }

/** Gets the name of the entity referred to. */
string getReference() { result = getChild(0).toString() }
string getReference() { result = getText() }
}

/** A Javadoc `@deprecated` tag. */
class DeprecatedTag extends JavadocTag {
DeprecatedTag() { this.getTagName() = "@deprecated" }
}

/** A Javadoc `@author` tag. */
class AuthorTag extends JavadocTag {
AuthorTag() { this.getTagName() = "@author" }

/** Gets the name of the author. */
string getAuthorName() { result = this.getChild(0).toString() }
string getAuthorName() { result = getText() }
}

/** A Javadoc `@version` tag. */
class VersionTag extends JavadocTag {
VersionTag() { this.getTagName() = "@version" }

/** Gets the version specified by this tag. */
string getVersion() { result = getText() }
}

/** A piece of Javadoc text. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ class LineComment extends Javadoc {
LineComment() { isEolComment(this) }

/** Gets the contents of the given comment, _without_ the preceding comment marker (`//`). */
string getContents() { result = this.getChild(0).toString() }
string getContents() { result = this.getChild(0).(JavadocText).getText() }
}

0 comments on commit 6b86a91

Please sign in to comment.