From 0d51aaf304722a4377a8e1cf634903a75101b854 Mon Sep 17 00:00:00 2001 From: Alexey Volkov Date: Mon, 27 Nov 2023 17:53:22 +0300 Subject: [PATCH] Static inner class returns false when isStatic is used #192 (#204) * Static inner class returns false when isStatic is used #192 * fix tests --- .../impl/bytecode/JcClassOrInterfaceImpl.kt | 2 +- .../org/jacodb/impl/fs/ByteCodeConverter.kt | 20 ++----------- .../org/jacodb/impl/types/TypeParameters.kt | 8 +++--- .../java/org/jacodb/testing/types/AAA.java | 28 +++++++++++++++++++ .../jacodb/testing/tests/DatabaseEnvTest.kt | 20 +++++++++++++ 5 files changed, 56 insertions(+), 22 deletions(-) create mode 100644 jacodb-core/src/testFixtures/java/org/jacodb/testing/types/AAA.java diff --git a/jacodb-core/src/main/kotlin/org/jacodb/impl/bytecode/JcClassOrInterfaceImpl.kt b/jacodb-core/src/main/kotlin/org/jacodb/impl/bytecode/JcClassOrInterfaceImpl.kt index 69369f73c..b35cfe86c 100644 --- a/jacodb-core/src/main/kotlin/org/jacodb/impl/bytecode/JcClassOrInterfaceImpl.kt +++ b/jacodb-core/src/main/kotlin/org/jacodb/impl/bytecode/JcClassOrInterfaceImpl.kt @@ -92,7 +92,7 @@ class JcClassOrInterfaceImpl( override val innerClasses: List get() { - return info.innerClasses.map { + return info.innerClasses.filter { it != name }.map { classpath.findClass(it) } } diff --git a/jacodb-core/src/main/kotlin/org/jacodb/impl/fs/ByteCodeConverter.kt b/jacodb-core/src/main/kotlin/org/jacodb/impl/fs/ByteCodeConverter.kt index 7b56197a1..64724b082 100644 --- a/jacodb-core/src/main/kotlin/org/jacodb/impl/fs/ByteCodeConverter.kt +++ b/jacodb-core/src/main/kotlin/org/jacodb/impl/fs/ByteCodeConverter.kt @@ -19,30 +19,16 @@ package org.jacodb.impl.fs import kotlinx.collections.immutable.toImmutableList import org.jacodb.api.ClassSource import org.jacodb.impl.storage.AnnotationValueKind -import org.jacodb.impl.types.AnnotationInfo -import org.jacodb.impl.types.AnnotationValue -import org.jacodb.impl.types.AnnotationValueList -import org.jacodb.impl.types.ClassInfo -import org.jacodb.impl.types.ClassRef -import org.jacodb.impl.types.EnumRef -import org.jacodb.impl.types.FieldInfo -import org.jacodb.impl.types.MethodInfo -import org.jacodb.impl.types.OuterClassRef -import org.jacodb.impl.types.ParameterInfo -import org.jacodb.impl.types.PrimitiveValue +import org.jacodb.impl.types.* import org.objectweb.asm.ClassReader import org.objectweb.asm.Opcodes import org.objectweb.asm.Type -import org.objectweb.asm.tree.AnnotationNode -import org.objectweb.asm.tree.ClassNode -import org.objectweb.asm.tree.FieldNode -import org.objectweb.asm.tree.MethodNode -import org.objectweb.asm.tree.TypeAnnotationNode +import org.objectweb.asm.tree.* fun ClassNode.asClassInfo(bytecode: ByteArray) = ClassInfo( name = Type.getObjectType(name).className, signature = signature, - access = access, + access = innerClasses?.firstOrNull { it.name == name }?.access ?: access, outerClass = outerClassRef(), innerClasses = innerClasses.map { diff --git a/jacodb-core/src/main/kotlin/org/jacodb/impl/types/TypeParameters.kt b/jacodb-core/src/main/kotlin/org/jacodb/impl/types/TypeParameters.kt index 50362ece7..16704fba9 100644 --- a/jacodb-core/src/main/kotlin/org/jacodb/impl/types/TypeParameters.kt +++ b/jacodb-core/src/main/kotlin/org/jacodb/impl/types/TypeParameters.kt @@ -43,12 +43,12 @@ fun JcClassOrInterface.directTypeParameters(): List */ fun JcClassOrInterface.allVisibleTypeParameters(): Map { val direct = typeParameters.associateBy { it.symbol } + val fromMethod = outerMethod?.allVisibleTypeParameters().orEmpty() if (!isStatic) { - val fromOuter = outerClass?.allVisibleTypeParameters() - val fromMethod = outerMethod?.allVisibleTypeParameters() - return ((fromMethod ?: fromOuter).orEmpty() + direct).toPersistentMap() + val fromOuter = outerClass?.allVisibleTypeParameters().orEmpty() + return (direct + fromOuter + fromMethod).toPersistentMap() } - return direct + return (direct + fromMethod).toPersistentMap() } fun JcMethod.allVisibleTypeParameters(): Map { diff --git a/jacodb-core/src/testFixtures/java/org/jacodb/testing/types/AAA.java b/jacodb-core/src/testFixtures/java/org/jacodb/testing/types/AAA.java new file mode 100644 index 000000000..ce3b575bd --- /dev/null +++ b/jacodb-core/src/testFixtures/java/org/jacodb/testing/types/AAA.java @@ -0,0 +1,28 @@ +/* + * Copyright 2022 UnitTestBot contributors (utbot.org) + *

+ * 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 + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.types; + +public class AAA { + + public class BBB { + + } + + static public class CCC { + + } +} diff --git a/jacodb-core/src/testFixtures/kotlin/org/jacodb/testing/tests/DatabaseEnvTest.kt b/jacodb-core/src/testFixtures/kotlin/org/jacodb/testing/tests/DatabaseEnvTest.kt index 67568a04d..847c6ad40 100644 --- a/jacodb-core/src/testFixtures/kotlin/org/jacodb/testing/tests/DatabaseEnvTest.kt +++ b/jacodb-core/src/testFixtures/kotlin/org/jacodb/testing/tests/DatabaseEnvTest.kt @@ -32,6 +32,8 @@ import org.jacodb.testing.* import org.jacodb.testing.hierarchies.Creature import org.jacodb.testing.structure.FieldsAndMethods import org.jacodb.testing.structure.HiddenFieldSuperClass.HiddenFieldSuccClass +import org.jacodb.testing.types.AAA +import org.jacodb.testing.types.AAA.CCC import org.jacodb.testing.usages.Generics import org.jacodb.testing.usages.HelloWorldAnonymousClasses import org.jacodb.testing.usages.WithInner @@ -601,6 +603,24 @@ abstract class DatabaseEnvTest { assertTrue(hiddenFieldSuccClass.toType().fields.size == hiddenFieldSuccClass.fields.size) } + @Test + fun `static flag on classes`() { + val aaa = cp.findClass() + + val bbb = cp.findClass() + val ccc = cp.findClass() + assertFalse(bbb.isStatic) + assertTrue(ccc.isStatic) + + assertTrue(ccc.innerClasses.isEmpty()) + assertTrue(bbb.innerClasses.isEmpty()) + + val inners = aaa.innerClasses.toList() + assertEquals(2, inners.size) + assertTrue(inners.first { it.name.contains("CCC") }.isStatic) + assertFalse(inners.first { it.name.contains("BBB") }.isStatic) + } + private inline fun findSubClasses(allHierarchy: Boolean = false): Sequence { return hierarchyExt.findSubClasses(T::class.java.name, allHierarchy) }