Skip to content

Commit a3538da

Browse files
committed
Fix some issues found by review
1 parent 00372ae commit a3538da

File tree

10 files changed

+47
-30
lines changed

10 files changed

+47
-30
lines changed

utbot-core/src/main/kotlin/org/utbot/common/KClassUtil.kt

+1-6
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,8 @@ package org.utbot.common
33
import java.lang.reflect.InvocationTargetException
44
import java.lang.reflect.Method
55

6-
val Class<*>.nameOfPackage: String get() = `package`?.name?:""
7-
86
fun Method.invokeCatching(obj: Any?, args: List<Any?>) = try {
97
Result.success(invoke(obj, *args.toTypedArray()))
108
} catch (e: InvocationTargetException) {
119
Result.failure<Nothing>(e.targetException)
12-
}
13-
14-
val Class<*>.allNestedClasses: List<Class<*>>
15-
get() = listOf(this) + this.declaredClasses.flatMap { it.allNestedClasses.toList() }
10+
}

utbot-core/src/main/kotlin/org/utbot/common/ReflectionUtil.kt

+7-1
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,10 @@ val Class<*>.isFinal
111111
get() = Modifier.isFinal(modifiers)
112112

113113
val Class<*>.isProtected
114-
get() = Modifier.isProtected(modifiers)
114+
get() = Modifier.isProtected(modifiers)
115+
116+
val Class<*>.nameOfPackage: String
117+
get() = `package`?.name?:""
118+
119+
val Class<*>.allNestedClasses: List<Class<*>>
120+
get() = listOf(this) + this.declaredClasses.flatMap { it.allNestedClasses }

utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/IdUtil.kt

+3
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,9 @@ val MethodId.method: Method
441441
?: error("Can't find method $signature in ${declaringClass.name}")
442442
}
443443

