Skip to content

Commit 78bbdb6

Browse files
authored
Merge pull request #98 from UnitTestBot/develop
1.1.0 release
2 parents 6139a09 + 16daefb commit 78bbdb6

File tree

112 files changed

+2929
-769
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+2929
-769
lines changed

.github/workflows/build-and-test.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@ name: Build and run tests
1010
on:
1111
push:
1212
branches:
13-
- main
14-
- develop
15-
- 'feature-**'
16-
- '*/feature-**'
13+
- '*'
14+
- '*/*'
1715
pull_request:
1816
branches:
1917
- main
18+
- develop
2019

2120
permissions:
2221
contents: read

.github/workflows/coverage.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Generate coverage report
22

33
on:
44
push:
5-
branches: [ develop, main ]
5+
branches: [ develop ]
66
pull_request:
77
branches: [ main ]
88
workflow_dispatch:

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
if: ${{ github.actor == 'lehvolk' || github.actor == 'denis-fokin' || github.actor == 'bissquit' }}
1414
runs-on: ubuntu-latest
1515
permissions:
16-
contents: read
16+
contents: write
1717
packages: write
1818
steps:
1919
- uses: actions/checkout@v3

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
[![ci status](https://github.com/UnitTestBot/jacodb/actions/workflows/build-and-test.yml/badge.svg)](https://github.com/UnitTestBot/jacodb/actions/workflows/build-and-test.yml)
1+
[![Maven](https://maven-badges.herokuapp.com/maven-central/org.jacodb/jacodb-api/badge.svg)](https://central.sonatype.com/search?smo=true&q=org.jacodb)
2+
[![Last Release](https://img.shields.io/github/release-date/unittestbot/jacodb.svg?logo=github)](https://github.com/unittestbot/jacodb/releases/latest)
3+
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
4+
![Pure Java + Kotlin](https://img.shields.io/badge/100%25-java%2bkotlin-orange.svg)
25
[![Coverage](./docs/badges/jacoco.svg)](https://github.com/UnitTestBot/jacodb/actions/workflows/coverage.yml)
36

47
## Overview

build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ val includeDokka: String? by project
88

99
group = "org.jacodb"
1010

11-
project.version = semVer ?: "1.0-SNAPSHOT"
11+
project.version = semVer ?: "1.1-SNAPSHOT"
1212

1313
buildscript {
1414
repositories {
@@ -175,6 +175,7 @@ if (!repoUrl.isNullOrEmpty()) {
175175
project(":jacodb-api"),
176176
project(":jacodb-core"),
177177
project(":jacodb-analysis"),
178+
project(":jacodb-approximations"),
178179
)
179180
) {
180181
publishing {

docs/badges/branches.svg

Lines changed: 1 addition & 1 deletion
Loading

docs/badges/coverage-summary.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"branches": 68.14246846401187, "coverage": 69.80196523053665}
1+
{"branches": 68.50657108721624, "coverage": 70.46257629296498}

docs/badges/jacoco.svg

Lines changed: 1 addition & 1 deletion
Loading

gradle.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ jooqVersion=3.14.16
99
junit5Version=5.9.0
1010

1111
intellij_community_url=https://download-cdn.jetbrains.com/idea/ideaIC-2022.2.3.win.zip
12-
#database_location=d:\\work\\jacodb\\jcdb-http.db
12+
#database_location=d:\\work\\jacodb\\jcdb-http.db
13+
org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m

jacodb-analysis/src/main/kotlin/org/jacodb/analysis/analyzers/NpeAnalyzer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ private class NPEForwardFunctions(
222222
// Possibly null arguments
223223
result += method.flowGraph().locals
224224
.filterIsInstance<JcArgument>()
225-
.filter { it.type.nullable != false }
225+
.filter { method.parameters[it.index].isNullable != false }
226226
.map { NPETaintNode(AccessPath.fromLocal(it)) }
227227

228228
// Possibly null statics

jacodb-analysis/src/test/kotlin/org/jacodb/analysis/impl/NpeAnalysisTest.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,19 +140,15 @@ class NpeAnalysisTest : BaseTest() {
140140
fun `npe on virtual call when possible`() {
141141
testOneMethod<NPEExamples>(
142142
"possibleNPEOnVirtualCall",
143-
144-
// TODO: first location is false-positive here due to not-parsed @NotNull annotation
145-
listOf("%0 = arg\$0.functionThatCanThrowNPEOnNull(arg\$1)", "%0 = arg\$0.length()")
143+
listOf("%0 = arg\$0.length()")
146144
)
147145
}
148146

149147
@Test
150148
fun `no npe on virtual call when impossible`() {
151149
testOneMethod<NPEExamples>(
152150
"noNPEOnVirtualCall",
153-
154-
// TODO: false-positive here due to not-parsed @NotNull annotation
155-
listOf("%0 = arg\$0.functionThatCanNotThrowNPEOnNull(arg\$1)")
151+
emptyList()
156152
)
157153
}
158154

jacodb-api/build.gradle.kts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,4 @@ dependencies {
1515
api(group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-jdk8", version = coroutinesVersion)
1616

1717
api(group = "org.jooq", name = "jooq", version = jooqVersion)
18-
implementation(group = "org.jetbrains.kotlinx", name = "kotlinx-metadata-jvm", version = kmetadataVersion)
19-
2018
}

jacodb-api/src/main/kotlin/org/jacodb/api/Classes.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import org.jacodb.api.cfg.JcGraph
2020
import org.jacodb.api.cfg.JcInst
2121
import org.jacodb.api.cfg.JcInstList
2222
import org.jacodb.api.cfg.JcRawInst
23+
import org.jacodb.api.ext.CONSTRUCTOR
2324
import org.objectweb.asm.Opcodes
2425
import org.objectweb.asm.tree.ClassNode
2526
import org.objectweb.asm.tree.MethodNode
@@ -116,7 +117,7 @@ interface JcMethod : JcSymbol, JcAnnotatedSymbol, JcAccessible {
116117
*/
117118
val isConstructor: Boolean
118119
get() {
119-
return name == "<init>"
120+
return name == CONSTRUCTOR
120121
}
121122

122123
val isClassInitializer: Boolean

jacodb-api/src/main/kotlin/org/jacodb/api/JcClasspath.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,10 @@ interface JcClasspath : Closeable {
5656
*/
5757
fun findTypeOrNull(name: String): JcType?
5858

59-
fun typeOf(jcClass: JcClassOrInterface): JcRefType
59+
fun typeOf(jcClass: JcClassOrInterface, nullability: Boolean? = null, annotations: List<JcAnnotation> = listOf()): JcRefType
60+
61+
fun arrayTypeOf(elementType: JcType, nullability: Boolean? = null, annotations: List<JcAnnotation> = listOf()): JcArrayType
6062

61-
fun arrayTypeOf(elementType: JcType): JcArrayType
6263
fun toJcClass(source: ClassSource): JcClassOrInterface
6364

6465
suspend fun refreshed(closeOld: Boolean): JcClasspath
@@ -138,7 +139,9 @@ interface JcClasspathExtFeature : JcClasspathFeature {
138139
interface JcClassExtFeature : JcClasspathFeature {
139140

140141
fun fieldsOf(clazz: JcClassOrInterface): List<JcField>? = null
142+
fun fieldsOf(clazz: JcClassOrInterface, originalFields: List<JcField>): List<JcField>? = fieldsOf(clazz)
141143
fun methodsOf(clazz: JcClassOrInterface): List<JcMethod>? = null
144+
fun methodsOf(clazz: JcClassOrInterface, originalMethods: List<JcMethod>): List<JcMethod>? = methodsOf(clazz)
142145

143146
fun extensionValuesOf(clazz: JcClassOrInterface): Map<String, Any>? = null
144147

@@ -151,6 +154,7 @@ interface JcInstExtFeature : JcClasspathFeature {
151154
fun transformInstList(method: JcMethod, list: JcInstList<JcInst>): JcInstList<JcInst> = list
152155
}
153156

157+
@JvmDefaultWithoutCompatibility
154158
interface JcMethodExtFeature : JcClasspathFeature {
155159

156160
fun flowGraph(method: JcMethod): JcGraph? = null

jacodb-api/src/main/kotlin/org/jacodb/api/PredefinedPrimitive.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ object PredefinedPrimitives {
3636
private val valueSet = values.toHashSet()
3737

3838
@JvmStatic
39-
fun of(name: String, cp: JcClasspath): JcPrimitiveType? {
39+
fun of(name: String, cp: JcClasspath, annotations: List<JcAnnotation> = listOf()): JcPrimitiveType? {
4040
if (valueSet.contains(name)) {
41-
return PredefinedPrimitive(cp, name)
41+
return PredefinedPrimitive(cp, name, annotations)
4242
}
4343
return null
4444
}
@@ -52,7 +52,8 @@ object PredefinedPrimitives {
5252
/**
5353
* Predefined primitive types
5454
*/
55-
class PredefinedPrimitive(override val classpath: JcClasspath, override val typeName: String) : JcPrimitiveType {
55+
class PredefinedPrimitive(override val classpath: JcClasspath, override val typeName: String,
56+
override val annotations: List<JcAnnotation> = listOf()) : JcPrimitiveType {
5657

5758
override fun equals(other: Any?): Boolean {
5859
if (this === other) return true
@@ -69,4 +70,6 @@ class PredefinedPrimitive(override val classpath: JcClasspath, override val type
6970
return typeName.hashCode()
7071
}
7172

73+
override fun copyWithAnnotations(annotations: List<JcAnnotation>): JcType =
74+
PredefinedPrimitive(classpath, typeName, annotations)
7275
}

jacodb-api/src/main/kotlin/org/jacodb/api/Types.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,16 @@ interface JcTypedMethodParameter {
4848
val type: JcType
4949
val name: String?
5050
val enclosingMethod: JcTypedMethod
51-
val nullable: Boolean?
5251
}
5352

5453
interface JcType {
5554
val classpath: JcClasspath
5655
val typeName: String
5756

5857
val nullable: Boolean?
58+
val annotations: List<JcAnnotation>
59+
60+
fun copyWithAnnotations(annotations: List<JcAnnotation>): JcType
5961
}
6062

6163
interface JcPrimitiveType : JcType {
@@ -109,12 +111,16 @@ interface JcTypeVariable : JcRefType {
109111
interface JcBoundedWildcard : JcRefType {
110112
val upperBounds: List<JcRefType>
111113
val lowerBounds: List<JcRefType>
114+
115+
override fun copyWithAnnotations(annotations: List<JcAnnotation>): JcType = this
112116
}
113117

114118
interface JcUnboundWildcard : JcRefType {
115119
override val jcClass: JcClassOrInterface
116120
get() = classpath.objectClass
117121

122+
override fun copyWithAnnotations(annotations: List<JcAnnotation>): JcType = this
123+
118124
}
119125

120126
interface JcTypeVariableDeclaration {

jacodb-api/src/main/kotlin/org/jacodb/api/cfg/FullExprSetCollector.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ abstract class AbstractFullRawExprSetCollector : JcRawExprVisitor<Unit>, Default
126126
override fun visitJcRawStringConstant(value: JcRawStringConstant) = ifMatches(value)
127127
override fun visitJcRawClassConstant(value: JcRawClassConstant) = ifMatches(value)
128128
override fun visitJcRawMethodConstant(value: JcRawMethodConstant) = ifMatches(value)
129+
override fun visitJcRawMethodType(value: JcRawMethodType) = ifMatches(value)
129130

130131
abstract fun ifMatches(expr: JcRawExpr)
131132
}
@@ -235,33 +236,34 @@ abstract class AbstractFullExprSetCollector : JcExprVisitor<Any>, DefaultJcInstV
235236
return Unit
236237
}
237238

238-
override fun visitJcArrayAccess(value: JcArrayAccess) : Any{
239+
override fun visitJcArrayAccess(value: JcArrayAccess): Any {
239240
ifMatches(value)
240241
value.array.accept(this)
241242
value.index.accept(this)
242243
return Unit
243244
}
244245

245-
override fun visitJcPhiExpr(expr: JcPhiExpr) : Any{
246+
override fun visitJcPhiExpr(expr: JcPhiExpr): Any {
246247
ifMatches(expr)
247248
expr.args.forEach { it.accept(this) }
248249
expr.values.forEach { it.accept(this) }
249250
return Unit
250251
}
251252

252253
override fun visitExternalJcExpr(expr: JcExpr): Any = ifMatches(expr)
253-
override fun visitJcBool(value: JcBool) : Any= ifMatches(value)
254+
override fun visitJcBool(value: JcBool): Any = ifMatches(value)
254255
override fun visitJcByte(value: JcByte): Any = ifMatches(value)
255-
override fun visitJcChar(value: JcChar) : Any= ifMatches(value)
256+
override fun visitJcChar(value: JcChar): Any = ifMatches(value)
256257
override fun visitJcShort(value: JcShort): Any = ifMatches(value)
257258
override fun visitJcInt(value: JcInt): Any = ifMatches(value)
258259
override fun visitJcLong(value: JcLong): Any = ifMatches(value)
259260
override fun visitJcFloat(value: JcFloat): Any = ifMatches(value)
260261
override fun visitJcDouble(value: JcDouble): Any = ifMatches(value)
261262
override fun visitJcNullConstant(value: JcNullConstant): Any = ifMatches(value)
262-
override fun visitJcStringConstant(value: JcStringConstant) : Any= ifMatches(value)
263-
override fun visitJcClassConstant(value: JcClassConstant) : Any= ifMatches(value)
264-
override fun visitJcMethodConstant(value: JcMethodConstant) : Any= ifMatches(value)
263+
override fun visitJcStringConstant(value: JcStringConstant): Any = ifMatches(value)
264+
override fun visitJcClassConstant(value: JcClassConstant): Any = ifMatches(value)
265+
override fun visitJcMethodConstant(value: JcMethodConstant): Any = ifMatches(value)
266+
override fun visitJcMethodType(value: JcMethodType): Any = ifMatches(value)
265267

266268
abstract fun ifMatches(expr: JcExpr)
267269
}

jacodb-api/src/main/kotlin/org/jacodb/api/cfg/JcInst.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,4 +1167,22 @@ data class JcMethodConstant(
11671167
override fun <T> accept(visitor: JcExprVisitor<T>): T {
11681168
return visitor.visitJcMethodConstant(this)
11691169
}
1170+
}
1171+
1172+
data class JcMethodType(
1173+
val argumentTypes: List<JcType>,
1174+
val returnType: JcType,
1175+
override val type: JcType
1176+
) : JcConstant {
1177+
override fun toString(): String = "${
1178+
argumentTypes.joinToString(
1179+
prefix = "(",
1180+
postfix = ")",
1181+
separator = ", "
1182+
)
1183+
}:${returnType}"
1184+
1185+
override fun <T> accept(visitor: JcExprVisitor<T>): T {
1186+
return visitor.visitJcMethodType(this)
1187+
}
11701188
}

jacodb-api/src/main/kotlin/org/jacodb/api/cfg/JcInstVisitor.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ interface JcExprVisitor<T> {
109109
fun visitJcStringConstant(value: JcStringConstant): T
110110
fun visitJcClassConstant(value: JcClassConstant): T
111111
fun visitJcMethodConstant(value: JcMethodConstant): T
112+
fun visitJcMethodType(value: JcMethodType): T
112113
fun visitJcPhiExpr(expr: JcPhiExpr): T
113114

114115
fun visitExternalJcExpr(expr: JcExpr): T
@@ -216,6 +217,8 @@ interface DefaultJcExprVisitor<T> : JcExprVisitor<T> {
216217

217218
override fun visitJcMethodConstant(value: JcMethodConstant): T = defaultExprHandler(value)
218219

220+
override fun visitJcMethodType(value: JcMethodType): T = defaultExprHandler(value)
221+
219222
override fun visitJcPhiExpr(expr: JcPhiExpr): T = defaultExprHandler(expr)
220223

221224
override fun visitExternalJcExpr(expr: JcExpr): T = defaultExprHandler(expr)

jacodb-api/src/main/kotlin/org/jacodb/api/cfg/JcRawInst.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,21 @@ data class JcRawMethodConstant(
959959
}
960960
}
961961

962+
data class JcRawMethodType(
963+
val argumentTypes: List<TypeName>,
964+
val returnType: TypeName,
965+
private val methodType: TypeName
966+
) : JcRawConstant {
967+
override val typeName: TypeName = methodType
968+
969+
override fun toString(): String =
970+
"${argumentTypes.joinToString(prefix = "(", postfix = ")")}:$returnType"
971+
972+
override fun <T> accept(visitor: JcRawExprVisitor<T>): T {
973+
return visitor.visitJcRawMethodType(this)
974+
}
975+
}
976+
962977
//
963978
//fun JcRawInstList.lineNumberOf(inst: JcRawInst): Int? {
964979
// val idx: Int = instructions.indexOf(inst)

jacodb-api/src/main/kotlin/org/jacodb/api/cfg/JcRawInstVisitor.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ interface JcRawExprVisitor<T> {
112112
fun visitJcRawStringConstant(value: JcRawStringConstant): T
113113
fun visitJcRawClassConstant(value: JcRawClassConstant): T
114114
fun visitJcRawMethodConstant(value: JcRawMethodConstant): T
115+
fun visitJcRawMethodType(value: JcRawMethodType): T
115116
}
116117

117118
@JvmDefaultWithoutCompatibility
@@ -214,4 +215,6 @@ interface DefaultJcRawExprVisitor<T> : JcRawExprVisitor<T> {
214215
override fun visitJcRawClassConstant(value: JcRawClassConstant): T = defaultExprHandler(value)
215216

216217
override fun visitJcRawMethodConstant(value: JcRawMethodConstant): T = defaultExprHandler(value)
218+
219+
override fun visitJcRawMethodType(value: JcRawMethodType): T = defaultExprHandler(value)
217220
}

jacodb-api/src/main/kotlin/org/jacodb/api/ext/JcClasses.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ fun JcClassOrInterface.toType(): JcClassType {
5252

5353
val JcClassOrInterface.packageName get() = name.substringBeforeLast(".")
5454

55+
const val JAVA_OBJECT = "java.lang.Object"
5556

5657
/**
5758
* find field by name
@@ -67,10 +68,13 @@ fun JcClassOrInterface.findFieldOrNull(name: String): JcField? {
6768
}
6869
}
6970

70-
fun JcClassOrInterface.findDeclaredFieldOrNull(name: String): JcField? = declaredFields.firstOrNull { it.name == name }
71+
fun JcClassOrInterface.findDeclaredFieldOrNull(name: String): JcField? = declaredFields.singleOrNull { it.name == name }
7172

7273
fun JcClassOrInterface.findDeclaredMethodOrNull(name: String, desc: String? = null): JcMethod? {
73-
return declaredMethods.firstOrNull { it.name == name && (desc == null || it.description == desc) }
74+
return when (desc) {
75+
null -> declaredMethods.firstOrNull { it.name == name }
76+
else -> declaredMethods.singleOrNull { it.name == name && it.description == desc }
77+
}
7478
}
7579

7680

jacodb-api/src/main/kotlin/org/jacodb/api/ext/JcMethods.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ import org.objectweb.asm.Type
2626
import org.objectweb.asm.tree.FieldInsnNode
2727
import org.objectweb.asm.tree.MethodInsnNode
2828

29+
30+
const val CONSTRUCTOR = "<init>"
31+
2932
/**
3033
* is method has `strictfp` modifier
3134
*/

0 commit comments

Comments
 (0)