Skip to content

Commit

Permalink
Fix some issues found by review
Browse files Browse the repository at this point in the history
  • Loading branch information
volivan239 committed Oct 25, 2022
1 parent 00372ae commit a3538da
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 30 deletions.
7 changes: 1 addition & 6 deletions utbot-core/src/main/kotlin/org/utbot/common/KClassUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@ package org.utbot.common
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method

val Class<*>.nameOfPackage: String get() = `package`?.name?:""

fun Method.invokeCatching(obj: Any?, args: List<Any?>) = try {
Result.success(invoke(obj, *args.toTypedArray()))
} catch (e: InvocationTargetException) {
Result.failure<Nothing>(e.targetException)
}

val Class<*>.allNestedClasses: List<Class<*>>
get() = listOf(this) + this.declaredClasses.flatMap { it.allNestedClasses.toList() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,10 @@ val Class<*>.isFinal
get() = Modifier.isFinal(modifiers)

val Class<*>.isProtected
get() = Modifier.isProtected(modifiers)
get() = Modifier.isProtected(modifiers)

val Class<*>.nameOfPackage: String
get() = `package`?.name?:""

val Class<*>.allNestedClasses: List<Class<*>>
get() = listOf(this) + this.declaredClasses.flatMap { it.allNestedClasses }
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,9 @@ val MethodId.method: Method
?: error("Can't find method $signature in ${declaringClass.name}")
}

/**
* See [KCallable.extensionReceiverParameter] for more details
*/
val MethodId.extensionReceiverParameterIndex: Int?
get() = this.method.kotlinFunction?.extensionReceiverParameter?.index

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

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

private val MethodId.accessibleByName: Boolean
get() = (context.shouldOptimizeImports && this in context.importedStaticMethods) || classId == context.generatedClass || classId.shouldBeOmittedWhenUsedAsCaller
get() = (context.shouldOptimizeImports && this in context.importedStaticMethods) || classId.methodsAreAccessibleAsTopLevel

override fun visit(element: CgElement) {
val error =
Expand Down Expand Up @@ -656,7 +659,7 @@ internal abstract class CgAbstractRenderer(
}

override fun visit(element: CgStaticFieldAccess) {
if (!element.declaringClass.shouldBeOmittedWhenUsedAsCaller) {
if (!element.declaringClass.methodsAreAccessibleAsTopLevel) {
print(element.declaringClass.asString())
print(".")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ internal class CgJavaRenderer(context: CgRendererContext, printer: CgPrinter = C

override val langPackage: String = "java.lang"

override val ClassId.shouldBeOmittedWhenUsedAsCaller: Boolean
get() = false
override val ClassId.methodsAreAccessibleAsTopLevel: Boolean
get() = this == context.generatedClass

override fun visit(element: AbstractCgClass<*>) {
for (annotation in element.annotations) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ internal class CgKotlinRenderer(context: CgRendererContext, printer: CgPrinter =

override val langPackage: String = "kotlin"

override val ClassId.shouldBeOmittedWhenUsedAsCaller: Boolean
get() = isKotlinFile
override val ClassId.methodsAreAccessibleAsTopLevel: Boolean
get() = (this == context.generatedClass) || isKotlinFile

override fun visit(element: AbstractCgClass<*>) {
for (annotation in element.annotations) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ class GenerateTestsAction : AnAction(), UpdateInBackground {

val psiElementHandler = PsiElementHandler.makePsiElementHandler(file)

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

private fun getAllClasses(directory: PsiDirectory): Set<PsiClass> {
val allClasses = directory.files.flatMap { getClassesFromFile(it) }.toMutableSet()
val allClasses = directory.files.flatMap { PsiElementHandler.makePsiElementHandler(it).getClassesFromFile(it) }.toMutableSet()
for (subDir in directory.subdirectories) allClasses += getAllClasses(subDir)
return allClasses
}
Expand All @@ -234,16 +233,10 @@ class GenerateTestsAction : AnAction(), UpdateInBackground {
if (!dirsArePackages) {
return emptySet()
}
val allClasses = psiFiles.flatMap { getClassesFromFile(it) }.toMutableSet()
val allClasses = psiFiles.flatMap { PsiElementHandler.makePsiElementHandler(it).getClassesFromFile(it) }.toMutableSet()
allClasses.addAll(psiFiles.mapNotNull { (it as? KtFile)?.findFacadeClass() })
for (psiDir in psiDirectories) allClasses += getAllClasses(psiDir)

return allClasses
}

private fun getClassesFromFile(psiFile: PsiFile): List<PsiClass> {
val psiElementHandler = PsiElementHandler.makePsiElementHandler(psiFile)
return PsiTreeUtil.getChildrenOfTypeAsList(psiFile, psiElementHandler.classClass)
.map { psiElementHandler.toPsi(it, PsiClass::class.java) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.utbot.intellij.plugin.ui.utils

import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.util.findParentOfType
import org.jetbrains.kotlin.asJava.findFacadeClass
import org.jetbrains.kotlin.idea.testIntegration.KotlinCreateTestIntention
Expand All @@ -11,7 +12,6 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.toKtPsiSourceElement
import org.jetbrains.uast.toUElement

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

override fun isCreateTestActionAvailable(element: PsiElement): Boolean =
getTarget(element)?.let { KotlinCreateTestIntention().applicabilityRange(it) != null } ?: false
override fun getClassesFromFile(psiFile: PsiFile): List<PsiClass> {
return listOfNotNull((psiFile as? KtFile)?.findFacadeClass()) + super.getClassesFromFile(psiFile)
}

override fun isCreateTestActionAvailable(element: PsiElement): Boolean {
getTarget(element)?.let {
return KotlinCreateTestIntention().applicabilityRange(it) != null
}
return (element.containingFile as? KtFile)?.findFacadeClass() != null
}

private fun getTarget(element: PsiElement?): KtNamedDeclaration? =
element?.parentsWithSelf
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.utbot.intellij.plugin.ui.utils
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.psi.KtFile

/**
Expand Down Expand Up @@ -36,6 +37,14 @@ interface PsiElementHandler {
*/
fun <T> toPsi(element: PsiElement, clazz: Class<T>): T

/**
* Returns all classes that are declared in the [psiFile]
*/
fun getClassesFromFile(psiFile: PsiFile): List<PsiClass> {
return PsiTreeUtil.getChildrenOfTypeAsList(psiFile, classClass)
.map { toPsi(it, PsiClass::class.java) }
}

/**
* Get java class of the Class in the corresponding syntax tree (PsiClass, KtClass, e.t.c).
*/
Expand Down

0 comments on commit a3538da

Please sign in to comment.