Skip to content

Commit dfcf0bd

Browse files
committed
Support hidden fields access in code generation
1 parent e0b2fc8 commit dfcf0bd

File tree

8 files changed

+265
-75
lines changed

8 files changed

+265
-75
lines changed

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/context/CgContext.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ internal interface CgContextOwner {
164164
// java.lang.reflect.Executable is a superclass of both of these types.
165165
var declaredExecutableRefs: PersistentMap<ExecutableId, CgVariable>
166166

167+
// Variables of java.lang.reflect.Field type declared in the current name scope
168+
var declaredFieldRefs: PersistentMap<FieldId, CgVariable>
169+
167170
// generated this instance for method under test
168171
var thisInstance: CgValue?
169172

@@ -310,6 +313,7 @@ internal interface CgContextOwner {
310313
val prevVariableNames = existingVariableNames
311314
val prevDeclaredClassRefs = declaredClassRefs
312315
val prevDeclaredExecutableRefs = declaredExecutableRefs
316+
val prevDeclaredFieldRefs = declaredFieldRefs
313317
val prevValueByModel = IdentityHashMap(valueByModel)
314318
val prevValueByModelId = valueByModelId.toMutableMap()
315319
return try {
@@ -318,6 +322,7 @@ internal interface CgContextOwner {
318322
existingVariableNames = prevVariableNames
319323
declaredClassRefs = prevDeclaredClassRefs
320324
declaredExecutableRefs = prevDeclaredExecutableRefs
325+
declaredFieldRefs = prevDeclaredFieldRefs
321326
valueByModel = prevValueByModel
322327
valueByModelId = prevValueByModelId
323328
}
@@ -415,6 +420,7 @@ internal data class CgContext(
415420
override var existingVariableNames: PersistentSet<String> = persistentSetOf(),
416421
override var declaredClassRefs: PersistentMap<ClassId, CgVariable> = persistentMapOf(),
417422
override var declaredExecutableRefs: PersistentMap<ExecutableId, CgVariable> = persistentMapOf(),
423+
override var declaredFieldRefs: PersistentMap<FieldId, CgVariable> = persistentMapOf(),
418424
override var thisInstance: CgValue? = null,
419425
override val methodArguments: MutableList<CgValue> = mutableListOf(),
420426
override val codeGenerationErrors: MutableMap<CgMethodTestSet, MutableMap<String, Int>> = mutableMapOf(),

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

Lines changed: 197 additions & 60 deletions
Large diffs are not rendered by default.

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import org.utbot.framework.codegen.model.tree.CgGetJavaClass
1717
import org.utbot.framework.codegen.model.tree.CgValue
1818
import org.utbot.framework.codegen.model.tree.CgVariable
1919
import org.utbot.framework.codegen.model.util.at
20-
import org.utbot.framework.codegen.model.util.get
2120
import org.utbot.framework.codegen.model.util.isAccessibleFrom
2221
import org.utbot.framework.codegen.model.util.stringLiteral
2322
import org.utbot.framework.fields.ArrayElementAccess

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ import org.utbot.framework.codegen.model.tree.convertDocToCg
6767
import org.utbot.framework.codegen.model.tree.toStatement
6868
import org.utbot.framework.codegen.model.util.canBeSetIn
6969
import org.utbot.framework.codegen.model.util.equalTo
70-
import org.utbot.framework.codegen.model.util.get
7170
import org.utbot.framework.codegen.model.util.inc
7271
import org.utbot.framework.codegen.model.util.isAccessibleFrom
7372
import org.utbot.framework.codegen.model.util.length

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import org.utbot.framework.codegen.model.tree.CgValue
2424
import org.utbot.framework.codegen.model.tree.CgVariable
2525
import org.utbot.framework.codegen.model.util.at
2626
import org.utbot.framework.codegen.model.util.canBeSetIn
27-
import org.utbot.framework.codegen.model.util.get
2827
import org.utbot.framework.codegen.model.util.inc
2928
import org.utbot.framework.codegen.model.util.isAccessibleFrom
3029
import org.utbot.framework.codegen.model.util.lessThan

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/util/CgStatementConstructor.kt

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,17 @@ import org.utbot.framework.plugin.api.util.isSubtypeOf
5757
import org.utbot.framework.plugin.api.util.objectArrayClassId
5858
import org.utbot.framework.plugin.api.util.objectClassId
5959
import fj.data.Either
60+
import org.utbot.framework.codegen.model.constructor.builtin.getDeclaredConstructor
61+
import org.utbot.framework.codegen.model.constructor.builtin.getDeclaredField
62+
import org.utbot.framework.codegen.model.constructor.builtin.getDeclaredMethod
6063
import org.utbot.framework.codegen.model.tree.CgArrayInitializer
64+
import org.utbot.framework.codegen.model.tree.CgGetJavaClass
6165
import org.utbot.framework.codegen.model.tree.CgIsInstance
66+
import org.utbot.framework.plugin.api.ConstructorId
67+
import org.utbot.framework.plugin.api.FieldId
68+
import org.utbot.framework.plugin.api.MethodId
6269
import org.utbot.framework.plugin.api.util.classClassId
70+
import org.utbot.framework.plugin.api.util.isPrimitive
6371
import java.lang.reflect.Constructor
6472
import java.lang.reflect.Method
6573
import kotlin.reflect.KFunction
@@ -113,6 +121,19 @@ interface CgStatementConstructor {
113121
fun doWhileLoop(condition: CgExpression, statements: () -> Unit)
114122
fun forEachLoop(init: CgForEachLoopBuilder.() -> Unit)
115123

124+
/**
125+
* Create a variable of type [java.lang.reflect.Field] by the given [FieldId].
126+
*/
127+
fun createFieldVariable(fieldId: FieldId): CgVariable
128+
129+
130+
/**
131+
* Given an [executableId] that represents method or constructor and a list of arguments for it,
132+
* create a variable of type [java.lang.reflect.Method] or [java.lang.reflect.Constructor].
133+
* This created variable is returned.
134+
*/
135+
fun createExecutableVariable(executableId: ExecutableId, arguments: List<CgExpression>): CgVariable
136+
116137
fun tryBlock(init: () -> Unit): CgTryCatch
117138
fun tryBlock(init: () -> Unit, resources: List<CgDeclaration>?): CgTryCatch
118139
fun CgTryCatch.catch(exception: ClassId, init: (CgVariable) -> Unit): CgTryCatch
@@ -284,6 +305,46 @@ internal class CgStatementConstructorImpl(context: CgContext) :
284305
currentBlock += buildCgForEachLoop(init)
285306
}
286307

308+
override fun createFieldVariable(fieldId: FieldId): CgVariable {
309+
val declaringClass = newVar(Class::class.id) { Class::class.id[forName](fieldId.declaringClass.name) }
310+
val name = fieldId.name + "Field"
311+
return newVar(java.lang.reflect.Field::class.id, name) {
312+
declaringClass[getDeclaredField](fieldId.name)
313+
}
314+
}
315+
316+
override fun createExecutableVariable(executableId: ExecutableId, arguments: List<CgExpression>): CgVariable {
317+
val declaringClass = newVar(Class::class.id) { Class::class.id[forName](executableId.classId.name) }
318+
val argTypes = (arguments zip executableId.parameters).map { (argument, parameterType) ->
319+
val baseName = when (argument) {
320+
is CgVariable -> "${argument.name}Type"
321+
else -> "${parameterType.prettifiedName.decapitalize()}Type"
322+
}
323+
newVar(classCgClassId, baseName) {
324+
if (parameterType.isPrimitive) {
325+
CgGetJavaClass(parameterType)
326+
} else {
327+
Class::class.id[forName](parameterType.name)
328+
}
329+
}
330+
}
331+
332+
return when (executableId) {
333+
is MethodId -> {
334+
val name = executableId.name + "Method"
335+
newVar(java.lang.reflect.Method::class.id, name) {
336+
declaringClass[getDeclaredMethod](executableId.name, *argTypes.toTypedArray())
337+
}
338+
}
339+
is ConstructorId -> {
340+
val name = executableId.classId.prettifiedName.decapitalize() + "Constructor"
341+
newVar(java.lang.reflect.Constructor::class.id, name) {
342+
declaringClass[getDeclaredConstructor](*argTypes.toTypedArray())
343+
}
344+
}
345+
}
346+
}
347+
287348
override fun tryBlock(init: () -> Unit): CgTryCatch = tryBlock(init, null)
288349

289350
override fun tryBlock(init: () -> Unit, resources: List<CgDeclaration>?): CgTryCatch =

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/util/DslUtil.kt

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,6 @@ fun charLiteral(c: Char) = CgLiteral(charClassId, c)
6868

6969
fun stringLiteral(string: String) = CgLiteral(stringClassId, string)
7070

71-
// Field access
72-
73-
// non-static fields
74-
operator fun CgExpression.get(fieldId: FieldId): CgFieldAccess =
75-
CgFieldAccess(this, fieldId)
76-
77-
// static fields
78-
// TODO: unused receiver
79-
operator fun ClassId.get(fieldId: FieldId): CgStaticFieldAccess =
80-
CgStaticFieldAccess(fieldId)
81-
8271
// Get array length
8372

8473
/**

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/util/ExecutableIdUtil.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import org.utbot.framework.plugin.api.ExecutableId
88
*
99
* @param packageName name of the package we check accessibility from
1010
*/
11-
fun ExecutableId.isAccessibleFrom(packageName: String): Boolean {
11+
infix fun ExecutableId.isAccessibleFrom(packageName: String): Boolean {
1212
val isAccessibleFromPackageByModifiers = isPublic || (classId.packageName == packageName && (isPackagePrivate || isProtected))
1313

1414
return classId.isAccessibleFrom(packageName) && isAccessibleFromPackageByModifiers

0 commit comments

Comments
 (0)