Skip to content

Commit 6b86a91

Browse files
committed
Java: Replace usage of toString() for Javadoc queries; add more Javadoc tags
1 parent b2c0259 commit 6b86a91

File tree

4 files changed

+62
-26
lines changed

4 files changed

+62
-26
lines changed

java/ql/src/Advisory/Deprecated Code/AvoidDeprecatedCallableAccess.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import java
1515

1616
private predicate isDeprecatedCallable(Callable c) {
1717
c.getAnAnnotation() instanceof DeprecatedAnnotation or
18-
exists(c.getDoc().getJavadoc().getATag("@deprecated"))
18+
exists(c.getDoc().getJavadoc().getATag().(DeprecatedTag))
1919
}
2020

2121
from Call ca, Callable c

java/ql/src/Advisory/Documentation/JavadocCommon.qll

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,19 @@ import java
55
/** Holds if the given `Javadoc` contains a minimum of a few characters of text. */
66
private predicate acceptableDocText(Javadoc j) {
77
// Require minimum combined length of all non-tag elements.
8-
sum(JavadocElement e, int toSum |
9-
e = j.getAChild() and
10-
not e = j.getATag(_) and
11-
toSum = e.toString().length()
8+
sum(JavadocText t, int toSum |
9+
t = j.getATextElement() and
10+
toSum = t.getText().length()
1211
|
1312
toSum
1413
) >= 5
1514
}
1615

1716
/** Holds if the given `JavadocTag` contains a minimum of a few characters of text. */
1817
private predicate acceptableTag(JavadocTag t) {
19-
sum(JavadocElement e, int toSum |
20-
e = t.getAChild() and
21-
toSum = e.toString().length()
18+
sum(JavadocText text, int toSum |
19+
text = t.getATextElement() and
20+
toSum = text.getText().length()
2221
|
2322
toSum
2423
) >= 5
@@ -72,7 +71,7 @@ class DocuParam extends Parameter {
7271
/** Holds if this parameter has a non-trivial `@param` tag. */
7372
predicate hasAcceptableParamTag() {
7473
exists(ParamTag t |
75-
t = this.getCallable().getDoc().getJavadoc().getATag("@param") and
74+
t = this.getCallable().getDoc().getJavadoc().getATag() and
7675
t.getParamName() = this.getName() and
7776
acceptableTag(t)
7877
)
@@ -90,7 +89,7 @@ class DocuReturn extends DocuCallable {
9089

9190
/** Holds if this callable's `Javadoc` has a non-trivial `@return` tag. */
9291
predicate hasAcceptableReturnTag() {
93-
acceptableTag(this.getDoc().getJavadoc().getATag("@return"))
92+
acceptableTag(this.getDoc().getJavadoc().getATag().(ReturnTag))
9493
}
9594
}
9695

@@ -111,9 +110,9 @@ class DocuThrows extends DocuCallable {
111110
predicate hasAcceptableThrowsTag(Exception e) {
112111
exists(Javadoc j |
113112
j = this.getDoc().getJavadoc() and
114-
exists(JavadocTag t |
115-
(t = j.getATag("@throws") or t = j.getATag("@exception")) and
116-
t.getChild(0).toString() = e.getName() and
113+
exists(ThrowsTag t |
114+
t = j.getATag() and
115+
t.getExceptionName() = e.getName() and
117116
acceptableTag(t)
118117
)
119118
)

java/ql/src/semmle/code/java/Javadoc.qll

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,19 @@ class JavadocParent extends @javadocParent, Top {
1616
/** Gets the number of documentation elements attached to this parent. */
1717
int getNumChild() { result = count(getAChild()) }
1818

19-
/** Gets a documentation element with the specified Javadoc tag name. */
20-
JavadocTag getATag(string name) { result = this.getAChild() and result.getTagName() = name }
19+
/**
20+
* DEPRECATED: Only `Javadoc` can have tag elements; `JavadocTag` (which also extends
21+
* `JavadocParent`) cannot have nested tag elements. Therefore this predicate has been
22+
* moved to `Javadoc`.
23+
*
24+
* Gets a documentation element with the specified Javadoc tag name.
25+
*/
26+
deprecated JavadocTag getATag(string name) {
27+
result = this.getAChild() and result.getTagName() = name
28+
}
29+
30+
/** Gets a text documentation element which is a direct child of this. */
31+
JavadocText getATextElement() { result = this.getAChild() }
2132

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

41+
/** Gets a documentation element with the specified Javadoc tag name. */
42+
override JavadocTag getATag(string name) {
43+
result = this.getATag() and result.getTagName() = name
44+
}
45+
46+
/** Gets a Javadoc tag documentation element. */
47+
JavadocTag getATag() { result = getAChild() }
48+
3049
/** Gets the value of the `@version` tag, if any. */
31-
string getVersion() { result = this.getATag("@version").getChild(0).toString() }
50+
string getVersion() { result = getATag().(VersionTag).getVersion() }
3251

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

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

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

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

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

102121
/** Gets the name of the parameter. */
103-
string getParamName() { result = this.getChild(0).toString() }
122+
string getParamName() { result = this.getChild(0).(JavadocText).getText() }
104123

105124
/** Gets the documentation for the parameter. */
106-
override string getText() { result = this.getChild(1).toString() }
125+
override string getText() { result = this.getChild(1).(JavadocText).getText() }
126+
}
127+
128+
/** A Javadoc `@return` tag. */
129+
class ReturnTag extends JavadocTag {
130+
ReturnTag() { this.getTagName() = "@return" }
107131
}
108132

109133
/** A Javadoc `@throws` or `@exception` tag. */
110134
class ThrowsTag extends JavadocTag {
111-
ThrowsTag() { this.getTagName() = "@throws" or this.getTagName() = "@exception" }
135+
ThrowsTag() { this.getTagName() = ["@throws", "@exception"] }
112136

113137
/** Gets the name of the exception. */
114-
string getExceptionName() { result = this.getChild(0).toString() }
138+
string getExceptionName() { result = this.getChild(0).(JavadocText).getText() }
115139

116140
/** Gets the documentation for the exception. */
117-
override string getText() { result = this.getChild(1).toString() }
141+
override string getText() { result = this.getChild(1).(JavadocText).getText() }
118142
}
119143

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

124148
/** Gets the name of the entity referred to. */
125-
string getReference() { result = getChild(0).toString() }
149+
string getReference() { result = getText() }
150+
}
151+
152+
/** A Javadoc `@deprecated` tag. */
153+
class DeprecatedTag extends JavadocTag {
154+
DeprecatedTag() { this.getTagName() = "@deprecated" }
126155
}
127156

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

132161
/** Gets the name of the author. */
133-
string getAuthorName() { result = this.getChild(0).toString() }
162+
string getAuthorName() { result = getText() }
163+
}
164+
165+
/** A Javadoc `@version` tag. */
166+
class VersionTag extends JavadocTag {
167+
VersionTag() { this.getTagName() = "@version" }
168+
169+
/** Gets the version specified by this tag. */
170+
string getVersion() { result = getText() }
134171
}
135172

136173
/** A piece of Javadoc text. */

java/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ class LineComment extends Javadoc {
88
LineComment() { isEolComment(this) }
99

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

0 commit comments

Comments
 (0)