Skip to content

Commit c122e77

Browse files
committed
Create speculativeNotNull implementation for Spring
1 parent 71a71e1 commit c122e77

13 files changed

Lines changed: 63 additions & 24 deletions

File tree

utbot-framework/src/main/kotlin/org/utbot/engine/util/trusted/TrustedPackages.kt renamed to utbot-framework-api/src/main/kotlin/org/utbot/framework/TrustedPackages.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
package org.utbot.engine.util.trusted
1+
package org.utbot.framework
22

3-
import org.utbot.framework.TrustedLibraries
43
import soot.SootClass
54

65
/**

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,14 @@ import kotlin.contracts.ExperimentalContracts
5656
import kotlin.contracts.contract
5757
import org.utbot.common.isAbstract
5858
import org.utbot.common.isStatic
59+
import org.utbot.framework.isFromTrustedLibrary
5960
import org.utbot.framework.plugin.api.TypeReplacementMode.*
61+
import org.utbot.framework.plugin.api.util.allDeclaredFieldIds
62+
import org.utbot.framework.plugin.api.util.fieldId
6063
import org.utbot.framework.plugin.api.util.isSubtypeOf
6164
import org.utbot.framework.plugin.api.util.utContext
6265
import org.utbot.framework.process.OpenModulesContainer
66+
import soot.SootField
6367

6468
const val SYMBOLIC_NULL_ADDR: Int = 0
6569

@@ -1196,6 +1200,7 @@ enum class TypeReplacementMode {
11961200
* @param mockFrameworkInstalled shows if we have installed framework dependencies
11971201
* @param staticsMockingIsConfigured shows if we have installed static mocking tools
11981202
*/
1203+
@Suppress("KDocUnresolvedReference")
11991204
open class ApplicationContext(
12001205
val mockFrameworkInstalled: Boolean = true,
12011206
staticsMockingIsConfigured: Boolean = true,
@@ -1229,6 +1234,26 @@ open class ApplicationContext(
12291234
* if it is guided with some additional information.
12301235
*/
12311236
open fun replaceTypeIfNeeded(type: RefType): ClassId? = null
1237+
1238+
/**
1239+
* Sets the restrictions on speculative not null
1240+
* constraints in current application context.
1241+
*
1242+
* @see docs/SpeculativeFieldNonNullability.md for more information.
1243+
*/
1244+
open fun avoidSpeculativeNotNullChecks(field: SootField): Boolean =
1245+
UtSettings.maximizeCoverageUsingReflection || !field.declaringClass.isFromTrustedLibrary()
1246+
1247+
/**
1248+
* Checks whether accessing [field] (with a method invocation or field access) speculatively
1249+
* cannot produce [NullPointerException] (according to its finality or accessibility).
1250+
*
1251+
* @see docs/SpeculativeFieldNonNullability.md for more information.
1252+
*/
1253+
open fun speculativelyCannotProduceNullPointerException(
1254+
field: SootField,
1255+
classUnderTest: ClassId,
1256+
): Boolean = field.isFinal || !field.isPublic
12321257
}
12331258

12341259
/**
@@ -1265,6 +1290,21 @@ class SpringApplicationContext(
12651290
} else {
12661291
null
12671292
}
1293+
1294+
override fun avoidSpeculativeNotNullChecks(field: SootField): Boolean = false
1295+
1296+
/**
1297+
* In Spring applications we can mark as speculatively not null
1298+
* fields if they are mocked and injecting into class under test so on.
1299+
*
1300+
* Fields are not mocked if their actual type is obtained from [springInjectedClasses].
1301+
*
1302+
*/
1303+
override fun speculativelyCannotProduceNullPointerException(
1304+
field: SootField,
1305+
classUnderTest: ClassId,
1306+
): Boolean =
1307+
field.fieldId in classUnderTest.allDeclaredFieldIds && field.declaringClass.id !in springInjectedClasses
12681308
}
12691309

12701310
val RefType.isAbstractType

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import org.utbot.framework.plugin.api.MethodId
1111
import org.utbot.framework.plugin.api.UtModel
1212
import org.utbot.framework.plugin.api.UtNullModel
1313
import org.utbot.framework.plugin.api.UtPrimitiveModel
14+
import org.utbot.framework.plugin.api.id
15+
import soot.SootField
1416
import java.lang.reflect.Constructor
1517
import java.lang.reflect.Executable
1618
import java.lang.reflect.Field
@@ -451,6 +453,9 @@ val ClassId.allDeclaredFieldIds: Sequence<FieldId>
451453
.flatMap { it.declaredFields.asSequence() }
452454
.map { it.fieldId }
453455