444+
/**
445+
* See [KCallable.extensionReceiverParameter] for more details
446+
*/
444447
val MethodId.extensionReceiverParameterIndex: Int?
445448
get() = this.method.kotlinFunction?.extensionReceiverParameter?.index
446449

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgCallableAccessManager.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,9 @@ internal class CgCallableAccessManagerImpl(val context: CgContext) : CgCallableA
205205
*/
206206
private fun CgMethodCall.takeCallerFromArgumentsIfNeeded(): CgMethodCall {
207207
if (codegenLanguage == CodegenLanguage.KOTLIN) {
208-
// TODO: reflection calls for util and some of mockito methods produce exceptions => currently runCatching is needed
209-
// (but their reflection may be supported, alternatively maybe get rid of reflection somehow here)
210-
runCatching {
208+
// TODO: reflection calls for util and some of mockito methods produce exceptions => here we suppose that
209+
// methods for BuiltinClasses are not extensions by default (which should be true as long as we suppose them to be java methods)
210+
if (executableId.classId !is BuiltinClassId) {
211211
executableId.extensionReceiverParameterIndex?.let { receiverIndex ->
212212
require(caller == null) { "${executableId.humanReadableName} is an extension function but it already has a non-static caller provided" }
213213
val args = arguments.toMutableList()

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/visitor/CgAbstractRenderer.kt

+6-3
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,13 @@ internal abstract class CgAbstractRenderer(
131131
}
132132
}
133133

134-
protected abstract val ClassId.shouldBeOmittedWhenUsedAsCaller: Boolean
134+
/**
135+
* Returns true if one can call methods of this class without specifying a caller (for example if ClassId represents this instance)
136+
*/
137+
protected abstract val ClassId.methodsAreAccessibleAsTopLevel: Boolean
135138

136139
private val MethodId.accessibleByName: Boolean
137-
get() = (context.shouldOptimizeImports && this in context.importedStaticMethods) || classId == context.generatedClass || classId.shouldBeOmittedWhenUsedAsCaller
140+
get() = (context.shouldOptimizeImports && this in context.importedStaticMethods) || classId.methodsAreAccessibleAsTopLevel
138141

139142
override fun visit(element: CgElement) {
140143
val error =
@@ -656,7 +659,7 @@ internal abstract class CgAbstractRenderer(
656659
}
657660

658661
override fun visit(element: CgStaticFieldAccess) {
659-
if (!element.declaringClass.shouldBeOmittedWhenUsedAsCaller) {
662+
if (!element.declaringClass.methodsAreAccessibleAsTopLevel) {
660663
print(element.declaringClass.asString())
661664
print(".")
662665
}

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/visitor/CgJavaRenderer.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ internal class CgJavaRenderer(context: CgRendererContext, printer: CgPrinter = C
6060

6161
override val langPackage: String = "java.lang"
6262

63-
override val ClassId.shouldBeOmittedWhenUsedAsCaller: Boolean
64-
get() = false
63+
override val ClassId.methodsAreAccessibleAsTopLevel: Boolean
64+
get() = this == context.generatedClass
6565

6666
override fun visit(element: AbstractCgClass<*>) {
6767
for (annotation in element.annotations) {

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/visitor/CgKotlinRenderer.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ internal class CgKotlinRenderer(context: CgRendererContext, printer: CgPrinter =
7373

7474
override val langPackage: String = "kotlin"
7575

76-
override val ClassId.shouldBeOmittedWhenUsedAsCaller: Boolean
77-
get() = isKotlinFile
76+
override val ClassId.methodsAreAccessibleAsTopLevel: Boolean
77+
get() = (this == context.generatedClass) || isKotlinFile
7878

7979
override fun visit(element: AbstractCgClass<*>) {
8080
for (annotation in element.annotations) {

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/actions/GenerateTestsAction.kt

+3-10
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ class GenerateTestsAction : AnAction(), UpdateInBackground {
6666

6767
val psiElementHandler = PsiElementHandler.makePsiElementHandler(file)
6868

69-
// When in Kotlin file, we should propose top-level functions for testing
70-
if (psiElementHandler.isCreateTestActionAvailable(element) || file is KtFile) {
69+
if (psiElementHandler.isCreateTestActionAvailable(element)) {
7170
val srcClass = psiElementHandler.containingClass(element) ?: return null
7271
val srcSourceRoot = srcClass.getSourceRoot() ?: return null
7372
val srcMembers = srcClass.extractFirstLevelMembers(false)
@@ -221,7 +220,7 @@ class GenerateTestsAction : AnAction(), UpdateInBackground {
221220
}
222221

223222
private fun getAllClasses(directory: PsiDirectory): Set<PsiClass> {
224-
val allClasses = directory.files.flatMap { getClassesFromFile(it) }.toMutableSet()
223+
val allClasses = directory.files.flatMap { PsiElementHandler.makePsiElementHandler(it).getClassesFromFile(it) }.toMutableSet()
225224
for (subDir in directory.subdirectories) allClasses += getAllClasses(subDir)
226225
return allClasses
227226
}
@@ -234,16 +233,10 @@ class GenerateTestsAction : AnAction(), UpdateInBackground {
234233
if (!dirsArePackages) {
235234
return emptySet()
236235
}
237-
val allClasses = psiFiles.flatMap { getClassesFromFile(it) }.toMutableSet()
236+
val allClasses = psiFiles.flatMap { PsiElementHandler.makePsiElementHandler(it).getClassesFromFile(it) }.toMutableSet()
238237
allClasses.addAll(psiFiles.mapNotNull { (it as? KtFile)?.findFacadeClass() })
239238
for (psiDir in psiDirectories) allClasses += getAllClasses(psiDir)
240239

241240
return allClasses
242241
}
243-
244-
private fun getClassesFromFile(psiFile: PsiFile): List<PsiClass> {
245-
val psiElementHandler = PsiElementHandler.makePsiElementHandler(psiFile)
246-
return PsiTreeUtil.getChildrenOfTypeAsList(psiFile, psiElementHandler.classClass)
247-
.map { psiElementHandler.toPsi(it, PsiClass::class.java) }
248-
}
249242
}

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/utils/KotlinPsiElementHandler.kt

+11-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package org.utbot.intellij.plugin.ui.utils
22

33
import com.intellij.psi.PsiClass
44
import com.intellij.psi.PsiElement
5+
import com.intellij.psi.PsiFile
56
import com.intellij.psi.util.findParentOfType
67
import org.jetbrains.kotlin.asJava.findFacadeClass
78
import org.jetbrains.kotlin.idea.testIntegration.KotlinCreateTestIntention
@@ -11,7 +12,6 @@ import org.jetbrains.kotlin.psi.KtFile
1112
import org.jetbrains.kotlin.psi.KtNamedDeclaration
1213
import org.jetbrains.kotlin.psi.KtNamedFunction
1314
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
14-
import org.jetbrains.kotlin.toKtPsiSourceElement
1515
import org.jetbrains.uast.toUElement
1616

1717
class KotlinPsiElementHandler(
@@ -27,8 +27,16 @@ class KotlinPsiElementHandler(
2727
return element.toUElement()?.javaPsi as? T ?: error("Could not cast $element to $clazz")
2828
}
2929

30-
override fun isCreateTestActionAvailable(element: PsiElement): Boolean =
31-
getTarget(element)?.let { KotlinCreateTestIntention().applicabilityRange(it) != null } ?: false
30+
override fun getClassesFromFile(psiFile: PsiFile): List<PsiClass> {
31+
return listOfNotNull((psiFile as? KtFile)?.findFacadeClass()) + super.getClassesFromFile(psiFile)
32+
}
33+
34+
override fun isCreateTestActionAvailable(element: PsiElement): Boolean {
35+
getTarget(element)?.let {
36+
return KotlinCreateTestIntention().applicabilityRange(it) != null
37+
}
38+
return (element.containingFile as? KtFile)?.findFacadeClass() != null
39+
}
3240

3341
private fun getTarget(element: PsiElement?): KtNamedDeclaration? =
3442
element?.parentsWithSelf

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/ui/utils/PsiElementHandler.kt

+9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.utbot.intellij.plugin.ui.utils
33
import com.intellij.psi.PsiClass
44
import com.intellij.psi.PsiElement
55
import com.intellij.psi.PsiFile
6+
import com.intellij.psi.util.PsiTreeUtil
67
import org.jetbrains.kotlin.psi.KtFile
78

89
/**
@@ -36,6 +37,14 @@ interface PsiElementHandler {
3637
*/
3738
fun <T> toPsi(element: PsiElement, clazz: Class<T>): T
3839

40+
/**
41+
* Returns all classes that are declared in the [psiFile]
42+
*/
43+
fun getClassesFromFile(psiFile: PsiFile): List<PsiClass> {
44+
return PsiTreeUtil.getChildrenOfTypeAsList(psiFile, classClass)
45+
.map { toPsi(it, PsiClass::class.java) }
46+
}
47+
3948
/**
4049
* Get java class of the Class in the corresponding syntax tree (PsiClass, KtClass, e.t.c).
4150
*/

0 commit comments

Comments
 (0)