Skip to content

Commit

Permalink
Getting method parameter names (#210)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vassiliy-Kudryashov authored Jan 29, 2024
1 parent 07a5c8b commit 53b8305
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ private fun MethodNode.asMethodInfo(): MethodInfo {
parametersInfo = List(params.size) { index ->
ParameterInfo(
index = index,
name = parameters?.get(index)?.name,
name = argumentName(index),
access = parameters?.get(index)?.access ?: Opcodes.ACC_PUBLIC,
type = params[index],
annotations = visibleParameterAnnotations?.get(index)?.asAnnotationInfos(true).orEmpty()
Expand All @@ -124,6 +124,17 @@ private fun MethodNode.asMethodInfo(): MethodInfo {
)
}

private fun MethodNode.argumentName(argIndex :Int): String? {
localVariables?.let {
(argIndex + 1 - (access and Opcodes.ACC_STATIC).countOneBits()).run {
if (it.size > this) {
return ArrayList(it).sortedBy(LocalVariableNode::index)[this].name
}
}
}
return parameters?.get(argIndex)?.name
}

private fun FieldNode.asFieldInfo() = FieldInfo(
name = name,
signature = signature,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2022 UnitTestBot contributors (utbot.org)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.jacodb.testing

import kotlinx.coroutines.runBlocking
import org.jacodb.api.JcMethod
import org.jacodb.api.JcParameter
import org.jacodb.api.ext.findClass
import org.jacodb.api.ext.methods
import org.jacodb.impl.fs.asClassInfo
import org.jacodb.impl.types.ParameterInfo
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import java.nio.file.Files

class ParameterNamesTest : BaseTest() {
companion object : WithDB()

private val target = Files.createTempDirectory("jcdb-temp")

@Test
fun checkParameterName() {
val clazz = cp.findClass("GenericsApi")
runBlocking {
cp.db.load(target.toFile())
}
val method = clazz.methods.firstOrNull { jcMethod -> jcMethod.name == "call" }
Assertions.assertNotNull(method)
Assertions.assertNull(method?.parameters?.get(0)?.name)
Assertions.assertEquals("arg", method?.parameterNames?.get(0))
}

private val JcMethod.parameterNames: List<String?>
get() {
return enclosingClass.asmNode()
.asClassInfo(enclosingClass.bytecode()).methods.find { info -> info.name == name && info.desc == description }
?.parametersInfo?.map(ParameterInfo::name)
?: parameters.map(JcParameter::name)
}
}

0 comments on commit 53b8305

Please sign in to comment.