Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e88bd65
Introduce custom plugin's JavaDoc tags #565
onewhl Jul 22, 2022
43c4cf0
Render UtBot custom JavaDoc tags correctly #565
onewhl Jul 25, 2022
760594f
Add an option to generate summaries using custom JavaDoc tags #565
onewhl Jul 26, 2022
050550f
Fill value of utbot.iterates tag #565
onewhl Jul 27, 2022
ca86976
Collect info about Invoke, Iterate, and Return sections #565
onewhl Jul 28, 2022
d77e739
Review fixes
onewhl Aug 1, 2022
6ae1157
Add unit tests for summaries with custom JavaDoc tags #565
onewhl Aug 2, 2022
100e3df
Fix after rebasing
onewhl Aug 3, 2022
8d4063b
Add summary tests for MinStack #565
onewhl Aug 3, 2022
6d01afe
Fix broken tests
onewhl Aug 4, 2022
d03ad76
Add <pre> tag only in case when custom javadoc tags are not used
onewhl Aug 4, 2022
74c5822
Use a full exception name instead of simple name to build inline link…
onewhl Aug 6, 2022
7e4aaf9
Minor refactoring
onewhl Aug 6, 2022
92eb15d
Minor refactoring: avoid code duplication
onewhl Aug 6, 2022
cf9b60f
Add DocCustomTagStatement and CgCustomTagStatement
onewhl Aug 6, 2022
9c14eb0
Refactored code to avoid code duplication
onewhl Aug 6, 2022
6dce850
Fix tests: add full name for classes
onewhl Aug 6, 2022
7800d33
Add JUnit extension to control USE_CUSTOM_TAGS setting
onewhl Aug 6, 2022
d003962
Move useCustomJavaDocTags to UtSettings, make useFuzzing true
onewhl Aug 7, 2022
f8e6764
Remove unused import and fix broken tests
onewhl Aug 7, 2022
321bf0d
Fix broken tests
onewhl Aug 8, 2022
a52fb20
Add comments, remove unused method
onewhl Aug 8, 2022
83f4e71
Review fixes: fixed formatting, removed redundant types
onewhl Aug 9, 2022
abe7ca6
Review fixes: fixed formatting, removed useless overriding methods
onewhl Aug 15, 2022
475cae5
Review fixes: extracted method, polished code
onewhl Aug 15, 2022
99b06ad
fix after rebasing
onewhl Aug 17, 2022
21a7035
fix after rebasing
onewhl Aug 23, 2022
4951b6f
review fixes
onewhl Aug 23, 2022
bd616a9
fix rendering after updating to idea 2022.1. now we don't need to gen…
onewhl Aug 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add an option to generate summaries using custom JavaDoc tags #565
  • Loading branch information