456+
val SootField.fieldId: FieldId
457+
get() = FieldId(declaringClass.id, name)
458+
454459
// FieldId utils
455460
val FieldId.safeJField: Field?
456461
get() = declaringClass.jClass.declaredFields.firstOrNull { it.name == name }

utbot-framework/src/main/kotlin/org/utbot/engine/ArrayObjectWrappers.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import org.utbot.framework.plugin.api.UtModel
2828
import org.utbot.framework.plugin.api.UtNullModel
2929
import org.utbot.framework.plugin.api.UtPrimitiveModel
3030
import org.utbot.framework.plugin.api.getIdOrThrow
31+
import org.utbot.framework.plugin.api.util.fieldId
3132
import org.utbot.framework.plugin.api.util.id
3233
import org.utbot.framework.plugin.api.util.objectArrayClassId
3334
import org.utbot.framework.plugin.api.util.objectClassId

utbot-framework/src/main/kotlin/org/utbot/engine/CollectionIteratorWrappers.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import org.utbot.framework.plugin.api.UtAssembleModel
1111
import org.utbot.framework.plugin.api.UtExecutableCallModel
1212
import org.utbot.framework.plugin.api.UtModel
1313
import org.utbot.framework.plugin.api.UtReferenceModel
14+
import org.utbot.framework.plugin.api.util.fieldId
1415
import org.utbot.framework.plugin.api.util.id
1516
import org.utbot.framework.plugin.api.util.methodId
1617
import soot.SootClass

utbot-framework/src/main/kotlin/org/utbot/engine/CollectionWrappers.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import org.utbot.framework.util.graph
3131
import org.utbot.framework.plugin.api.id
3232
import org.utbot.framework.plugin.api.util.booleanClassId
3333
import org.utbot.framework.plugin.api.util.constructorId
34+
import org.utbot.framework.plugin.api.util.fieldId
3435
import org.utbot.framework.plugin.api.util.id
3536
import org.utbot.framework.plugin.api.util.methodId
3637
import org.utbot.framework.plugin.api.util.objectClassId

utbot-framework/src/main/kotlin/org/utbot/engine/Extensions.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,6 @@ val JimpleLocal.variable: LocalVariable
285285
val Type.defaultSymValue: UtExpression
286286
get() = toSort().defaultValue
287287

288-
val SootField.fieldId: FieldId
289-
get() = FieldId(declaringClass.id, name)
290-
291288
val SootField.isEnumConstant: Boolean
292289
get() = name in declaringClass.id.enumConstants.orEmpty().map { enum -> enum.name }
293290

utbot-framework/src/main/kotlin/org/utbot/engine/Memory.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import org.utbot.engine.types.STRING_TYPE
4141
import org.utbot.engine.types.SeqType
4242
import org.utbot.engine.types.TypeResolver
4343
import org.utbot.framework.plugin.api.id
44+
import org.utbot.framework.plugin.api.util.fieldId
4445
import org.utbot.framework.plugin.api.util.isEnum
4546
import soot.ArrayType
4647
import soot.CharType

utbot-framework/src/main/kotlin/org/utbot/engine/Resolver.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ import org.utbot.framework.UtSettings
104104
import org.utbot.framework.plugin.api.visible.UtStreamConsumingException
105105
import org.utbot.framework.plugin.api.UtStreamConsumingFailure
106106
import org.utbot.framework.plugin.api.util.constructor.ValueConstructor
107+
import org.utbot.framework.plugin.api.util.fieldId
107108
import org.utbot.framework.plugin.api.util.isStatic
108109

109110
// hack

utbot-framework/src/main/kotlin/org/utbot/engine/ThreadWrappers.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import org.utbot.framework.plugin.api.UtNullModel
2323
import org.utbot.framework.plugin.api.id
2424
import org.utbot.framework.plugin.api.util.constructorId
2525
import org.utbot.framework.plugin.api.util.defaultValueModel
26+
import org.utbot.framework.plugin.api.util.fieldId
2627
import org.utbot.framework.plugin.api.util.intClassId
2728
import org.utbot.framework.plugin.api.util.objectClassId
2829
import org.utbot.framework.plugin.api.util.stringClassId

0 commit comments

Comments
 (0)