onewhl committed Aug 24, 2022
commit 760594ff5cc05c1224550c02ff92adba27f88e19
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ object UtSettings {
/**
* Set to true to start fuzzing if symbolic execution haven't return anything
*/
var useFuzzing: Boolean by getBooleanProperty(true)
var useFuzzing: Boolean by getBooleanProperty(false)
Comment thread
onewhl marked this conversation as resolved.
Outdated

/**
* Set the total attempts to improve coverage by fuzzer.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,7 @@ internal abstract class CgAbstractRenderer(val context: CgContext, val printer:
}
override fun visit(element: CgDocPreTagStatement) {
if (element.content.all { it.isEmpty() }) return

println("<pre>")
Comment thread
onewhl marked this conversation as resolved.
for (stmt in element.content) stmt.accept(this)
println("</pre>")
}
override fun visit(element: CgDocCodeStmt) {
if (element.isEmpty()) return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class UtCustomJavaDocTagProvider : CustomJavadocTagProvider {
UtCustomTag.ActualResult,
UtCustomTag.Executes,
UtCustomTag.Invokes,
UtCustomTag.Iterates,
UtCustomTag.ReturnsFrom,
UtCustomTag.ThrowsException,
)
Expand All @@ -44,6 +45,7 @@ class UtCustomJavaDocTagProvider : CustomJavadocTagProvider {
object ActualResult : UtCustomTag("utbot.actualResult", "Actual result")
object Executes : UtCustomTag("utbot.executes", "Executes")
object Invokes : UtCustomTag("utbot.invokes", "Invokes")
object Iterates : UtCustomTag("utbot.iterates", "Iterates")
object ReturnsFrom : UtCustomTag("utbot.returnsFrom", "Returns from")
object ThrowsException : UtCustomTag("utbot.throwsException", "Throws exception")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.utbot.framework.UtSettings
import org.utbot.framework.plugin.api.UtClusterInfo
import org.utbot.framework.plugin.api.UtSymbolicExecution
import org.utbot.framework.plugin.api.UtExecutionCluster
import org.utbot.framework.plugin.api.UtExecutionCreator
import org.utbot.framework.plugin.api.UtMethodTestSet
import org.utbot.instrumentation.instrumentation.instrumenter.Instrumenter
import org.utbot.summary.SummarySentenceConstants.NEW_LINE
Expand All @@ -28,6 +29,8 @@ import org.utbot.fuzzer.FuzzedValue
import org.utbot.fuzzer.UtFuzzedExecution
import org.utbot.summary.fuzzer.names.MethodBasedNameSuggester
import org.utbot.summary.fuzzer.names.ModelBasedNameSuggester
import org.utbot.summary.UtSummarySettings.USE_CUSTOM_JAVADOC_TAGS
import org.utbot.summary.comment.CustomJavaDocCommentBuilder
import soot.SootMethod

private val logger = KotlinLogging.logger {}
Expand Down Expand Up @@ -154,7 +157,10 @@ class Summarization(val sourceFile: File?, val invokeDescriptions: List<InvokeDe
}

for (traceTags in clusterTraceTags.traceTags) {
if (GENERATE_COMMENTS) {
if (GENERATE_COMMENTS && USE_CUSTOM_JAVADOC_TAGS) {
traceTags.execution.summary =
CustomJavaDocCommentBuilder(traceTags, sootToAST).buildDocStatements(methodUnderTest)
} else if (GENERATE_COMMENTS) {
traceTags.execution.summary =
SimpleCommentBuilder(traceTags, sootToAST).buildDocStmts(methodUnderTest)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ object UtSummarySettings {
*/
var GENERATE_CLUSTER_COMMENTS = true

/**
* Generate summaries using plugin's custom JavaDoc tags.
*/
var USE_CUSTOM_JAVADOC_TAGS = true

/**
* If True names for tests will be generated
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.utbot.summary.comment

/**
* Represents a set of plugin's custom JavaDoc tags.
*/
data class CustomJavaDocComment(
val classUnderTest: String,
val methodUnderTest: String,
val expectedResult: String?,
val actualResult: String?,
var executes: String?,
var invokes: String?,
var iterates: String?,
var returnsFrom: String?,
val throwsException: String?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package org.utbot.summary.comment

import org.utbot.framework.plugin.api.DocPreTagStatement
import org.utbot.framework.plugin.api.DocRegularStmt
import org.utbot.framework.plugin.api.DocStatement
import org.utbot.framework.plugin.api.exceptionOrNull
import org.utbot.summary.ast.JimpleToASTMap
import org.utbot.summary.tag.TraceTagWithoutExecution
import soot.SootMethod

//TODO: polish code
class CustomJavaDocCommentBuilder(
Comment thread
onewhl marked this conversation as resolved.
traceTag: TraceTagWithoutExecution,
sootToAST: MutableMap<SootMethod, JimpleToASTMap>
) : SimpleCommentBuilder(traceTag, sootToAST, stringTemplates = StringsTemplatesPlural()) {

/**
* Collects statements for final JavaDoc comment.
*/
fun buildDocStatements(method: SootMethod): List<DocStatement> {
val comment: CustomJavaDocComment = buildCustomJavaDocComment(method)
Comment thread
onewhl marked this conversation as resolved.
Outdated
val docStatementList = mutableListOf<DocStatement>()

docStatementList += DocRegularStmt("@utbot.classUnderTest ${comment.classUnderTest}\n")
docStatementList += DocRegularStmt("@utbot.methodUnderTest ${comment.methodUnderTest}\n")
if (comment.expectedResult != null)
docStatementList += DocRegularStmt("@utbot.expectedResult ${comment.expectedResult}\n")
if (comment.actualResult != null)
docStatementList += DocRegularStmt("@utbot.actualResult ${comment.actualResult}\n")
if (comment.executes != null)
docStatementList += DocRegularStmt("@utbot.executes ${comment.executes}\n")
if (comment.invokes != null)
docStatementList += DocRegularStmt("@utbot.invokes ${comment.invokes}\n")
if (comment.iterates != null)
docStatementList += DocRegularStmt("@utbot.iterates ${comment.iterates}\n")
if (comment.returnsFrom != null)
docStatementList += DocRegularStmt("@utbot.returnsFrom ${comment.returnsFrom}\n")
if (comment.throwsException != null)
docStatementList += DocRegularStmt("@utbot.throwsException ${comment.throwsException}")

return listOf<DocStatement>(DocPreTagStatement(docStatementList))
}

private fun buildCustomJavaDocComment(currentMethod: SootMethod): CustomJavaDocComment {
val methodReference =
getMethodReference(currentMethod.declaringClass.name, currentMethod.name, currentMethod.parameterTypes)
val classReference = getClassReference(currentMethod.declaringClass.javaStyleName)

val thrownException = traceTag.result.exceptionOrNull()
val exceptionThrow: String? = if (thrownException == null) {
traceTag.result.exceptionOrNull()?.let { it::class.qualifiedName }
Comment thread
amandelpie marked this conversation as resolved.
} else {
val exceptionName = thrownException.javaClass.simpleName
val reason = findExceptionReason(currentMethod, thrownException)
"{@link $exceptionName} $reason"
}

val customJavaDocComment = CustomJavaDocComment(
classUnderTest = classReference,
methodUnderTest = methodReference,
expectedResult = null,
actualResult = null,
executes = null,
invokes = null,
Comment thread
onewhl marked this conversation as resolved.
Outdated
iterates = null,
returnsFrom = null,
throwsException = exceptionThrow
)

val rootSentenceBlock = SimpleSentenceBlock(stringTemplates = stringTemplates)

buildSentenceBlock(traceTag.rootStatementTag, rootSentenceBlock, currentMethod)

for (stmtDescription: StmtDescription in rootSentenceBlock.stmtTexts) {
when (stmtDescription.stmtType.name) {
"Invoke" -> {
val info = stmtDescription.description
customJavaDocComment.invokes = "{@code $info}"
}
"Return" -> {
val info = stmtDescription.description
customJavaDocComment.returnsFrom = "{@code $info}"
}
"Condition" -> {
val info = stmtDescription.description
customJavaDocComment.executes = "{@code $info}"
}
}
}

return customJavaDocComment
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class SimpleClusterCommentBuilder(
* Builds sentence blocks as parent one,
* but ignores few types of statementTag that are considered in SimpleCommentBuilder
*/
private fun buildSentenceBlock(
override fun buildSentenceBlock(
statementTag: StatementTag?,
sentenceBlock: SimpleSentenceBlock,
currentMethod: SootMethod
Expand Down Expand Up @@ -93,7 +93,7 @@ class SimpleClusterCommentBuilder(
sentenceInvoke.squashStmtText()
if (!sentenceInvoke.isEmpty()) {
sentenceBlock.invokeSentenceBlock =
Pair(invokeDescription(className, methodName, methodParameterTypes), sentenceInvoke)
Pair(getMethodReference(className, methodName, methodParameterTypes), sentenceInvoke)
createNextBlock = true
invokeRegistered = true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,11 @@ open class SimpleCommentBuilder(
}

/**
* Creates List<DocStatement> from SimpleSentenceBlock
* Creates List<[DocStatement]> from [SimpleSentenceBlock].
*/
open fun buildDocStmts(currentMethod: SootMethod): List<DocStatement> {
val root = SimpleSentenceBlock(stringTemplates = stringTemplates)

val thrownException = traceTag.result.exceptionOrNull()
if (thrownException == null) {
root.exceptionThrow = traceTag.result.exceptionOrNull()?.let { it::class.qualifiedName }
} else {
val exceptionName = thrownException.javaClass.simpleName
val reason = findExceptionReason(currentMethod, thrownException)
root.exceptionThrow = "$exceptionName $reason"
}
skippedIterations()
buildSentenceBlock(traceTag.rootStatementTag, root, currentMethod)
val docStmts = toDocStmts(root)
val sentenceBlock = buildSentenceBlock(currentMethod)
val docStmts = toDocStmts(sentenceBlock)

if (docStmts.isEmpty()) {
return listOf(DocRegularStmt(genWarnNotification())) //TODO SAT-1310
Expand All @@ -88,6 +77,22 @@ open class SimpleCommentBuilder(
return listOf<DocStatement>(DocPreTagStatement(docStmts))
}

private fun buildSentenceBlock(currentMethod: SootMethod): SimpleSentenceBlock {
val rootSentenceBlock = SimpleSentenceBlock(stringTemplates = stringTemplates)

val thrownException = traceTag.result.exceptionOrNull()
if (thrownException == null) {
rootSentenceBlock.exceptionThrow = traceTag.result.exceptionOrNull()?.let { it::class.qualifiedName }
} else {
val exceptionName = thrownException.javaClass.simpleName
val reason = findExceptionReason(currentMethod, thrownException)
rootSentenceBlock.exceptionThrow = "$exceptionName $reason"
}
skippedIterations()
buildSentenceBlock(traceTag.rootStatementTag, rootSentenceBlock, currentMethod)
return rootSentenceBlock
}

Comment thread
onewhl marked this conversation as resolved.
protected fun genWarnNotification(): String = " " //why is it empty?

/**
Expand All @@ -114,7 +119,7 @@ open class SimpleCommentBuilder(
return stmts
}

private fun findExceptionReason(currentMethod: SootMethod, thrownException: Throwable): String {
fun findExceptionReason(currentMethod: SootMethod, thrownException: Throwable): String {
val path = traceTag.path
if (path.isEmpty()) {
if (thrownException is ConcreteExecutionFailureException) {
Expand Down Expand Up @@ -161,7 +166,7 @@ open class SimpleCommentBuilder(
/**
* Sentence blocks are built based on unique and partly unique statement tags.
*/
private fun buildSentenceBlock(
open fun buildSentenceBlock(
statementTag: StatementTag?,
sentenceBlock: SimpleSentenceBlock,
currentMethod: SootMethod
Expand Down Expand Up @@ -191,7 +196,7 @@ open class SimpleCommentBuilder(
sentenceInvoke.squashStmtText()
if (!sentenceInvoke.isEmpty()) {
sentenceBlock.invokeSentenceBlock =
Pair(invokeDescription(className, methodName, methodParameterTypes), sentenceInvoke)
Pair(getMethodReference(className, methodName, methodParameterTypes), sentenceInvoke)
createNextBlock = true
invokeRegistered = true
}
Expand Down Expand Up @@ -317,7 +322,7 @@ open class SimpleCommentBuilder(
sentenceBlock.stmtTexts.add(
StmtDescription(
StmtType.Invoke,
invokeDescription(className, methodName, methodParameterTypes),
getMethodReference(className, methodName, methodParameterTypes),
frequency
)
)
Expand Down Expand Up @@ -349,7 +354,7 @@ open class SimpleCommentBuilder(
* In case when an enclosing class in nested, we need to replace '$' with '.'
* to render the reference.
*/
fun invokeDescription(className: String, methodName: String, methodParameterTypes: List<Type>): String {
protected fun getMethodReference(className: String, methodName: String, methodParameterTypes: List<Type>): String {
val prettyClassName: String = className.replace("$", ".")

return if (methodParameterTypes.isEmpty()) {
Expand All @@ -360,6 +365,14 @@ open class SimpleCommentBuilder(
}
}

/**
* Returns a reference to the class.
* Replaces '$' with '.' in case a class is nested.
*/
fun getClassReference(fullClasName: String): String {
return "{@link ${fullClasName.replace("$", ".")}}"
}

protected fun buildIterationsBlock(
iterations: List<StatementTag>,
activatedStep: Step,
Expand Down