~ [j] tests refactor + invalid names tests
diff --git a/compiler/java-direct/ITERATION_RESULTS.md b/compiler/java-direct/ITERATION_RESULTS.md index 5885fae..38b776c 100644 --- a/compiler/java-direct/ITERATION_RESULTS.md +++ b/compiler/java-direct/ITERATION_RESULTS.md
@@ -36,6 +36,22 @@ <!-- Add new entries below, newest first. --> +### 2026-07-31 — Unit tests use JUnit asserters; lightweight scan of malformed package names +- **Change**: reviewer follow-up on `JavaParsingLightweightScannerTest`. Every raw Kotlin + `assert(...)` in the module's unit tests (a no-op without `-ea`) is now a JUnit assertion — + `assertEquals`/`assertTrue`/`assertFalse`/`assertNull`/`assertSame` and the contract-carrying + `org.junit.jupiter.api.assertNotNull`, which let the following `!!` go. Messages that only + restated expected/actual are dropped. New scanner tests: a package name split across a line + and a block comment (`package builder // c \n . /* c */ subpackage;`), `package com.123;`, and + `class 456 {}` with and without a well-formed sibling. `extractFileInfoLightweight` now joins + identifier segments instead of appending identifiers and dots verbatim, so a malformed name + degrades to its valid prefix (`com`) rather than the stray-dot `com.`. +- **Files**: `util/JavaSourceIndex.kt` (+3/−3); all 10 unit test files under `test/` (~440 + assertions rewritten), `JavaParsingLightweightScannerTest.kt` +4 tests. +- **Tests**: unit tests 121/121 green (12 classes); box + phased green (2795 executed, 0 + failures, 0 errors). +- **Result**: green. + ### 2026-07-31 — Lazy enum-entry annotations without the fragile mutable list - **Change**: the previous schema let `FirLazyJavaAnnotationMutableList` sit in `FirEnumEntryImpl`'s `MutableOrEmptyList` slot, and depended on nothing but `isEmpty` being
diff --git a/compiler/java-direct/src/org/jetbrains/kotlin/java/direct/util/JavaSourceIndex.kt b/compiler/java-direct/src/org/jetbrains/kotlin/java/direct/util/JavaSourceIndex.kt index abb8530..1c9ae0d 100644 --- a/compiler/java-direct/src/org/jetbrains/kotlin/java/direct/util/JavaSourceIndex.kt +++ b/compiler/java-direct/src/org/jetbrains/kotlin/java/direct/util/JavaSourceIndex.kt
@@ -63,17 +63,17 @@ var packageName: String? = null if (at(JavaSyntaxTokenType.PACKAGE_KEYWORD)) { - val name = StringBuilder() + val segments = mutableListOf<String>() advance() loop@ while (!end() && !at(JavaSyntaxTokenType.SEMICOLON)) { when (lexer.getTokenType()) { - JavaSyntaxTokenType.IDENTIFIER, JavaSyntaxTokenType.DOT -> name.append(lexer.getTokenText()) - SyntaxTokenTypes.WHITE_SPACE, in JavaSyntaxDefinition.comments -> Unit + JavaSyntaxTokenType.IDENTIFIER -> segments.add(lexer.getTokenText()) + JavaSyntaxTokenType.DOT, SyntaxTokenTypes.WHITE_SPACE, in JavaSyntaxDefinition.comments -> Unit else -> break@loop } advance() } - packageName = name.toString().takeIf { it.isNotEmpty() } + packageName = segments.takeIf { it.isNotEmpty() }?.joinToString(".") } val classNames = mutableSetOf<String>()
diff --git a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaConstantEvaluatorTest.kt b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaConstantEvaluatorTest.kt index 626e195..d606c1a 100644 --- a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaConstantEvaluatorTest.kt +++ b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaConstantEvaluatorTest.kt
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.java.direct.parse.JavaLightNode import org.jetbrains.kotlin.java.direct.parse.JavaLightTree import org.jetbrains.kotlin.java.direct.util.ConstantEvaluator +import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test class JavaConstantEvaluatorTest : JavaParsingTestBase() { @@ -54,13 +55,8 @@ val result = evaluator.evaluate(refNode) - assert(captured == "com.example.Constants" to "MAX") { - "Statically imported field 'MAX' should reach the external resolver as " + - "('com.example.Constants', 'MAX'), but was routed as $captured" - } - assert(result == 42) { - "Expected the statically imported field to evaluate to 42, got $result" - } + assertEquals("com.example.Constants" to "MAX", captured) + assertEquals(42, result) } /** @@ -93,9 +89,7 @@ evaluator.evaluate(refNode) - assert(captured == (null to "MISSING")) { - "A bare name with no static import must reach the resolver as (null, 'MISSING'), got $captured" - } + assertEquals(null to "MISSING", captured) } private fun findReferenceExpression(tree: JavaLightTree, node: JavaLightNode, text: String): JavaLightNode? {
diff --git a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaCycleBreakerTest.kt b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaCycleBreakerTest.kt index 2abf839..545e526 100644 --- a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaCycleBreakerTest.kt +++ b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaCycleBreakerTest.kt
@@ -22,6 +22,8 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows @@ -93,9 +95,7 @@ walk(a) - assert(visits == 2) { - "Each class in the cycle must be entered exactly once; re-entry is broken by the guard, got $visits" - } + assertEquals(2, visits, "Each class in the cycle must be entered exactly once; re-entry is broken by the guard") } @OptIn(SessionConfiguration::class) @@ -153,13 +153,13 @@ val result = session.cycleSafeClassLikeSymbol(a) - assert(result == null) { - "The re-entrant probe for an in-flight ClassId must be short-circuited to null, got $result" - } - assert(providerInvocations == 1) { + assertNull(result, "The re-entrant probe for an in-flight ClassId must be short-circuited to null") + assertEquals( + 1, + providerInvocations, "The provider must be entered exactly once; the re-entrant probe for the same in-flight " + - "ClassId short-circuits before reaching the provider again, got $providerInvocations" - } + "ClassId short-circuits before reaching the provider again" + ) } @OptIn(SessionConfiguration::class)
diff --git a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingAnnotationsTest.kt b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingAnnotationsTest.kt index 806faed..4af2592 100644 --- a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingAnnotationsTest.kt +++ b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingAnnotationsTest.kt
@@ -12,7 +12,12 @@ import org.jetbrains.kotlin.load.java.structure.JavaClassifierType import org.jetbrains.kotlin.load.java.structure.JavaEnumValueAnnotationArgument import org.jetbrains.kotlin.name.FqName +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertNotNull class JavaParsingAnnotationsTest : JavaParsingTestBase() { @@ -24,10 +29,10 @@ """.trimIndent() val javaClass = parseFirstClass(source) - assert(javaClass.annotations.size == 1) + assertEquals(1, javaClass.annotations.size) // Unit test parses without FIR, so annotation is unresolved (just "Deprecated") // FIR will resolve it to java.lang.Deprecated via resolveAnnotation - assert(javaClass.annotations.first().classId?.asSingleFqName()?.asString() == "Deprecated") + assertEquals("Deprecated", javaClass.annotations.first().classId?.asSingleFqName()?.asString()) } @Test @@ -37,11 +42,11 @@ public class Foo {} """.trimIndent() val javaClass = parseFirstClass(source) - assert(javaClass.annotations.isNotEmpty()) { "Should have annotations" } + assertTrue(javaClass.annotations.isNotEmpty()) { "Should have annotations" } val found = javaClass.findAnnotation(FqName("Deprecated")) - assert(found != null) { "findAnnotation should find @Deprecated on class, got null" } + assertNotNull(found) { "findAnnotation should find @Deprecated on class" } val notFound = javaClass.findAnnotation(FqName("Override")) - assert(notFound == null) { "findAnnotation should return null for missing annotation" } + assertNull(notFound) { "findAnnotation should return null for missing annotation" } } @Test @@ -60,26 +65,16 @@ val field = javaClass.fields.first { it.name.asString() == "items" } val fieldType = field.type as JavaClassifierType - assert(fieldType.classifierQualifiedName == "List") { - "Expected 'List', got ${fieldType.classifierQualifiedName}" - } - assert(fieldType.typeArguments.size == 1) { - "Expected 1 type argument, got ${fieldType.typeArguments.size}" - } + assertEquals("List", fieldType.classifierQualifiedName) + assertEquals(1, fieldType.typeArguments.size) val typeArg = fieldType.typeArguments[0] as JavaClassifierType - assert(typeArg.classifierQualifiedName == "Integer") { - "Expected 'Integer', got ${typeArg.classifierQualifiedName}" - } + assertEquals("Integer", typeArg.classifierQualifiedName) // TYPE_USE annotation @NotNull should be on the type argument - assert(typeArg.annotations.size == 1) { - "Expected 1 annotation on type argument, got ${typeArg.annotations.size}: ${typeArg.annotations.map { it.classId }}" - } + assertEquals(1, typeArg.annotations.size) { "Annotations on type argument: ${typeArg.annotations.map { it.classId }}" } val annotation = typeArg.annotations.first() - assert(annotation.classId?.shortClassName?.asString() == "NotNull") { - "Expected @NotNull annotation, got ${annotation.classId}" - } + assertEquals("NotNull", annotation.classId?.shortClassName?.asString()) } @Test @@ -99,36 +94,20 @@ val field = javaClass.fields.first { it.name.asString() == "map" } val fieldType = field.type as JavaClassifierType - assert(fieldType.classifierQualifiedName == "Map") { - "Expected 'Map', got ${fieldType.classifierQualifiedName}" - } - assert(fieldType.typeArguments.size == 2) { - "Expected 2 type arguments, got ${fieldType.typeArguments.size}" - } + assertEquals("Map", fieldType.classifierQualifiedName) + assertEquals(2, fieldType.typeArguments.size) // First type argument: @NotNull String val keyArg = fieldType.typeArguments[0] as JavaClassifierType - assert(keyArg.classifierQualifiedName == "String") { - "Expected 'String', got ${keyArg.classifierQualifiedName}" - } - assert(keyArg.annotations.size == 1) { - "Expected 1 annotation on key type argument, got ${keyArg.annotations.size}" - } - assert(keyArg.annotations.first().classId?.shortClassName?.asString() == "NotNull") { - "Expected @NotNull annotation on key" - } + assertEquals("String", keyArg.classifierQualifiedName) + assertEquals(1, keyArg.annotations.size) { "Annotations on key type argument: ${keyArg.annotations.map { it.classId }}" } + assertEquals("NotNull", keyArg.annotations.first().classId?.shortClassName?.asString()) // Second type argument: @Nullable Integer val valueArg = fieldType.typeArguments[1] as JavaClassifierType - assert(valueArg.classifierQualifiedName == "Integer") { - "Expected 'Integer', got ${valueArg.classifierQualifiedName}" - } - assert(valueArg.annotations.size == 1) { - "Expected 1 annotation on value type argument, got ${valueArg.annotations.size}" - } - assert(valueArg.annotations.first().classId?.shortClassName?.asString() == "Nullable") { - "Expected @Nullable annotation on value" - } + assertEquals("Integer", valueArg.classifierQualifiedName) + assertEquals(1, valueArg.annotations.size) { "Annotations on value type argument: ${valueArg.annotations.map { it.classId }}" } + assertEquals("Nullable", valueArg.annotations.first().classId?.shortClassName?.asString()) } @Test @@ -147,20 +126,12 @@ val method = javaClass.methods.first { it.name.asString() == "getItems" } val returnType = method.returnType as JavaClassifierType - assert(returnType.classifierQualifiedName == "List") { - "Expected 'List', got ${returnType.classifierQualifiedName}" - } - assert(returnType.typeArguments.size == 1) { - "Expected 1 type argument, got ${returnType.typeArguments.size}" - } + assertEquals("List", returnType.classifierQualifiedName) + assertEquals(1, returnType.typeArguments.size) val typeArg = returnType.typeArguments[0] as JavaClassifierType - assert(typeArg.annotations.size == 1) { - "Expected 1 annotation on type argument, got ${typeArg.annotations.size}" - } - assert(typeArg.annotations.first().classId?.shortClassName?.asString() == "NotNull") { - "Expected @NotNull annotation" - } + assertEquals(1, typeArg.annotations.size) { "Annotations on type argument: ${typeArg.annotations.map { it.classId }}" } + assertEquals("NotNull", typeArg.annotations.first().classId?.shortClassName?.asString()) } @Test @@ -180,20 +151,12 @@ val param = method.valueParameters.first() val paramType = param.type as JavaClassifierType - assert(paramType.classifierQualifiedName == "List") { - "Expected 'List', got ${paramType.classifierQualifiedName}" - } - assert(paramType.typeArguments.size == 1) { - "Expected 1 type argument, got ${paramType.typeArguments.size}" - } + assertEquals("List", paramType.classifierQualifiedName) + assertEquals(1, paramType.typeArguments.size) val typeArg = paramType.typeArguments[0] as JavaClassifierType - assert(typeArg.annotations.size == 1) { - "Expected 1 annotation on type argument, got ${typeArg.annotations.size}" - } - assert(typeArg.annotations.first().classId?.shortClassName?.asString() == "NotNull") { - "Expected @NotNull annotation" - } + assertEquals(1, typeArg.annotations.size) { "Annotations on type argument: ${typeArg.annotations.map { it.classId }}" } + assertEquals("NotNull", typeArg.annotations.first().classId?.shortClassName?.asString()) } @Test @@ -212,8 +175,8 @@ val fieldType = field.type as JavaClassifierType val typeArg = fieldType.typeArguments[0] as JavaClassifierType - assert(typeArg.annotations.isEmpty()) { - "Expected no annotations on type argument, got ${typeArg.annotations.size}" + assertTrue(typeArg.annotations.isEmpty()) { + "Expected no annotations on type argument, got ${typeArg.annotations.map { it.classId }}" } } @@ -235,28 +198,24 @@ val classNode = tree.getChildren(root).first { tree.getType(it).toString() == "CLASS" } val javaClass = JavaClassOverAst(classNode, tree, parsed.context) - assert(javaClass.typeParameters.size == 2) { "Expected 2 type parameters, got ${javaClass.typeParameters.size}" } + assertEquals(2, javaClass.typeParameters.size) val paramT = javaClass.typeParameters.first { it.name.asString() == "T" } - assert(paramT.upperBounds.size == 1) { "T should have 1 upper bound, got ${paramT.upperBounds.size}" } + assertEquals(1, paramT.upperBounds.size) val boundT = paramT.upperBounds.first() - assert(boundT.classifierQualifiedName == "Object") { "T's bound should be Object, got ${boundT.classifierQualifiedName}" } + assertEquals("Object", boundT.classifierQualifiedName) // Check annotations on the bound type - assert(boundT.annotations.size == 1) { "T's bound should have 1 annotation (@NotNull), got ${boundT.annotations.size}" } - assert(boundT.annotations.first().classId?.shortClassName?.asString() == "NotNull") { - "Expected @NotNull annotation on T's bound" - } + assertEquals(1, boundT.annotations.size) { "Annotations on T's bound: ${boundT.annotations.map { it.classId }}" } + assertEquals("NotNull", boundT.annotations.first().classId?.shortClassName?.asString()) val paramU = javaClass.typeParameters.first { it.name.asString() == "U" } - assert(paramU.upperBounds.size == 1) { "U should have 1 upper bound" } + assertEquals(1, paramU.upperBounds.size) val boundU = paramU.upperBounds.first() - assert(boundU.classifierQualifiedName == "Number") { "U's bound should be Number" } + assertEquals("Number", boundU.classifierQualifiedName) - assert(boundU.annotations.size == 1) { "U's bound should have 1 annotation (@Nullable), got ${boundU.annotations.size}" } - assert(boundU.annotations.first().classId?.shortClassName?.asString() == "Nullable") { - "Expected @Nullable annotation on U's bound" - } + assertEquals(1, boundU.annotations.size) { "Annotations on U's bound: ${boundU.annotations.map { it.classId }}" } + assertEquals("Nullable", boundU.annotations.first().classId?.shortClassName?.asString()) } @Test @@ -281,19 +240,15 @@ val fooMethod = javaClass.methods.first { it.name.asString() == "foo" } val fooReturnType = fooMethod.returnType as JavaClassifierType - assert(fooReturnType.classifierQualifiedName == "T") { "foo's return type should be T" } - assert(fooReturnType.annotations.size == 1) { "foo's return type should have 1 annotation (@NotNull), got ${fooReturnType.annotations.size}" } - assert(fooReturnType.annotations.first().classId?.shortClassName?.asString() == "NotNull") { - "Expected @NotNull annotation on foo's return type" - } + assertEquals("T", fooReturnType.classifierQualifiedName) + assertEquals(1, fooReturnType.annotations.size) { "Annotations on foo's return type: ${fooReturnType.annotations.map { it.classId }}" } + assertEquals("NotNull", fooReturnType.annotations.first().classId?.shortClassName?.asString()) val barMethod = javaClass.methods.first { it.name.asString() == "bar" } val barReturnType = barMethod.returnType as JavaClassifierType - assert(barReturnType.classifierQualifiedName == "T") { "bar's return type should be T" } - assert(barReturnType.annotations.size == 1) { "bar's return type should have 1 annotation (@Nullable), got ${barReturnType.annotations.size}" } - assert(barReturnType.annotations.first().classId?.shortClassName?.asString() == "Nullable") { - "Expected @Nullable annotation on bar's return type" - } + assertEquals("T", barReturnType.classifierQualifiedName) + assertEquals(1, barReturnType.annotations.size) { "Annotations on bar's return type: ${barReturnType.annotations.map { it.classId }}" } + assertEquals("Nullable", barReturnType.annotations.first().classId?.shortClassName?.asString()) } @Test @@ -315,10 +270,8 @@ // Check that star import is extracted val starCandidate = with(context) { getFirstStarImportCandidate("NotNull") } - assert(starCandidate != null) { "Expected star import candidate for NotNull" } - assert(starCandidate?.packageFqName?.asString() == "org.jetbrains.annotations") { - "Expected package org.jetbrains.annotations, got ${starCandidate?.packageFqName}" - } + assertNotNull(starCandidate) { "Expected star import candidate for NotNull" } + assertEquals("org.jetbrains.annotations", starCandidate.packageFqName.asString()) // Find the class and method val classNode = tree.getChildren(root).first { tree.getType(it).toString() == "CLASS" } @@ -328,13 +281,13 @@ // Get the type argument (Integer with @NotNull) val typeArg = returnType.typeArguments.firstOrNull() as? JavaClassifierType - assert(typeArg != null) { "Expected type argument on Iterator" } + assertNotNull(typeArg) { "Expected type argument on Iterator" } - val allAnnotations = typeArg!!.annotations.toList() - assert(allAnnotations.size == 1) { "Expected 1 annotation on type argument, got ${allAnnotations.size}: ${allAnnotations.map { it.classId }}" } + val allAnnotations = typeArg.annotations.toList() + assertEquals(1, allAnnotations.size) { "Annotations on type argument: ${allAnnotations.map { it.classId }}" } val ann = allAnnotations.first() - assert(ann.classId?.shortClassName?.asString() == "NotNull") { "Expected NotNull annotation, got ${ann.classId}" } + assertEquals("NotNull", ann.classId?.shortClassName?.asString()) // Type-position annotations (`@NotNull` on a type argument) flow through the // `typePositionAnnotations` path of `JavaTypeOverAst.annotations`, which is returned // unconditionally — no `@Target` callback needed. @@ -362,9 +315,7 @@ // Verify star imports are extracted val starCandidate1 = with(context) { getFirstStarImportCandidate("Iterator") } - assert(starCandidate1?.packageFqName?.asString() == "java.util") { - "First star import should be java.util, got ${starCandidate1?.packageFqName}" - } + assertEquals("java.util", starCandidate1?.packageFqName?.asString()) // Find the class and method val classNode = tree.getChildren(root).first { tree.getType(it).toString() == "CLASS" } @@ -373,14 +324,14 @@ val returnType = method.returnType as JavaClassifierType // Get the type argument (Integer with @NotNull) - assert(returnType.typeArguments.size == 1) { "Expected 1 type arg, got ${returnType.typeArguments.size}" } + assertEquals(1, returnType.typeArguments.size) val typeArg = returnType.typeArguments.first() as JavaClassifierType val allAnnotations = typeArg.annotations.toList() - assert(allAnnotations.size == 1) { "Expected 1 annotation on type argument, got ${allAnnotations.size}" } + assertEquals(1, allAnnotations.size) { "Annotations on type argument: ${allAnnotations.map { it.classId }}" } val ann = allAnnotations.first() - assert(ann.classId?.shortClassName?.asString() == "NotNull") { "Expected NotNull, got ${ann.classId}" } + assertEquals("NotNull", ann.classId?.shortClassName?.asString()) // See sibling test above — type-position annotations are exposed via the // unconditional `typePositionAnnotations` path of `JavaTypeOverAst.annotations`. } @@ -403,10 +354,8 @@ val retention = javaClass.annotations.first { it.classId?.shortClassName?.asString() == "Retention" } val arg = retention.arguments.first() as JavaEnumValueAnnotationArgument - assert(arg.enumClassId?.asSingleFqName()?.asString() == "java.lang.annotation.RetentionPolicy") { - "Expected enumClassId java.lang.annotation.RetentionPolicy, got ${arg.enumClassId}" - } - assert(arg.entryName?.asString() == "RUNTIME") { "Expected entry RUNTIME, got ${arg.entryName}" } + assertEquals("java.lang.annotation.RetentionPolicy", arg.enumClassId?.asSingleFqName()?.asString()) + assertEquals("RUNTIME", arg.entryName?.asString()) } @Test @@ -428,10 +377,8 @@ // the assertion below covered the model-internal heuristic gate. Surrounding `enumClassId` / // `entryName` checks cover the user-visible invariants. - assert(arg.enumClassId?.asSingleFqName()?.asString() == "com.example.MyEnum") { - "Expected enumClassId com.example.MyEnum (same-package heuristic), got ${arg.enumClassId}" - } - assert(arg.entryName?.asString() == "A") { "Expected entry A, got ${arg.entryName}" } + assertEquals("com.example.MyEnum", arg.enumClassId?.asSingleFqName()?.asString()) { "Expected the same-package heuristic to kick in" } + assertEquals("A", arg.entryName?.asString()) } @Test @@ -455,10 +402,8 @@ val retention = javaClass.annotations.first { it.classId?.shortClassName?.asString() == "Retention" } val arg = retention.arguments.first() as JavaEnumValueAnnotationArgument - assert(arg.entryName?.asString() == "RUNTIME") { "Expected entry RUNTIME, got ${arg.entryName}" } - assert(arg.enumClassId?.asSingleFqName()?.asString() == "java.lang.annotation.RetentionPolicy") { - "Expected enumClassId java.lang.annotation.RetentionPolicy, got ${arg.enumClassId}" - } + assertEquals("RUNTIME", arg.entryName?.asString()) + assertEquals("java.lang.annotation.RetentionPolicy", arg.enumClassId?.asSingleFqName()?.asString()) } @Test @@ -479,8 +424,8 @@ val retention = javaClass.annotations.first { it.classId?.shortClassName?.asString() == "Retention" } val arg = retention.arguments.first() as JavaEnumValueAnnotationArgument - assert(arg.enumClassId == null) { "Without any import hint, enumClassId must be null, got ${arg.enumClassId}" } - assert(arg.entryName?.asString() == "RUNTIME") { "Expected entry RUNTIME, got ${arg.entryName}" } + assertNull(arg.enumClassId) { "Without any import hint, enumClassId must be null" } + assertEquals("RUNTIME", arg.entryName?.asString()) } @Test @@ -498,15 +443,15 @@ } """.trimIndent() val javaClass = parseFirstClass(source) - assert(javaClass.isDeprecatedInJavaDoc) { "Class Foo should be deprecated via JavaDoc" } + assertTrue(javaClass.isDeprecatedInJavaDoc) { "Class Foo should be deprecated via JavaDoc" } val oldMethod = javaClass.methods.first { it.name.asString() == "oldMethod" } - assert(oldMethod.isDeprecatedInJavaDoc) { "oldMethod should be deprecated via JavaDoc" } + assertTrue(oldMethod.isDeprecatedInJavaDoc) { "oldMethod should be deprecated via JavaDoc" } val newMethod = javaClass.methods.first { it.name.asString() == "newMethod" } - assert(!newMethod.isDeprecatedInJavaDoc) { "newMethod should NOT be deprecated" } + assertFalse(newMethod.isDeprecatedInJavaDoc) { "newMethod should NOT be deprecated" } val oldField = javaClass.fields.first { it.name.asString() == "oldField" } - assert(oldField.isDeprecatedInJavaDoc) { "oldField should be deprecated via JavaDoc" } + assertTrue(oldField.isDeprecatedInJavaDoc) { "oldField should be deprecated via JavaDoc" } } }
diff --git a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingBasicTest.kt b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingBasicTest.kt index 3f63aea..c3c92bd 100644 --- a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingBasicTest.kt +++ b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingBasicTest.kt
@@ -11,7 +11,11 @@ import com.intellij.java.syntax.element.JavaSyntaxTokenType import org.jetbrains.kotlin.java.direct.model.JavaClassOverAst import org.jetbrains.kotlin.java.direct.parse.JavaLightNode +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertNotNull class JavaParsingBasicTest : JavaParsingTestBase() { @@ -19,19 +23,19 @@ fun testBasicJavaParsing() { val source = "public final class A {}" val javaClass = parseFirstClass(source) - assert(javaClass.name.asString() == "A") - assert(javaClass.isFinal) - assert(!javaClass.isAbstract) - assert(javaClass.visibility.toString() == "public") + assertEquals("A", javaClass.name.asString()) + assertTrue(javaClass.isFinal) + assertFalse(javaClass.isAbstract) + assertEquals("public", javaClass.visibility.toString()) } @Test fun testAbstractInterface() { val source = "interface I {}" val javaClass = parseFirstClass(source) - assert(javaClass.name.asString() == "I") - assert(javaClass.isInterface) - assert(javaClass.isAbstract) + assertEquals("I", javaClass.name.asString()) + assertTrue(javaClass.isInterface) + assertTrue(javaClass.isAbstract) } @Test @@ -41,7 +45,7 @@ class A {} """.trimIndent() val javaClass = parseFirstClass(source) - assert(javaClass.fqName.asString() == "com.example.A") + assertEquals("com.example.A", javaClass.fqName.asString()) } @Test @@ -57,11 +61,10 @@ val tree = parsed.tree val packageStmt = tree.findChildByType(parsed.root, JavaSyntaxElementType.PACKAGE_STATEMENT) - assert(packageStmt != null) { "Expected PACKAGE_STATEMENT node" } - val packageName = packageStmt?.let { - tree.findChildByType(it, JavaSyntaxElementType.JAVA_CODE_REFERENCE)?.let { ref -> tree.getText(ref).toString() } - } - assert(packageName == "example") { "Expected 'example', got $packageName" } + assertNotNull(packageStmt, "Expected PACKAGE_STATEMENT node") + val packageName = + tree.findChildByType(packageStmt, JavaSyntaxElementType.JAVA_CODE_REFERENCE)?.let { ref -> tree.getText(ref).toString() } + assertEquals("example", packageName) } @Test @@ -94,21 +97,21 @@ } val fooTypeNode = tree.findChildByType(fooMethod, JavaSyntaxElementType.TYPE)!! val fooTypes = collectTypes(fooTypeNode) - assert(fooTypes.any { it == "QUEST" }) { "foo should have QUEST in: $fooTypes" } + assertTrue(fooTypes.any { it == "QUEST" }, "foo should have QUEST in: $fooTypes") val barMethod = methods.first { tree.findChildByType(it, JavaSyntaxTokenType.IDENTIFIER)?.let { id -> tree.getText(id).toString() } == "bar" } val barTypeNode = tree.findChildByType(barMethod, JavaSyntaxElementType.TYPE)!! val barTypes = collectTypes(barTypeNode) - assert(barTypes.any { it == "QUEST" }) { "bar should have QUEST in: $barTypes" } + assertTrue(barTypes.any { it == "QUEST" }, "bar should have QUEST in: $barTypes") val bazMethod = methods.first { tree.findChildByType(it, JavaSyntaxTokenType.IDENTIFIER)?.let { id -> tree.getText(id).toString() } == "baz" } val bazTypeNode = tree.findChildByType(bazMethod, JavaSyntaxElementType.TYPE)!! val bazTypes = collectTypes(bazTypeNode) - assert(bazTypes.any { it == "QUEST" }) { "baz should have QUEST in: $bazTypes" } - assert(bazTypes.any { it == "SUPER_KEYWORD" }) { "baz should have SUPER_KEYWORD in: $bazTypes" } + assertTrue(bazTypes.any { it == "QUEST" }, "baz should have QUEST in: $bazTypes") + assertTrue(bazTypes.any { it == "SUPER_KEYWORD" }, "baz should have SUPER_KEYWORD in: $bazTypes") } }
diff --git a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingClassFinderTest.kt b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingClassFinderTest.kt index aa52406..80b8a62 100644 --- a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingClassFinderTest.kt +++ b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingClassFinderTest.kt
@@ -15,7 +15,13 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertSame +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertNotNull import org.junit.jupiter.api.io.TempDir import java.nio.file.Path import kotlin.io.path.writeText @@ -42,7 +48,7 @@ simpleName: String, ): ClassId? { val containingClass = finder.findClass(JavaClassFinder.Request(containingClassId)) - assert(containingClass is JavaClassOverAst) { "Expected to find source class $containingClassId" } + assertTrue(containingClass is JavaClassOverAst, "Expected to find source class $containingClassId") containingClass as JavaClassOverAst return with(containingClass.resolutionContext) { resolveInheritedInnerClassToClassId(simpleName, containingClass) @@ -81,24 +87,24 @@ // Test package with classes - should return class names val comExampleClasses = finder.knownClassNamesInPackage(FqName("com.example")) - assert(comExampleClasses.size == 2) { "Expected 2 classes in com.example, got ${comExampleClasses.size}" } - assert("ClassA" in comExampleClasses) { "Expected ClassA in com.example" } - assert("ClassB" in comExampleClasses) { "Expected ClassB in com.example" } + assertEquals(2, comExampleClasses.size) + assertTrue("ClassA" in comExampleClasses, "Expected ClassA in com.example") + assertTrue("ClassB" in comExampleClasses, "Expected ClassB in com.example") val testClasses = finder.knownClassNamesInPackage(FqName("test")) - assert(testClasses.size == 1) { "Expected 1 class in test, got ${testClasses.size}" } - assert("ClassC" in testClasses) { "Expected ClassC in test" } + assertEquals(1, testClasses.size) + assertTrue("ClassC" in testClasses, "Expected ClassC in test") // Test package NOT in our index - should return empty set (not null) val kotlinPackageClasses = finder.knownClassNamesInPackage(FqName("kotlin")) - assert(kotlinPackageClasses.isEmpty()) { "Expected empty set for package kotlin, got $kotlinPackageClasses" } + assertTrue(kotlinPackageClasses.isEmpty(), "Expected empty set for package kotlin, got $kotlinPackageClasses") val javaLangClasses = finder.knownClassNamesInPackage(FqName("java.lang")) - assert(javaLangClasses.isEmpty()) { "Expected empty set for package java.lang, got $javaLangClasses" } + assertTrue(javaLangClasses.isEmpty(), "Expected empty set for package java.lang, got $javaLangClasses") // Test non-existent package - should also return empty set val nonExistentClasses = finder.knownClassNamesInPackage(FqName("does.not.exist")) - assert(nonExistentClasses.isEmpty()) { "Expected empty set for non-existent package" } + assertTrue(nonExistentClasses.isEmpty(), "Expected empty set for non-existent package") } @Test @@ -124,9 +130,9 @@ val request = JavaClassFinder.Request(classId) val javaClass = finder.findClass(request) - assert(javaClass != null) { "Expected to find example.Hello class" } - assert(javaClass?.name?.asString() == "Hello") { "Expected class name 'Hello', got ${javaClass?.name?.asString()}" } - assert(javaClass?.fqName?.asString() == "example.Hello") { "Expected fqName 'example.Hello', got ${javaClass?.fqName?.asString()}" } + assertNotNull(javaClass, "Expected to find example.Hello class") + assertEquals("Hello", javaClass.name.asString()) + assertEquals("example.Hello", javaClass.fqName?.asString()) } @Test @@ -170,30 +176,27 @@ // Verify NotNull.java is indexed val annotationPackageClasses = finder.knownClassNamesInPackage(FqName("org.jetbrains.annotations")) - assert("NotNull" in annotationPackageClasses) { + assertTrue( + "NotNull" in annotationPackageClasses, "NotNull should be in org.jetbrains.annotations, found: $annotationPackageClasses" - } + ) // Verify we can find the annotation class val notNullClassId = ClassId(FqName("org.jetbrains.annotations"), Name.identifier("NotNull")) val notNullClass = finder.findClass(JavaClassFinder.Request(notNullClassId)) - assert(notNullClass != null) { "Should find NotNull class" } - assert(notNullClass!!.isAnnotationType) { "NotNull should be an annotation type" } + assertNotNull(notNullClass, "Should find NotNull class") + assertTrue(notNullClass.isAnnotationType, "NotNull should be an annotation type") // Check that NotNull has @Target annotation with TYPE_USE val allAnnotations = notNullClass.annotations.toList() - assert(allAnnotations.isNotEmpty()) { - "NotNull should have annotations, but found none" - } + assertTrue(allAnnotations.isNotEmpty(), "NotNull should have annotations, but found none") val targetAnnotation = allAnnotations.find { val classId = it.classId classId?.shortClassName?.asString() == "Target" || classId?.asSingleFqName()?.asString() == "java.lang.annotation.Target" } - assert(targetAnnotation != null) { - "NotNull should have @Target annotation, found: ${allAnnotations.map { it.classId }}" - } + assertNotNull(targetAnnotation, "NotNull should have @Target annotation, found: ${allAnnotations.map { it.classId }}") } @Test @@ -236,9 +239,7 @@ val simpleDescId = ClassId(FqName("test"), Name.identifier("SimpleFunctionDescriptor")) val copyBuilderId = resolveInheritedNestedClass(finder, simpleDescId, "CopyBuilder") - assert(copyBuilderId?.asString() == "test/FunctionDescriptor.CopyBuilder") { - "Expected CopyBuilder of SimpleFunctionDescriptor to resolve to test.FunctionDescriptor.CopyBuilder, got $copyBuilderId" - } + assertEquals("test/FunctionDescriptor.CopyBuilder", copyBuilderId?.asString()) } @Test @@ -276,9 +277,7 @@ // Verify inherited inner class resolution works cross-package (star import in impl) val funcDescImplId = ClassId(FqName("base.impl"), Name.identifier("FunctionDescriptorImpl")) val userDataKeyId = resolveInheritedNestedClass(finder, funcDescImplId, "UserDataKey") - assert(userDataKeyId?.asString() == "base/FunctionDescriptor.UserDataKey") { - "Expected UserDataKey of FunctionDescriptorImpl to resolve to base.FunctionDescriptor.UserDataKey, got $userDataKeyId" - } + assertEquals("base/FunctionDescriptor.UserDataKey", userDataKeyId?.asString()) } @Test @@ -306,9 +305,7 @@ val childId = ClassId(FqName("test"), Name.identifier("Child")) for (innerName in listOf("InnerA", "InnerB")) { val resolved = resolveInheritedNestedClass(finder, childId, innerName) - assert(resolved == ClassId(FqName("test"), FqName("Parent.$innerName"), isLocal = false)) { - "Expected $innerName of Child to resolve to test.Parent.$innerName, got $resolved" - } + assertEquals(ClassId(FqName("test"), FqName("Parent.$innerName"), isLocal = false), resolved) } } @@ -332,22 +329,22 @@ // First lookup: Outer val outerId = ClassId(FqName("pkg"), Name.identifier("Outer")) val outer1 = finder.findClass(JavaClassFinder.Request(outerId)) - assert(outer1 != null) { "Expected to find pkg.Outer" } + assertNotNull(outer1, "Expected to find pkg.Outer") // Second lookup: same ClassId — must be the exact same instance val outer2 = finder.findClass(JavaClassFinder.Request(outerId)) - assert(outer1 === outer2) { "Repeated findClass must return the same JavaClassOverAst instance" } + assertSame(outer1, outer2, "Repeated findClass must return the same JavaClassOverAst instance") // Lookup via inner class: navigating Outer.Inner should reference the same Outer val innerId = ClassId(FqName("pkg"), FqName("Outer.Inner"), isLocal = false) val inner = finder.findClass(JavaClassFinder.Request(innerId)) - assert(inner != null) { "Expected to find pkg.Outer.Inner" } - assert(inner!!.outerClass === outer1) { "Inner class's outerClass must be the same Outer instance" } + assertNotNull(inner, "Expected to find pkg.Outer.Inner") + assertSame(outer1, inner.outerClass, "Inner class's outerClass must be the same Outer instance") // Type parameters on both references must be object-identical val tp1 = (outer1 as JavaClassOverAst).typeParameters.single() val tp2 = (outer2 as JavaClassOverAst).typeParameters.single() - assert(tp1 === tp2) { "Type parameter instances must be identical (===) across lookups" } + assertSame(tp1, tp2, "Type parameter instances must be identical (===) across lookups") } @Test @@ -395,13 +392,11 @@ // The simple name "Conflict" should resolve to Base.Conflict (inherited inner), // not to the top-level pkg.Conflict. val classifier = fieldType.classifier - assert(classifier != null) { "Conflict should resolve locally" } + assertNotNull(classifier, "Conflict should resolve locally") // Inner class's outer class must be Base val outerClass = (classifier as? JavaClassOverAst)?.outerClass - assert(outerClass != null && outerClass.name.asString() == "Base") { - "Expected Conflict to resolve to Base.Conflict (inner class), " + - "but outerClass=${outerClass?.name}" - } + assertNotNull(outerClass, "Expected Conflict to resolve to Base.Conflict (inner class), but it has no outer class") + assertEquals("Base", outerClass.name.asString(), "Expected Conflict to resolve to Base.Conflict (inner class)") } @Test @@ -455,15 +450,11 @@ val singleId = ClassId(FqName("pkg"), Name.identifier("Single")) val resolved = resolveInheritedNestedClass(finder, singleId, "Inner") - assert(resolved == ClassId(FqName("pkg"), FqName("Left.Inner"), isLocal = false)) { - "Expected Inner of Single to resolve to pkg.Left.Inner, got $resolved" - } + assertEquals(ClassId(FqName("pkg"), FqName("Left.Inner"), isLocal = false), resolved) val ambiguousId = ClassId(FqName("pkg"), Name.identifier("Ambiguous")) val ambiguous = resolveInheritedNestedClass(finder, ambiguousId, "Inner") - assert(ambiguous == null) { - "Expected Inner of Ambiguous to be ambiguous (null), got $ambiguous" - } + assertNull(ambiguous, "Inner is declared by two unrelated ancestors, so it must stay unresolved (JLS 8.5)") } @Test @@ -500,10 +491,11 @@ val derivedId = ClassId(FqName("a"), Name.identifier("Derived")) val resolved = resolveInheritedNestedClass(finder, derivedId, "N") - assert(resolved == ClassId(FqName("a"), FqName("B.C.N"), isLocal = false)) { - "Expected 'extends B<String>.C' to keep the qualified nested supertype, so that N " + - "resolves to a.B.C.N, got $resolved" - } + assertEquals( + ClassId(FqName("a"), FqName("B.C.N"), isLocal = false), + resolved, + "Expected 'extends B<String>.C' to keep the qualified nested supertype, so that N resolves to a.B.C.N" + ) } @Test @@ -525,16 +517,17 @@ val finder = JavaClassFinderOverAstImpl(listOf(tempDir.toFile())) val targetId = ClassId(FqName("pkg"), Name.identifier("Target")) val direct = finder.findClass(JavaClassFinder.Request(targetId)) - assert(direct != null) { "Expected to find pkg.Target" } + assertNotNull(direct, "Expected to find pkg.Target") val tree = parseJavaToLightTree("package pkg;\nclass Dummy {}", 0) val context = JavaResolutionContext.create(tree, createDummyFirSessionForTests(), classFinder = finder) val viaAdapter = with(context) { classifierAdapterFor(targetId) } - assert(viaAdapter === direct) { - "Expected classifierAdapterFor to route the source-backed ClassId to the canonical " + - "JavaClassOverAst instance, got a different object: $viaAdapter" - } + assertSame( + direct, + viaAdapter, + "Expected classifierAdapterFor to route the source-backed ClassId to the canonical JavaClassOverAst instance" + ) } @Test @@ -554,15 +547,16 @@ // knownClassNamesInPackage should expose only "Main", not "Helper" val knownNames = finder.knownClassNamesInPackage(FqName("pkg")) - assert("Main" in knownNames) { "Expected Main in known names, got $knownNames" } - assert("Helper" !in knownNames) { + assertTrue("Main" in knownNames, "Expected Main in known names, got $knownNames") + assertFalse( + "Helper" in knownNames, "Helper is a non-canonical class (in Main.java) and must NOT appear in knownClassNamesInPackage, got $knownNames" - } + ) // But Helper should still be findable by direct ClassId lookup val helperId = ClassId(FqName("pkg"), Name.identifier("Helper")) val helper = finder.findClass(JavaClassFinder.Request(helperId)) - assert(helper != null) { "Expected to find pkg.Helper by direct ClassId lookup" } - assert(helper!!.name.asString() == "Helper") { "Expected name 'Helper', got ${helper.name}" } + assertNotNull(helper, "Expected to find pkg.Helper by direct ClassId lookup") + assertEquals("Helper", helper.name.asString()) } }
diff --git a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingLightweightScannerTest.kt b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingLightweightScannerTest.kt index b91c6d6..fe075c1 100644 --- a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingLightweightScannerTest.kt +++ b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingLightweightScannerTest.kt
@@ -10,7 +10,11 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertNotNull import org.junit.jupiter.api.io.TempDir import java.nio.file.Path import kotlin.io.path.writeText @@ -31,9 +35,9 @@ ) val info = extractFileInfoLightweight(file.toFile()) - assert(info != null) { "Expected non-null LightweightFileInfo" } - assert(info!!.packageName == "com.example") { "Expected package 'com.example', got '${info.packageName}'" } - assert(info.topLevelClassNames == setOf("Foo")) { "Expected {Foo}, got ${info.topLevelClassNames}" } + assertNotNull(info) + assertEquals("com.example", info.packageName) + assertEquals(setOf("Foo"), info.topLevelClassNames) } @Test @@ -50,9 +54,79 @@ ) val info = extractFileInfoLightweight(file.toFile()) - assert(info != null) { "Expected non-null LightweightFileInfo" } - assert(info!!.packageName == "com.example") { "Expected package 'com.example', got '${info.packageName}'" } - assert(info.topLevelClassNames == setOf("Foo")) { "Expected {Foo}, got ${info.topLevelClassNames}" } + assertNotNull(info) + assertEquals("com.example", info.packageName) + assertEquals(setOf("Foo"), info.topLevelClassNames) + } + + @Test + fun testLightweightScannerPackageWithCommentsBetweenSegments(@TempDir tempDir: Path) { + // Comments and line breaks are allowed anywhere between the segments of a package name. + val file = tempDir.resolve("Foo.java") + file.writeText( + """ + package builder // line comment + . /* block comment */ subpackage; + + public class Foo {} + """.trimIndent() + ) + + val info = extractFileInfoLightweight(file.toFile()) + assertNotNull(info) + assertEquals("builder.subpackage", info.packageName) + assertEquals(setOf("Foo"), info.topLevelClassNames) + } + + @Test + fun testLightweightScannerMalformedPackageName(@TempDir tempDir: Path) { + // `com.123` is not a valid package name: the scan stops at the malformed segment without + // emitting a trailing dot, and still indexes the file's classes. + val file = tempDir.resolve("Foo.java") + file.writeText( + """ + package com.123; + + public class Foo {} + """.trimIndent() + ) + + val info = extractFileInfoLightweight(file.toFile()) + assertNotNull(info) + assertEquals("com", info.packageName) + assertEquals(setOf("Foo"), info.topLevelClassNames) + } + + @Test + fun testLightweightScannerMalformedClassName(@TempDir tempDir: Path) { + val file = tempDir.resolve("Valid.java") + file.writeText( + """ + package test; + + class 456 {} + class Valid {} + """.trimIndent() + ) + + val info = extractFileInfoLightweight(file.toFile()) + assertNotNull(info) + assertEquals("test", info.packageName) + assertEquals(setOf("Valid"), info.topLevelClassNames) + } + + @Test + fun testLightweightScannerOnlyMalformedClassName(@TempDir tempDir: Path) { + val file = tempDir.resolve("Broken.java") + file.writeText( + """ + package test; + + class 456 {} + """.trimIndent() + ) + + assertNull(extractFileInfoLightweight(file.toFile())) } @Test @@ -65,9 +139,9 @@ ) val info = extractFileInfoLightweight(file.toFile()) - assert(info != null) { "Expected non-null LightweightFileInfo" } - assert(info!!.packageName == null) { "Expected null package (default), got '${info.packageName}'" } - assert(info.topLevelClassNames == setOf("Bar")) { "Expected {Bar}, got ${info.topLevelClassNames}" } + assertNotNull(info) + assertNull(info.packageName) + assertEquals(setOf("Bar"), info.topLevelClassNames) } @Test @@ -85,11 +159,9 @@ ) val info = extractFileInfoLightweight(file.toFile()) - assert(info != null) { "Expected non-null LightweightFileInfo" } - assert(info!!.packageName == "test") { "Expected package 'test', got '${info.packageName}'" } - assert(info.topLevelClassNames == setOf("Multi", "Helper", "Service", "Color")) { - "Expected {Multi, Helper, Service, Color}, got ${info.topLevelClassNames}" - } + assertNotNull(info) + assertEquals("test", info.packageName) + assertEquals(setOf("Multi", "Helper", "Service", "Color"), info.topLevelClassNames) } @Test @@ -112,10 +184,8 @@ ) val info = extractFileInfoLightweight(file.toFile()) - assert(info != null) { "Expected non-null LightweightFileInfo" } - assert(info!!.topLevelClassNames == setOf("Comments")) { - "Expected only {Comments}, got ${info.topLevelClassNames}" - } + assertNotNull(info) + assertEquals(setOf("Comments"), info.topLevelClassNames) } @Test @@ -134,10 +204,8 @@ ) val info = extractFileInfoLightweight(file.toFile()) - assert(info != null) { "Expected non-null LightweightFileInfo" } - assert(info!!.topLevelClassNames == setOf("Outer")) { - "Expected only {Outer}, got ${info.topLevelClassNames}" - } + assertNotNull(info) + assertEquals(setOf("Outer"), info.topLevelClassNames) } @Test @@ -156,10 +224,8 @@ ) val info = extractFileInfoLightweight(file.toFile()) - assert(info != null) { "Expected non-null LightweightFileInfo" } - assert(info!!.topLevelClassNames == setOf("BlockComment")) { - "Expected only {BlockComment}, got ${info.topLevelClassNames}" - } + assertNotNull(info) + assertEquals(setOf("BlockComment"), info.topLevelClassNames) } @Test @@ -174,9 +240,9 @@ ) val info = extractFileInfoLightweight(file.toFile()) - assert(info != null) { "Expected non-null LightweightFileInfo" } - assert(info!!.packageName == "geometry") { "Expected package 'geometry', got '${info.packageName}'" } - assert(info.topLevelClassNames == setOf("Point")) { "Expected {Point}, got ${info.topLevelClassNames}" } + assertNotNull(info) + assertEquals("geometry", info.packageName) + assertEquals(setOf("Point"), info.topLevelClassNames) } @Test @@ -189,8 +255,7 @@ """.trimIndent() ) - val info = extractFileInfoLightweight(file.toFile()) - assert(info == null) { "Expected null for file with no class declarations" } + assertNull(extractFileInfoLightweight(file.toFile())) } @Test @@ -207,12 +272,10 @@ ) val info = extractFileInfoLightweight(file.toFile()) - assert(info != null) { "Expected non-null LightweightFileInfo" } - assert(info!!.packageName == "annotations") { "Expected 'annotations', got '${info.packageName}'" } + assertNotNull(info) + assertEquals("annotations", info.packageName) // @interface declares a type named MyAnnotation — the scanner extracts "MyAnnotation" from "interface MyAnnotation" - assert("MyAnnotation" in info.topLevelClassNames) { - "Expected MyAnnotation in class names, got ${info.topLevelClassNames}" - } + assertTrue("MyAnnotation" in info.topLevelClassNames) { "got ${info.topLevelClassNames}" } } @Test @@ -233,11 +296,9 @@ ) val info = extractFileInfoLightweight(file.toFile()) - assert(info != null) { "Expected non-null LightweightFileInfo" } - assert(info!!.packageName == "com.example") { "Expected package 'com.example', got '${info.packageName}'" } - assert(info.topLevelClassNames == setOf("Broken", "Foo")) { - "Expected {Broken, Foo}, got ${info.topLevelClassNames}" - } + assertNotNull(info) + assertEquals("com.example", info.packageName) + assertEquals(setOf("Broken", "Foo"), info.topLevelClassNames) } @Test @@ -256,10 +317,8 @@ ) val info = extractFileInfoLightweight(file.toFile()) - assert(info != null) { "Expected non-null LightweightFileInfo" } - assert(info!!.topLevelClassNames == setOf("Foo", "Bar")) { - "Expected {Foo, Bar}, got ${info.topLevelClassNames}" - } + assertNotNull(info) + assertEquals(setOf("Foo", "Bar"), info.topLevelClassNames) } @Test @@ -282,9 +341,9 @@ val request = JavaClassFinder.Request(classId) val javaClass = finder.findClass(request) - assert(javaClass != null) { "Expected to find Small class" } - assert(javaClass?.name?.asString() == "Small") { "Expected name 'Small'" } - assert(javaClass?.fields?.size == 1) { "Expected 1 field, got ${javaClass?.fields?.size}" } + assertNotNull(javaClass) + assertEquals("Small", javaClass.name.asString()) + assertEquals(1, javaClass.fields.size) } @Test @@ -309,10 +368,10 @@ val mainClass = finder.findClass(JavaClassFinder.Request(mainId)) val helperClass = finder.findClass(JavaClassFinder.Request(helperId)) - assert(mainClass != null) { "Expected to find Main class" } - assert(helperClass != null) { "Expected to find Helper class" } - assert(mainClass?.name?.asString() == "Main") - assert(helperClass?.name?.asString() == "Helper") + assertNotNull(mainClass) + assertNotNull(helperClass) + assertEquals("Main", mainClass.name.asString()) + assertEquals("Helper", helperClass.name.asString()) } @Test @@ -331,7 +390,7 @@ } sb.appendLine("}") val largeContent = sb.toString() - assert(largeContent.toByteArray().size > 4096) { "Test file should be > 4KB" } + assertTrue(largeContent.toByteArray().size > 4096) { "Test file should be > 4KB" } pkgDir.resolve("Large.java").writeText(largeContent) @@ -342,9 +401,9 @@ val request = JavaClassFinder.Request(classId) val javaClass = finder.findClass(request) - assert(javaClass != null) { "Expected to find Large class" } - assert(javaClass?.name?.asString() == "Large") { "Expected name 'Large'" } - assert(javaClass?.fields?.size == 200) { "Expected 200 fields, got ${javaClass?.fields?.size}" } + assertNotNull(javaClass) + assertEquals("Large", javaClass.name.asString()) + assertEquals(200, javaClass.fields.size) } @Test @@ -362,7 +421,7 @@ sb.appendLine("}") sb.appendLine("class BigHelper {}") val largeContent = sb.toString() - assert(largeContent.toByteArray().size > 4096) { "Test file should be > 4KB" } + assertTrue(largeContent.toByteArray().size > 4096) { "Test file should be > 4KB" } pkgDir.resolve("BigMain.java").writeText(largeContent) @@ -372,11 +431,9 @@ val mainId = ClassId(FqName("test"), Name.identifier("BigMain")) val helperId = ClassId(FqName("test"), Name.identifier("BigHelper")) - val mainClass = finder.findClass(JavaClassFinder.Request(mainId)) - assert(mainClass != null) { "Expected to find BigMain class" } + assertNotNull(finder.findClass(JavaClassFinder.Request(mainId))) // BigHelper should also be cached from the same parse (no additional file I/O) - val helperClass = finder.findClass(JavaClassFinder.Request(helperId)) - assert(helperClass != null) { "Expected to find BigHelper class" } + assertNotNull(finder.findClass(JavaClassFinder.Request(helperId))) } }
diff --git a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingMembersTest.kt b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingMembersTest.kt index 7e8abb8..b92be41 100644 --- a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingMembersTest.kt +++ b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingMembersTest.kt
@@ -9,6 +9,10 @@ import org.jetbrains.kotlin.load.java.structure.JavaArrayType import org.jetbrains.kotlin.load.java.structure.JavaClassifierType import org.jetbrains.kotlin.load.java.structure.JavaPrimitiveType +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test class JavaParsingMembersTest : JavaParsingTestBase() { @@ -24,14 +28,14 @@ """.trimIndent() val javaClass = parseFirstClass(source) - assert(javaClass.fields.size == 1) - assert(javaClass.fields.first().name.asString() == "field") + assertEquals(1, javaClass.fields.size) + assertEquals("field", javaClass.fields.first().name.asString()) - assert(javaClass.methods.size == 1) - assert(javaClass.methods.first().name.asString() == "method") + assertEquals(1, javaClass.methods.size) + assertEquals("method", javaClass.methods.first().name.asString()) - assert(javaClass.constructors.size == 1) - assert(javaClass.constructors.first().name.asString() == "A") + assertEquals(1, javaClass.constructors.size) + assertEquals("A", javaClass.constructors.first().name.asString()) } @Test @@ -41,9 +45,9 @@ """.trimIndent() val javaClass1 = parseFirstClass(sourceWithoutConstructor) - assert(javaClass1.constructors.isEmpty()) { "Expected no explicit constructors" } - assert(javaClass1.hasDefaultConstructor()) { "Expected hasDefaultConstructor() = true for class without explicit constructor" } - assert(!javaClass1.isInterface) { "A is not an interface" } + assertTrue(javaClass1.constructors.isEmpty(), "Expected no explicit constructors") + assertTrue(javaClass1.hasDefaultConstructor(), "Expected hasDefaultConstructor() = true for class without explicit constructor") + assertFalse(javaClass1.isInterface, "A is not an interface") val sourceWithConstructor = """ public class B { @@ -52,17 +56,17 @@ """.trimIndent() val javaClass2 = parseFirstClass(sourceWithConstructor) - assert(javaClass2.constructors.size == 1) { "Expected 1 explicit constructor, got ${javaClass2.constructors.size}" } - assert(!javaClass2.hasDefaultConstructor()) { "Expected hasDefaultConstructor() = false for class with explicit constructor" } + assertEquals(1, javaClass2.constructors.size) + assertFalse(javaClass2.hasDefaultConstructor(), "Expected hasDefaultConstructor() = false for class with explicit constructor") val sourceInterface = """ public interface I {} """.trimIndent() val javaClass3 = parseFirstClass(sourceInterface) - assert(javaClass3.constructors.isEmpty()) { "Expected no constructors for interface" } - assert(!javaClass3.hasDefaultConstructor()) { "Expected hasDefaultConstructor() = false for interface" } - assert(javaClass3.isInterface) { "I should be an interface" } + assertTrue(javaClass3.constructors.isEmpty(), "Expected no constructors for interface") + assertFalse(javaClass3.hasDefaultConstructor(), "Expected hasDefaultConstructor() = false for interface") + assertTrue(javaClass3.isInterface, "I should be an interface") } @Test @@ -74,13 +78,13 @@ """.trimIndent() val javaClass = parseFirstClass(source) - assert(javaClass.methods.size == 1) { "Expected 1 method, got ${javaClass.methods.size}" } + assertEquals(1, javaClass.methods.size) val method = javaClass.methods.first() - assert(method.name.asString() == "method") + assertEquals("method", method.name.asString()) val returnType = method.returnType - assert(returnType is JavaPrimitiveType) { "Expected JavaPrimitiveType, got ${returnType::class.java}" } - assert((returnType as JavaPrimitiveType).type == null) { "Expected type=null for void, got ${returnType.type}" } + assertTrue(returnType is JavaPrimitiveType, "Expected JavaPrimitiveType, got ${returnType::class.java}") + assertNull((returnType as JavaPrimitiveType).type, "A void return type must be a JavaPrimitiveType with no primitive kind") } @Test @@ -99,43 +103,43 @@ val javaClass = parseFirstClass(source) val method1 = javaClass.methods.first { it.name.asString() == "method1" } - assert(method1.valueParameters.isEmpty()) { "method1 should have 0 parameters, got ${method1.valueParameters.size}" } + assertTrue(method1.valueParameters.isEmpty(), "method1 should have 0 parameters, got ${method1.valueParameters.size}") val method2 = javaClass.methods.first { it.name.asString() == "method2" } - assert(method2.valueParameters.size == 1) { "method2 should have 1 parameter, got ${method2.valueParameters.size}" } + assertEquals(1, method2.valueParameters.size) val param2 = method2.valueParameters.first() - assert(param2.name?.asString() == "a") { "Expected parameter name 'a', got ${param2.name}" } - assert(param2.type is JavaPrimitiveType) { "Expected int to be JavaPrimitiveType" } + assertEquals("a", param2.name?.asString()) + assertTrue(param2.type is JavaPrimitiveType, "Expected int to be JavaPrimitiveType") val method3 = javaClass.methods.first { it.name.asString() == "method3" } - assert(method3.valueParameters.size == 3) { "method3 should have 3 parameters, got ${method3.valueParameters.size}" } + assertEquals(3, method3.valueParameters.size) val params3 = method3.valueParameters.toList() - assert(params3[0].name?.asString() == "a") { "Expected parameter name 'a', got ${params3[0].name}" } - assert(params3[1].name?.asString() == "b") { "Expected parameter name 'b', got ${params3[1].name}" } - assert(params3[2].name?.asString() == "c") { "Expected parameter name 'c', got ${params3[2].name}" } + assertEquals("a", params3[0].name?.asString()) + assertEquals("b", params3[1].name?.asString()) + assertEquals("c", params3[2].name?.asString()) val paramAType = params3[0].type as JavaClassifierType - assert(paramAType.classifierQualifiedName == "String") { "Expected String, got ${paramAType.classifierQualifiedName}" } + assertEquals("String", paramAType.classifierQualifiedName) val paramBType = params3[1].type as JavaPrimitiveType - assert(paramBType.type == PrimitiveType.INT) { "Expected INT primitive type" } + assertEquals(PrimitiveType.INT, paramBType.type) val paramCType = params3[2].type as JavaClassifierType - assert(paramCType.classifierQualifiedName == "List") { "Expected List, got ${paramCType.classifierQualifiedName}" } + assertEquals("List", paramCType.classifierQualifiedName) val constructor0 = javaClass.constructors.first { it.valueParameters.isEmpty() } - assert(constructor0.valueParameters.isEmpty()) { "Constructor should have 0 parameters" } + assertTrue(constructor0.valueParameters.isEmpty(), "Constructor should have 0 parameters") val constructor1 = javaClass.constructors.first { it.valueParameters.size == 1 } - assert(constructor1.valueParameters.size == 1) { "Constructor should have 1 parameter, got ${constructor1.valueParameters.size}" } + assertEquals(1, constructor1.valueParameters.size) val constParam1 = constructor1.valueParameters.first() - assert(constParam1.name?.asString() == "x") { "Expected parameter name 'x', got ${constParam1.name}" } + assertEquals("x", constParam1.name?.asString()) val constructor2 = javaClass.constructors.first { it.valueParameters.size == 2 } - assert(constructor2.valueParameters.size == 2) { "Constructor should have 2 parameters, got ${constructor2.valueParameters.size}" } + assertEquals(2, constructor2.valueParameters.size) val constParams2 = constructor2.valueParameters.toList() - assert(constParams2[0].name?.asString() == "s") { "Expected parameter name 's', got ${constParams2[0].name}" } - assert(constParams2[1].name?.asString() == "o") { "Expected parameter name 'o', got ${constParams2[1].name}" } + assertEquals("s", constParams2[0].name?.asString()) + assertEquals("o", constParams2[1].name?.asString()) } @Test @@ -148,14 +152,14 @@ val javaClass = parseFirstClass(source) val equalsMethod = javaClass.methods.first { it.name.asString() == "equals" } - assert(equalsMethod.valueParameters.size == 1) { "equals should have 1 parameter, got ${equalsMethod.valueParameters.size}" } + assertEquals(1, equalsMethod.valueParameters.size) val param = equalsMethod.valueParameters.first() - assert(param.name?.asString() == "o") { "Expected parameter name 'o', got ${param.name}" } + assertEquals("o", param.name?.asString()) val paramType = param.type as JavaClassifierType - assert(paramType.classifierQualifiedName == "Object") { "Expected 'Object', got '${paramType.classifierQualifiedName}'" } - assert(paramType.classifier == null) { "Object should have null classifier without a wired symbol provider" } + assertEquals("Object", paramType.classifierQualifiedName) + assertNull(paramType.classifier, "Object should have null classifier without a wired symbol provider") } @Test @@ -169,8 +173,8 @@ val javaClass = parseFirstClass(source) val nativeMethod = javaClass.methods.first { it.name.asString() == "nativeMethod" } val normalMethod = javaClass.methods.first { it.name.asString() == "normalMethod" } - assert(nativeMethod.isNative) { "nativeMethod should have isNative=true" } - assert(!normalMethod.isNative) { "normalMethod should have isNative=false" } + assertTrue(nativeMethod.isNative, "nativeMethod should have isNative=true") + assertFalse(normalMethod.isNative, "normalMethod should have isNative=false") } @Test @@ -178,9 +182,9 @@ val source = "public class Foo { public Foo() {} }" val javaClass = parseFirstClass(source) val ctor = javaClass.constructors.single() - assert(ctor.isFinal) { "Constructor should be implicitly final" } - assert(!ctor.isAbstract) { "Constructor should not be abstract" } - assert(!ctor.isStatic) { "Constructor should not be static" } + assertTrue(ctor.isFinal, "Constructor should be implicitly final") + assertFalse(ctor.isAbstract, "Constructor should not be abstract") + assertFalse(ctor.isStatic, "Constructor should not be static") } @Test @@ -200,16 +204,14 @@ // All fields in a multi-field declaration share the same modifiers for (field in listOf(errorField, eofField, eolField)) { - assert(field.isStatic) { "${field.name} should be static" } - assert(field.isFinal) { "${field.name} should be final" } - assert(field.visibility == org.jetbrains.kotlin.descriptors.Visibilities.Public) { - "${field.name} should be public, got ${field.visibility}" - } + assertTrue(field.isStatic, "${field.name} should be static") + assertTrue(field.isFinal, "${field.name} should be final") + assertEquals(org.jetbrains.kotlin.descriptors.Visibilities.Public, field.visibility, "${field.name} should be public") } // All fields share the same type (int) - assert(eofField.type is JavaPrimitiveType) { "EOF type should be primitive, got ${eofField.type::class.simpleName}" } - assert(eolField.type is JavaPrimitiveType) { "EOL type should be primitive, got ${eolField.type::class.simpleName}" } + assertTrue(eofField.type is JavaPrimitiveType, "EOF type should be primitive, got ${eofField.type::class.simpleName}") + assertTrue(eolField.type is JavaPrimitiveType, "EOL type should be primitive, got ${eolField.type::class.simpleName}") } @Test @@ -239,30 +241,35 @@ // against a full FIR session. val regular = javaClass.methods.first { it.name.asString() == "ofRegular" } val regularParam = regular.valueParameters.first() - assert(!regularParam.isVararg) { "Regular param should not be vararg" } - assert(regularParam.type is JavaClassifierType) { + assertFalse(regularParam.isVararg, "Regular param should not be vararg") + assertTrue( + regularParam.type is JavaClassifierType, "Regular param type should be JavaClassifierType, got ${regularParam.type::class.simpleName}" - } - assert(regularParam.annotations.any { it.classId?.asString()?.contains("NonNull") == true }) { + ) + assertTrue( + regularParam.annotations.any { it.classId?.asString()?.contains("NonNull") == true }, "Parser should capture @NonNull on the parameter, got: ${regularParam.annotations.map { it.classId }}" - } + ) // Varargs parameter: type should be JavaArrayType (String[]) with a JavaClassifierType // component (String). Component-vs-array annotation placement is again covered by // `JavaUsingAst*` integration tests rather than this parsing-only test (see comment above). val vararg = javaClass.methods.first { it.name.asString() == "ofJspecify" } val varargParam = vararg.valueParameters.first() - assert(varargParam.isVararg) { "Vararg param should be vararg" } - assert(varargParam.type is JavaArrayType) { + assertTrue(varargParam.isVararg, "Vararg param should be vararg") + assertTrue( + varargParam.type is JavaArrayType, "Vararg param type should be JavaArrayType, got ${varargParam.type::class.simpleName}" - } + ) val arrayType = varargParam.type as JavaArrayType val componentType = arrayType.componentType - assert(componentType is JavaClassifierType) { + assertTrue( + componentType is JavaClassifierType, "Vararg component type should be JavaClassifierType, got ${componentType::class.simpleName}" - } - assert(varargParam.annotations.any { it.classId?.asString()?.contains("NonNull") == true }) { + ) + assertTrue( + varargParam.annotations.any { it.classId?.asString()?.contains("NonNull") == true }, "Parser should capture @NonNull on the vararg parameter, got: ${varargParam.annotations.map { it.classId }}" - } + ) } }
diff --git a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingModifiersAndSpecialClassesTest.kt b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingModifiersAndSpecialClassesTest.kt index a5aa0e9..dd6d238 100644 --- a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingModifiersAndSpecialClassesTest.kt +++ b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingModifiersAndSpecialClassesTest.kt
@@ -12,7 +12,11 @@ import org.jetbrains.kotlin.java.direct.model.JavaClassOverAst import org.jetbrains.kotlin.load.java.structure.JavaClassifierType import org.jetbrains.kotlin.name.Name +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertNotNull class JavaParsingModifiersAndSpecialClassesTest : JavaParsingTestBase() { @@ -26,17 +30,17 @@ """.trimIndent() val javaClass = parseFirstClass(source) - assert(javaClass.isInterface) { "Expected interface" } - assert(javaClass.fields.size == 2) { "Expected 2 fields, got ${javaClass.fields.size}" } + assertTrue(javaClass.isInterface) + assertEquals(2, javaClass.fields.size) val constantField = javaClass.fields.first { it.name.asString() == "CONSTANT" } - assert(constantField.isStatic) { "Interface field CONSTANT should be implicitly static" } - assert(constantField.isFinal) { "Interface field CONSTANT should be implicitly final" } - assert(constantField.visibility.toString() == "public") { "Interface field should be public" } + assertTrue(constantField.isStatic, "Interface field CONSTANT should be implicitly static") + assertTrue(constantField.isFinal, "Interface field CONSTANT should be implicitly final") + assertEquals("public", constantField.visibility.toString()) val numberField = javaClass.fields.first { it.name.asString() == "NUMBER" } - assert(numberField.isStatic) { "Interface field NUMBER should be implicitly static" } - assert(numberField.isFinal) { "Interface field NUMBER should be implicitly final" } + assertTrue(numberField.isStatic, "Interface field NUMBER should be implicitly static") + assertTrue(numberField.isFinal, "Interface field NUMBER should be implicitly final") } @Test @@ -51,24 +55,24 @@ """.trimIndent() val javaClass = parseFirstClass(source) - assert(!javaClass.isInterface) { "Expected class, not interface" } - assert(javaClass.fields.size == 4) { "Expected 4 fields, got ${javaClass.fields.size}" } + assertFalse(javaClass.isInterface, "Expected class, not interface") + assertEquals(4, javaClass.fields.size) val field1 = javaClass.fields.first { it.name.asString() == "field1" } - assert(!field1.isStatic) { "field1 should NOT be static" } - assert(!field1.isFinal) { "field1 should NOT be final" } + assertFalse(field1.isStatic, "field1 should NOT be static") + assertFalse(field1.isFinal, "field1 should NOT be final") val field2 = javaClass.fields.first { it.name.asString() == "field2" } - assert(field2.isStatic) { "field2 should be static" } - assert(!field2.isFinal) { "field2 should NOT be final" } + assertTrue(field2.isStatic, "field2 should be static") + assertFalse(field2.isFinal, "field2 should NOT be final") val field3 = javaClass.fields.first { it.name.asString() == "field3" } - assert(!field3.isStatic) { "field3 should NOT be static" } - assert(field3.isFinal) { "field3 should be final" } + assertFalse(field3.isStatic, "field3 should NOT be static") + assertTrue(field3.isFinal, "field3 should be final") val field4 = javaClass.fields.first { it.name.asString() == "field4" } - assert(field4.isStatic) { "field4 should be static" } - assert(field4.isFinal) { "field4 should be final" } + assertTrue(field4.isStatic, "field4 should be static") + assertTrue(field4.isFinal, "field4 should be final") } @Test @@ -82,19 +86,19 @@ """.trimIndent() val javaClass = parseFirstClass(source) - assert(javaClass.isInterface) { "Expected interface" } - assert(javaClass.methods.size == 3) { "Expected 3 methods, got ${javaClass.methods.size}" } + assertTrue(javaClass.isInterface) + assertEquals(3, javaClass.methods.size) val abstractMethod = javaClass.methods.first { it.name.asString() == "abstractMethod" } - assert(abstractMethod.isAbstract) { "Interface method without body should be implicitly abstract" } - assert(abstractMethod.visibility.toString() == "public") { "Interface method should be public" } + assertTrue(abstractMethod.isAbstract, "Interface method without body should be implicitly abstract") + assertEquals("public", abstractMethod.visibility.toString()) val anotherAbstract = javaClass.methods.first { it.name.asString() == "anotherAbstractMethod" } - assert(anotherAbstract.isAbstract) { "Interface method without body should be implicitly abstract" } - assert(anotherAbstract.valueParameters.size == 1) { "Should have 1 parameter" } + assertTrue(anotherAbstract.isAbstract, "Interface method without body should be implicitly abstract") + assertEquals(1, anotherAbstract.valueParameters.size) val defaultMethod = javaClass.methods.first { it.name.asString() == "defaultMethod" } - assert(!defaultMethod.isAbstract) { "Default method with body should NOT be abstract" } + assertFalse(defaultMethod.isAbstract, "Default method with body should NOT be abstract") } @Test @@ -107,14 +111,14 @@ """.trimIndent() val javaClass = parseFirstClass(source) - assert(!javaClass.isInterface) { "Expected class, not interface" } - assert(javaClass.methods.size == 2) { "Expected 2 methods, got ${javaClass.methods.size}" } + assertFalse(javaClass.isInterface, "Expected class, not interface") + assertEquals(2, javaClass.methods.size) val regularMethod = javaClass.methods.first { it.name.asString() == "regularMethod" } - assert(!regularMethod.isAbstract) { "Regular method with body should NOT be abstract" } + assertFalse(regularMethod.isAbstract, "Regular method with body should NOT be abstract") val abstractMethod = javaClass.methods.first { it.name.asString() == "abstractMethod" } - assert(abstractMethod.isAbstract) { "Method with explicit abstract keyword should be abstract" } + assertTrue(abstractMethod.isAbstract, "Method with explicit abstract keyword should be abstract") } @Test @@ -127,25 +131,23 @@ """.trimIndent() val javaClass = parseFirstClass(source) - assert(javaClass.isInterface) { "Expected interface" } - assert(javaClass.methods.size == 1) { "Expected 1 method (SAM), got ${javaClass.methods.size}" } + assertTrue(javaClass.isInterface) + assertEquals(1, javaClass.methods.size, "Expected exactly 1 method (SAM)") val applyMethod = javaClass.methods.first() - assert(applyMethod.name.asString() == "apply") { "Expected method 'apply'" } - assert(applyMethod.isAbstract) { "SAM method should be abstract for SAM conversion to work" } - assert(applyMethod.valueParameters.size == 1) { "apply should have 1 parameter" } + assertEquals("apply", applyMethod.name.asString()) + assertTrue(applyMethod.isAbstract, "SAM method should be abstract for SAM conversion to work") + assertEquals(1, applyMethod.valueParameters.size) // Verify type parameters - assert(javaClass.typeParameters.size == 2) { "Expected 2 type parameters, got ${javaClass.typeParameters.size}" } + assertEquals(2, javaClass.typeParameters.size) val typeParamNames = javaClass.typeParameters.map { it.name.asString() } - assert("T" in typeParamNames) { "Expected type parameter T" } - assert("R" in typeParamNames) { "Expected type parameter R" } + assertTrue("T" in typeParamNames, "Expected type parameter T, got $typeParamNames") + assertTrue("R" in typeParamNames, "Expected type parameter R, got $typeParamNames") // Verify the annotation is parsed - assert(javaClass.annotations.size == 1) { "Expected 1 annotation, got ${javaClass.annotations.size}" } - assert(javaClass.annotations.first().classId?.shortClassName?.asString() == "FunctionalInterface") { - "Expected @FunctionalInterface annotation" - } + assertEquals(1, javaClass.annotations.size) + assertEquals("FunctionalInterface", javaClass.annotations.first().classId?.shortClassName?.asString()) } @Test @@ -170,47 +172,47 @@ val outerClass = parseFirstClass(source) // Verify outer class - assert(outerClass.name.asString() == "A") { "Expected outer class name 'A'" } - assert(outerClass.typeParameters.size == 1) { "Outer class should have 1 type parameter, got ${outerClass.typeParameters.size}" } - assert(outerClass.typeParameters.first().name.asString() == "X") { "Outer type param should be 'X'" } + assertEquals("A", outerClass.name.asString()) + assertEquals(1, outerClass.typeParameters.size) + assertEquals("X", outerClass.typeParameters.first().name.asString()) // Verify nested interface exists - assert(outerClass.innerClassNames.size == 1) { "Expected 1 inner class, got ${outerClass.innerClassNames.size}" } - assert(outerClass.innerClassNames.first().asString() == "I") { "Expected inner class name 'I'" } + assertEquals(1, outerClass.innerClassNames.size) + assertEquals("I", outerClass.innerClassNames.first().asString()) // Get nested interface via findInnerClass val nestedInterface = outerClass.findInnerClass(Name.identifier("I")) - assert(nestedInterface != null) { "findInnerClass should find 'I'" } - assert(nestedInterface!!.isInterface) { "I should be an interface" } - assert(nestedInterface.name.asString() == "I") { "Nested interface name should be 'I'" } + assertNotNull(nestedInterface) { "findInnerClass should find 'I'" } + assertTrue(nestedInterface.isInterface, "I should be an interface") + assertEquals("I", nestedInterface.name.asString()) // Verify nested interface type parameters - assert(nestedInterface.typeParameters.size == 1) { "Nested interface should have 1 type parameter, got ${nestedInterface.typeParameters.size}" } - assert(nestedInterface.typeParameters.first().name.asString() == "T") { "Nested type param should be 'T'" } + assertEquals(1, nestedInterface.typeParameters.size) + assertEquals("T", nestedInterface.typeParameters.first().name.asString()) // Verify nested interface has SAM method - assert(nestedInterface.methods.size == 1) { "Nested interface should have 1 method, got ${nestedInterface.methods.size}" } + assertEquals(1, nestedInterface.methods.size) val computeMethod = nestedInterface.methods.first() - assert(computeMethod.name.asString() == "compute") { "Method name should be 'compute'" } - assert(computeMethod.isAbstract) { "Interface method should be implicitly abstract" } + assertEquals("compute", computeMethod.name.asString()) + assertTrue(computeMethod.isAbstract, "Interface method should be implicitly abstract") // Verify fqName of nested interface - assert(nestedInterface.fqName?.asString() == "A.I") { "Expected fqName 'A.I', got ${nestedInterface.fqName?.asString()}" } + assertEquals("A.I", nestedInterface.fqName?.asString()) // Verify outerClass reference - assert(nestedInterface.outerClass == outerClass) { "Nested interface should reference outer class" } + assertEquals(outerClass, nestedInterface.outerClass, "Nested interface should reference outer class") // Verify get method in outer class that uses the nested interface val getMethod = outerClass.methods.first { it.name.asString() == "get" } - assert(getMethod.typeParameters.size == 1) { "get method should have 1 type parameter" } - assert(getMethod.typeParameters.first().name.asString() == "T") { "get method type param should be 'T'" } - assert(getMethod.valueParameters.size == 1) { "get method should have 1 parameter" } + assertEquals(1, getMethod.typeParameters.size) + assertEquals("T", getMethod.typeParameters.first().name.asString()) + assertEquals(1, getMethod.valueParameters.size) val paramType = getMethod.valueParameters.first().type as JavaClassifierType // The type reference I<T> resolves to A.I since it's used within class A - assert(paramType.classifierQualifiedName == "A.I") { "Parameter type name should be 'A.I', got ${paramType.classifierQualifiedName}" } - assert(paramType.classifier == nestedInterface) { "Parameter type should resolve to nested interface" } - assert(paramType.typeArguments.size == 1) { "Parameter type should have 1 type argument, got ${paramType.typeArguments.size}" } + assertEquals("A.I", paramType.classifierQualifiedName) + assertEquals(nestedInterface, paramType.classifier, "Parameter type should resolve to nested interface") + assertEquals(1, paramType.typeArguments.size) } @Test @@ -232,17 +234,17 @@ val outerClass = parseFirstClass(source) val nestedInterface = outerClass.findInnerClass(Name.identifier("NestedInterface")) - assert(nestedInterface != null) { "Should find NestedInterface" } + assertNotNull(nestedInterface) { "Should find NestedInterface" } // Interfaces are implicitly static in Java - assert(nestedInterface!!.isInterface) { "NestedInterface should be an interface" } + assertTrue(nestedInterface.isInterface, "NestedInterface should be an interface") val nestedStaticClass = outerClass.findInnerClass(Name.identifier("NestedStaticClass")) - assert(nestedStaticClass != null) { "Should find NestedStaticClass" } - assert(nestedStaticClass!!.isStatic) { "NestedStaticClass should be explicitly static" } + assertNotNull(nestedStaticClass) { "Should find NestedStaticClass" } + assertTrue(nestedStaticClass.isStatic, "NestedStaticClass should be explicitly static") val nestedInnerClass = outerClass.findInnerClass(Name.identifier("NestedInnerClass")) - assert(nestedInnerClass != null) { "Should find NestedInnerClass" } - assert(!nestedInnerClass!!.isStatic) { "NestedInnerClass should NOT be static" } + assertNotNull(nestedInnerClass) { "Should find NestedInnerClass" } + assertFalse(nestedInnerClass.isStatic, "NestedInnerClass should NOT be static") } @Test @@ -267,23 +269,23 @@ // Nested interface should be implicitly static (no 'static' keyword in source) val nestedInterface = outerClass.findInnerClass(Name.identifier("NestedInterface")) - assert(nestedInterface != null) { "Should find NestedInterface" } - assert(nestedInterface!!.isInterface) { "NestedInterface should be an interface" } - assert(nestedInterface.isStatic) { "Nested interface should be implicitly static for FIR isInner=false" } - assert(nestedInterface.outerClass == outerClass) { "Nested interface should have outer class reference" } + assertNotNull(nestedInterface) { "Should find NestedInterface" } + assertTrue(nestedInterface.isInterface, "NestedInterface should be an interface") + assertTrue(nestedInterface.isStatic, "Nested interface should be implicitly static for FIR isInner=false") + assertEquals(outerClass, nestedInterface.outerClass, "Nested interface should have outer class reference") // Nested enum should be implicitly static val nestedEnum = outerClass.findInnerClass(Name.identifier("NestedEnum")) - assert(nestedEnum != null) { "Should find NestedEnum" } - assert(nestedEnum!!.isEnum) { "NestedEnum should be an enum" } - assert(nestedEnum.isStatic) { "Nested enum should be implicitly static for FIR isInner=false" } + assertNotNull(nestedEnum) { "Should find NestedEnum" } + assertTrue(nestedEnum.isEnum, "NestedEnum should be an enum") + assertTrue(nestedEnum.isStatic, "Nested enum should be implicitly static for FIR isInner=false") // Inner class (without static keyword) should NOT be static val innerClass = outerClass.findInnerClass(Name.identifier("InnerClass")) - assert(innerClass != null) { "Should find InnerClass" } - assert(!innerClass!!.isInterface) { "InnerClass should not be an interface" } - assert(!innerClass.isEnum) { "InnerClass should not be an enum" } - assert(!innerClass.isStatic) { "Inner class without 'static' keyword should NOT be static" } + assertNotNull(innerClass) { "Should find InnerClass" } + assertFalse(innerClass.isInterface, "InnerClass should not be an interface") + assertFalse(innerClass.isEnum, "InnerClass should not be an enum") + assertFalse(innerClass.isStatic, "Inner class without 'static' keyword should NOT be static") } @Test @@ -303,14 +305,14 @@ val classes = tree.getChildrenByType(root, JavaSyntaxElementType.CLASS).map { JavaClassOverAst(it, tree, context) } val day = classes.first { it.name.asString() == "Day" } - assert(day.isEnum) { "Day should be enum" } - assert(day.isFinal) { "Plain enum Day should be implicitly final" } - assert(!day.isAbstract) { "Plain enum Day should not be abstract" } + assertTrue(day.isEnum, "Day should be enum") + assertTrue(day.isFinal, "Plain enum Day should be implicitly final") + assertFalse(day.isAbstract, "Plain enum Day should not be abstract") val ops = classes.first { it.name.asString() == "Ops" } - assert(ops.isEnum) { "Ops should be enum" } - assert(!ops.isFinal) { "Enum Ops with abstract method should NOT be final" } - assert(ops.isAbstract) { "Enum Ops with abstract method should be abstract" } + assertTrue(ops.isEnum, "Ops should be enum") + assertFalse(ops.isFinal, "Enum Ops with abstract method should NOT be final") + assertTrue(ops.isAbstract, "Enum Ops with abstract method should be abstract") } @Test @@ -318,9 +320,9 @@ // Annotation types with methods are implicitly abstract val source = "public @interface Ann { String value(); }" val javaClass = parseFirstClass(source) - assert(javaClass.isAnnotationType) { "Ann should be annotation type" } - assert(javaClass.isAbstract) { "Annotation type with methods should be abstract" } - assert(!javaClass.isFinal) { "Annotation type should not be final" } + assertTrue(javaClass.isAnnotationType, "Ann should be annotation type") + assertTrue(javaClass.isAbstract, "Annotation type with methods should be abstract") + assertFalse(javaClass.isFinal, "Annotation type should not be final") } @Test @@ -350,12 +352,14 @@ tree.findChildByType(node, JavaSyntaxTokenType.IDENTIFIER)?.let { tree.getText(it).toString() } == "Shape" } val shape = JavaClassOverAst(shapeNode, tree, parsed.context) - assert(shape.isSealed) { "Shape should be sealed" } + assertTrue(shape.isSealed, "Shape should be sealed") val permitted = shape.permittedTypes.map { it.classifierQualifiedName }.toSet() - assert(permitted == setOf("Shape.Inner", "Circle", "Square", "Holder.Triangle", "Holder.Mid.Deep")) { - "Implicit permits must scan the whole compilation unit (siblings + deeply-nested), got $permitted" - } + assertEquals( + setOf("Shape.Inner", "Circle", "Square", "Holder.Triangle", "Holder.Mid.Deep"), + permitted, + "Implicit permits must scan the whole compilation unit (siblings + deeply-nested)", + ) } @Test @@ -381,12 +385,14 @@ tree.findChildByType(node, JavaSyntaxTokenType.IDENTIFIER)?.let { tree.getText(it).toString() } == "Shape" } val shape = JavaClassOverAst(shapeNode, tree, parsed.context) - assert(shape.isSealed) { "Top-level Shape should be sealed" } + assertTrue(shape.isSealed, "Top-level Shape should be sealed") val permitted = shape.permittedTypes.map { it.classifierQualifiedName }.toSet() - assert(permitted == setOf("Circle")) { + assertEquals( + setOf("Circle"), + permitted, "Resolution-based match must include only the real subtype `Circle` and exclude `Box.Impl` " + - "(whose `Shape` resolves to the nested `Box.Shape`), got $permitted" - } + "(whose `Shape` resolves to the nested `Box.Shape`)", + ) } }
diff --git a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingTypeResolutionTest.kt b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingTypeResolutionTest.kt index e2b97fa..4d5b2db 100644 --- a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingTypeResolutionTest.kt +++ b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingTypeResolutionTest.kt
@@ -13,7 +13,12 @@ import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaClassifierType import org.jetbrains.kotlin.name.Name +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertNotNull class JavaParsingTypeResolutionTest : JavaParsingTestBase() { @@ -22,14 +27,14 @@ val source = "class A<T> extends B implements C, D {}" val javaClass = parseFirstClass(source) - assert(javaClass.typeParameters.size == 1) - assert(javaClass.typeParameters.first().name.asString() == "T") + assertEquals(1, javaClass.typeParameters.size) + assertEquals("T", javaClass.typeParameters.first().name.asString()) - assert(javaClass.supertypes.size == 3) + assertEquals(3, javaClass.supertypes.size) val supertypeNames = javaClass.supertypes.map { it.classifierQualifiedName } - assert(supertypeNames.contains("B")) - assert(supertypeNames.contains("C")) - assert(supertypeNames.contains("D")) + assertTrue(supertypeNames.contains("B")) { "Supertypes: $supertypeNames" } + assertTrue(supertypeNames.contains("C")) { "Supertypes: $supertypeNames" } + assertTrue(supertypeNames.contains("D")) { "Supertypes: $supertypeNames" } } @Test @@ -58,13 +63,11 @@ val found = with(context) { findInnerClassFromSupertypes(Name.identifier("Target"), derived) } - assert(found != null) { + assertNotNull(found) { "Expected to resolve inherited inner class 'Target' through nested generic supertype " + "Outer<String>.Inner, but resolution returned null" } - assert(found?.name?.asString() == "Target") { - "Expected resolved inner class 'Target', got '${found?.name?.asString()}'" - } + assertEquals("Target", found.name.asString()) } @Test @@ -79,27 +82,27 @@ val context = parsed.context val classes = tree.getChildren(root).filter { tree.getType(it).toString() == "CLASS" } - assert(classes.size == 2) { "Expected 2 classes, got ${classes.size}" } + assertEquals(2, classes.size) val base = JavaClassOverAst(classes[0], tree, context) val derived = JavaClassOverAst(classes[1], tree, context) - assert(base.name.asString() == "Base") - assert(derived.name.asString() == "Derived") + assertEquals("Base", base.name.asString()) + assertEquals("Derived", derived.name.asString()) // Base has implicit java.lang.Object supertype - assert(base.supertypes.size == 1) { "Base should have 1 supertype (implicit Object), got ${base.supertypes.size}" } - assert(base.supertypes.first().classifierQualifiedName == "java.lang.Object") { "Base should extend Object" } + assertEquals(1, base.supertypes.size) { "Base should have exactly the implicit Object supertype" } + assertEquals("java.lang.Object", base.supertypes.first().classifierQualifiedName) - assert(derived.supertypes.size == 1) { "Derived should have 1 supertype, got ${derived.supertypes.size}" } + assertEquals(1, derived.supertypes.size) val supertype = derived.supertypes.first() - assert(supertype.classifierQualifiedName == "Base") { "Expected Base, got ${supertype.classifierQualifiedName}" } + assertEquals("Base", supertype.classifierQualifiedName) val classifier = supertype.classifier - assert(classifier != null) { "Expected classifier to be resolved" } - assert(classifier is JavaClass) { "Expected JavaClass, got ${classifier?.javaClass}" } - assert((classifier as JavaClass).name.asString() == "Base") { "Expected Base class, got ${classifier.name}" } + assertNotNull(classifier) { "Expected classifier to be resolved" } + assertTrue(classifier is JavaClass) { "Expected JavaClass, got ${classifier.javaClass}" } + assertEquals("Base", (classifier as JavaClass).name.asString()) } @Test @@ -119,20 +122,20 @@ } val derived = JavaClassOverAst(derivedNode, tree1, context1) - assert(derived.supertypes.size == 1) { "Expected 1 supertype" } + assertEquals(1, derived.supertypes.size) val supertype = derived.supertypes.first() - assert(supertype.classifierQualifiedName == "Base") { "Expected 'Base', got '${supertype.classifierQualifiedName}'" } - assert(supertype.classifier != null) { "Base should be resolved via local scope" } + assertEquals("Base", supertype.classifierQualifiedName) + assertNotNull(supertype.classifier) { "Base should be resolved via local scope" } val sourceQualifiedName = """ class MyClass extends java.util.ArrayList {} """.trimIndent() val myClass = parseFirstClass(sourceQualifiedName) - assert(myClass.supertypes.size == 1) { "Expected 1 supertype" } + assertEquals(1, myClass.supertypes.size) val supertype2 = myClass.supertypes.first() - assert(supertype2.classifierQualifiedName == "java.util.ArrayList") { "Expected 'java.util.ArrayList', got '${supertype2.classifierQualifiedName}'" } - assert(supertype2.classifier == null) { "java.util.ArrayList should NOT be in local scope" } + assertEquals("java.util.ArrayList", supertype2.classifierQualifiedName) + assertNull(supertype2.classifier) { "java.util.ArrayList should NOT be in local scope" } } @Test @@ -151,17 +154,17 @@ val javaClass = parseFirstClass(source) - assert(javaClass.supertypes.size == 1) { "Expected 1 supertype" } + assertEquals(1, javaClass.supertypes.size) val supertype = javaClass.supertypes.first() - assert(supertype.classifierQualifiedName == "ArrayList") { "Expected simple name ArrayList, got ${supertype.classifierQualifiedName}" } + assertEquals("ArrayList", supertype.classifierQualifiedName) val listField = javaClass.fields.first { it.name.asString() == "list" } val listType = listField.type as JavaClassifierType - assert(listType.classifierQualifiedName == "List") { "Expected simple name List for list field, got ${listType.classifierQualifiedName}" } + assertEquals("List", listType.classifierQualifiedName) val counterField = javaClass.fields.first { it.name.asString() == "counter" } val counterType = counterField.type as JavaClassifierType - assert(counterType.classifierQualifiedName == "AtomicInteger") { "Expected simple name AtomicInteger for star import, got ${counterType.classifierQualifiedName}" } + assertEquals("AtomicInteger", counterType.classifierQualifiedName) { "The star-imported type should keep its simple name" } } @Test @@ -173,12 +176,12 @@ """.trimIndent() val javaClass = parseFirstClass(source) - assert(javaClass.fields.size == 1) { "Expected 1 field, got ${javaClass.fields.size}" } + assertEquals(1, javaClass.fields.size) val field = javaClass.fields.first() val fieldType = field.type as JavaClassifierType - assert(fieldType.classifierQualifiedName == "Object") { "Expected 'Object', got '${fieldType.classifierQualifiedName}'" } - assert(fieldType.classifier == null) { "Expected classifier=null for external type without a wired symbol provider" } + assertEquals("Object", fieldType.classifierQualifiedName) + assertNull(fieldType.classifier) { "Expected classifier=null for external type without a wired symbol provider" } } @Test @@ -194,13 +197,13 @@ val field = javaClass.fields.first { it.name.asString() == "field" } val fieldType = field.type as JavaClassifierType - assert(fieldType.classifier != null) { "Field type 'B' should have resolved classifier" } - assert(fieldType.classifier?.name?.asString() == "B") { "Field type classifier should be 'B'" } + assertNotNull(fieldType.classifier) { "Field type 'B' should have resolved classifier" } + assertEquals("B", fieldType.classifier?.name?.asString()) val method = javaClass.methods.first { it.name.asString() == "method" } val returnType = method.returnType as JavaClassifierType - assert(returnType.classifier != null) { "Method return type 'B' should have resolved classifier" } - assert(returnType.classifier?.name?.asString() == "B") { "Method return type classifier should be 'B'" } + assertNotNull(returnType.classifier) { "Method return type 'B' should have resolved classifier" } + assertEquals("B", returnType.classifier?.name?.asString()) } @Test @@ -222,23 +225,23 @@ val field1 = javaClass.fields.first { it.name.asString() == "field1" } val type1 = field1.type as JavaClassifierType - assert(type1.classifier != null) { "field1 type 'Inner' should resolve" } - assert(type1.classifier?.name?.asString() == "Inner") { "field1 type should be 'Inner'" } + assertNotNull(type1.classifier) { "field1 type 'Inner' should resolve" } + assertEquals("Inner", type1.classifier?.name?.asString()) val field2 = javaClass.fields.first { it.name.asString() == "field2" } val type2 = field2.type as JavaClassifierType - assert(type2.classifier != null) { "field2 type 'Outer.Inner' should resolve" } - assert(type2.classifier?.name?.asString() == "Inner") { "field2 type should be 'Inner'" } + assertNotNull(type2.classifier) { "field2 type 'Outer.Inner' should resolve" } + assertEquals("Inner", type2.classifier?.name?.asString()) val field3 = javaClass.fields.first { it.name.asString() == "field3" } val type3 = field3.type as JavaClassifierType - assert(type3.classifier != null) { "field3 type 'Outer.Inner.Deep' should resolve" } - assert(type3.classifier?.name?.asString() == "Deep") { "field3 type should be 'Deep'" } + assertNotNull(type3.classifier) { "field3 type 'Outer.Inner.Deep' should resolve" } + assertEquals("Deep", type3.classifier?.name?.asString()) val field4 = javaClass.fields.first { it.name.asString() == "field4" } val type4 = field4.type as JavaClassifierType - assert(type4.classifier != null) { "field4 type 'Inner.Deep' should resolve" } - assert(type4.classifier?.name?.asString() == "Deep") { "field4 type should be 'Deep'" } + assertNotNull(type4.classifier) { "field4 type 'Inner.Deep' should resolve" } + assertEquals("Deep", type4.classifier?.name?.asString()) } @Test @@ -264,8 +267,8 @@ // Verify we can find nested class b val nestedB = classA.findInnerClass(Name.identifier("b")) - assert(nestedB != null) { "Should find nested class b in class a" } - assert(nestedB!!.fqName?.asString() == "a.b") { "Nested class fqName should be 'a.b', got ${nestedB.fqName}" } + assertNotNull(nestedB) { "Should find nested class b in class a" } + assertEquals("a.b", nestedB.fqName?.asString()) // Now test resolution of "a.b" as a type reference in another class (same file) val source2 = """ @@ -295,8 +298,8 @@ // The return type "a.b" should resolve to nested class a.b (class a has priority over package a) - assert(returnType.classifier != null) { "Return type 'a.b' should resolve to local nested class" } - assert(returnType.classifier?.name?.asString() == "b") { "Classifier should be 'b'" } + assertNotNull(returnType.classifier) { "Return type 'a.b' should resolve to local nested class" } + assertEquals("b", returnType.classifier?.name?.asString()) } @Test @@ -326,8 +329,8 @@ // When class 'a' is NOT in the same file, classifier should be null (external, // parsing-level fixture has no `FirSession` wired so the cross-file branch // short-circuits per Step 4.5b). - assert(returnType.classifier == null) { "Classifier should be null for external type" } - assert(returnType.classifierQualifiedName == "a.b") { "classifierQualifiedName should be 'a.b'" } + assertNull(returnType.classifier) { "Classifier should be null for external type" } + assertEquals("a.b", returnType.classifierQualifiedName) } @Test @@ -359,24 +362,24 @@ // Find FunctionDescriptorImpl val implClass = outerClass.findInnerClass(Name.identifier("FunctionDescriptorImpl")) - assert(implClass != null) { "Expected to find FunctionDescriptorImpl" } + assertNotNull(implClass) { "Expected to find FunctionDescriptorImpl" } // Find CopyConfiguration - val copyConfig = implClass!!.findInnerClass(Name.identifier("CopyConfiguration")) - assert(copyConfig != null) { "Expected to find CopyConfiguration" } + val copyConfig = implClass.findInnerClass(Name.identifier("CopyConfiguration")) + assertNotNull(copyConfig) { "Expected to find CopyConfiguration" } // CopyConfiguration should have SimpleFunctionDescriptor.CopyBuilder as a supertype - val supertypes = copyConfig!!.supertypes.toList() - assert(supertypes.isNotEmpty()) { "CopyConfiguration should have supertypes" } + val supertypes = copyConfig.supertypes.toList() + assertTrue(supertypes.isNotEmpty()) { "CopyConfiguration should have supertypes" } // Declared-only contract: findInnerClass returns ONLY directly declared member types, // matching JavaClassImpl (PSI) / BinaryJavaClass. CopyBuilder is inherited (declared in // FunctionDescriptor), so a direct findInnerClass on SimpleFunctionDescriptor must NOT find it; // inherited lookup is the resolution layer's job (validated via the type reference below). val simpleFuncDesc = outerClass.findInnerClass(Name.identifier("SimpleFunctionDescriptor")) - assert(simpleFuncDesc != null) { "Expected to find SimpleFunctionDescriptor" } - val inheritedCopyBuilder = simpleFuncDesc!!.findInnerClass(Name.identifier("CopyBuilder")) - assert(inheritedCopyBuilder == null) { + assertNotNull(simpleFuncDesc) { "Expected to find SimpleFunctionDescriptor" } + val inheritedCopyBuilder = simpleFuncDesc.findInnerClass(Name.identifier("CopyBuilder")) + assertNull(inheritedCopyBuilder) { "SimpleFunctionDescriptor.findInnerClass('CopyBuilder') must return null for an inherited " + "(not directly declared) member type. innerClassNames=${simpleFuncDesc.innerClassNames}" } @@ -386,20 +389,20 @@ // member type inherited by SimpleFunctionDescriptor from FunctionDescriptor. val allQualifiedNames = supertypes.map { it.classifierQualifiedName } val copyBuilderSupertype = supertypes.find { it.classifierQualifiedName.contains("CopyBuilder") } - assert(copyBuilderSupertype != null) { + assertNotNull(copyBuilderSupertype) { "Expected a supertype containing 'CopyBuilder', got supertypes: $allQualifiedNames" } - val supertypeQualified = copyBuilderSupertype!!.classifierQualifiedName + val supertypeQualified = copyBuilderSupertype.classifierQualifiedName // Check classifierQualifiedName resolves the FQN properly - assert(supertypeQualified != "SimpleFunctionDescriptor.CopyBuilder") { + assertNotEquals("SimpleFunctionDescriptor.CopyBuilder", supertypeQualified) { "classifierQualifiedName should resolve to the actual FQN, not raw text. " + - "Got '$supertypeQualified'. This means classifierQualifiedName did not resolve via findInnerClass." + "This means classifierQualifiedName did not resolve via findInnerClass." } // Critical: the classifier should actually resolve (not be null) val classifier = copyBuilderSupertype.classifier - assert(classifier != null) { + assertNotNull(classifier) { "Expected supertype classifier to resolve for SimpleFunctionDescriptor.CopyBuilder " + "(inherited inner class). classifierQualifiedName='$supertypeQualified'" } @@ -438,13 +441,11 @@ // `B` is inherited from the qualified-nested supertype `x.S`; the same-file supertype walk // must resolve it by navigating the full reference, not just its first segment. - assert(returnType.classifier != null) { + assertNotNull(returnType.classifier) { "Return type 'B' should resolve to the inherited nested class x.S.B via the same-file " + "supertype walk, but classifier was null " + "(classifierQualifiedName='${returnType.classifierQualifiedName}')" } - assert(returnType.classifier?.name?.asString() == "B") { - "Classifier should be 'B', got '${returnType.classifier?.name}'" - } + assertEquals("B", returnType.classifier?.name?.asString()) } }
diff --git a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingTypeSystemTest.kt b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingTypeSystemTest.kt index bc444bf..2548ea8 100644 --- a/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingTypeSystemTest.kt +++ b/compiler/java-direct/test/org/jetbrains/kotlin/java/direct/JavaParsingTypeSystemTest.kt
@@ -13,7 +13,12 @@ import org.jetbrains.kotlin.load.java.structure.JavaClassifierType import org.jetbrains.kotlin.load.java.structure.JavaWildcardType import org.jetbrains.kotlin.name.Name +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertNotNull class JavaParsingTypeSystemTest : JavaParsingTestBase() { @@ -32,22 +37,20 @@ val fieldA = javaClass.fields.first { it.name.asString() == "a" } val typeA = fieldA.type as JavaClassifierType - assert(typeA.classifierQualifiedName == "List") { - "Expected simple name List for List<String>, got ${typeA.classifierQualifiedName}" - } + assertEquals("List", typeA.classifierQualifiedName, "Type name of List<String> must be stripped of type arguments") val fieldB = javaClass.fields.first { it.name.asString() == "b" } val typeB = fieldB.type as JavaClassifierType - assert(typeB.classifierQualifiedName == "java.util.Map") { - "Expected qualified name java.util.Map for java.util.Map<String, Integer>, got ${typeB.classifierQualifiedName}" - } + assertEquals( + "java.util.Map", + typeB.classifierQualifiedName, + "Type name of java.util.Map<String, Integer> must keep the qualifier and drop type arguments", + ) val fieldC = javaClass.fields.first { it.name.asString() == "c" } val typeC = fieldC.type as JavaArrayType val componentType = typeC.componentType as JavaClassifierType - assert(componentType.classifierQualifiedName == "Object") { - "Expected component type Object for Object[], got ${componentType.classifierQualifiedName}" - } + assertEquals("Object", componentType.classifierQualifiedName) } @Test @@ -66,27 +69,27 @@ val items = javaClass.fields.first { it.name.asString() == "items" } val itemsType = items.type as JavaClassifierType - assert(itemsType.classifierQualifiedName == "List") { "Expected 'List', got ${itemsType.classifierQualifiedName}" } - assert(itemsType.typeArguments.size == 1) { "Expected 1 type argument, got ${itemsType.typeArguments.size}" } + assertEquals("List", itemsType.classifierQualifiedName) + assertEquals(1, itemsType.typeArguments.size) val stringArg = itemsType.typeArguments[0] as JavaClassifierType - assert(stringArg.classifierQualifiedName == "String") { "Expected 'String', got ${stringArg.classifierQualifiedName}" } - assert(stringArg.classifier == null) { "String should have null classifier (needs FIR)" } + assertEquals("String", stringArg.classifierQualifiedName) + assertNull(stringArg.classifier, "String should have null classifier (needs FIR)") val objects = javaClass.fields.first { it.name.asString() == "objects" } val objectsType = objects.type as JavaClassifierType - assert(objectsType.typeArguments.size == 1) { "Expected 1 type argument, got ${objectsType.typeArguments.size}" } + assertEquals(1, objectsType.typeArguments.size) val objectArg = objectsType.typeArguments[0] as JavaClassifierType - assert(objectArg.classifierQualifiedName == "Object") { "Expected 'Object', got ${objectArg.classifierQualifiedName}" } - assert(objectArg.classifier == null) { "Object should have null classifier (needs FIR)" } + assertEquals("Object", objectArg.classifierQualifiedName) + assertNull(objectArg.classifier, "Object should have null classifier (needs FIR)") val map = javaClass.fields.first { it.name.asString() == "map" } val mapType = map.type as JavaClassifierType - assert(mapType.classifierQualifiedName == "Map") { "Expected 'Map', got ${mapType.classifierQualifiedName}" } - assert(mapType.typeArguments.size == 2) { "Expected 2 type arguments, got ${mapType.typeArguments.size}" } + assertEquals("Map", mapType.classifierQualifiedName) + assertEquals(2, mapType.typeArguments.size) val keyArg = mapType.typeArguments[0] as JavaClassifierType - assert(keyArg.classifierQualifiedName == "String") { "Expected 'String', got ${keyArg.classifierQualifiedName}" } + assertEquals("String", keyArg.classifierQualifiedName) val valueArg = mapType.typeArguments[1] as JavaClassifierType - assert(valueArg.classifierQualifiedName == "Integer") { "Expected 'Integer', got ${valueArg.classifierQualifiedName}" } + assertEquals("Integer", valueArg.classifierQualifiedName) } @Test @@ -117,123 +120,95 @@ val context = parsed.context val classes = tree.getChildren(root).filter { tree.getType(it).toString() == "CLASS" } - assert(classes.size == 3) { "Expected 3 classes (A, B, BImpl), got ${classes.size}" } + assertEquals(3, classes.size, "Expected 3 classes (A, B, BImpl)") // Find interface A val interfaceANode = classes.first { tree.findChildByType(it, JavaSyntaxTokenType.IDENTIFIER)?.let { id -> tree.getText(id).toString() } == "A" } val interfaceA = JavaClassOverAst(interfaceANode, tree, context) - assert(interfaceA.isInterface) { "A should be an interface" } + assertTrue(interfaceA.isInterface, "A should be an interface") // Check A.foo() return type val aFoo = interfaceA.methods.first { it.name.asString() == "foo" } val aFooReturnType = aFoo.returnType as JavaClassifierType - assert(aFooReturnType.classifierQualifiedName == "A.X") { - "A.foo() should return A.X, got ${aFooReturnType.classifierQualifiedName}" - } - assert(aFooReturnType.typeArguments.size == 1) { - "A.X should have 1 type argument, got ${aFooReturnType.typeArguments.size}" - } + assertEquals("A.X", aFooReturnType.classifierQualifiedName, "A.foo() should return A.X") + assertEquals(1, aFooReturnType.typeArguments.size, "A.X should have 1 type argument") // Check the wildcard type argument val aWildcard = aFooReturnType.typeArguments[0] - assert(aWildcard is JavaWildcardType) { - "Expected JavaWildcardType, got ${aWildcard?.javaClass}" - } + assertTrue(aWildcard is JavaWildcardType, "Expected JavaWildcardType, got ${aWildcard?.javaClass}") val aWildcardType = aWildcard as JavaWildcardType - assert(aWildcardType.isExtends) { "Should be '? extends'" } - assert(aWildcardType.bound != null) { "Wildcard should have a bound" } + assertTrue(aWildcardType.isExtends, "Should be '? extends'") + assertNotNull(aWildcardType.bound) { "Wildcard should have a bound" } val aBound = aWildcardType.bound as JavaClassifierType - assert(aBound.classifierQualifiedName == "A") { - "Wildcard bound should be A, got ${aBound.classifierQualifiedName}" - } + assertEquals("A", aBound.classifierQualifiedName, "Wildcard bound should be A") // Find interface B val interfaceBNode = classes.first { tree.findChildByType(it, JavaSyntaxTokenType.IDENTIFIER)?.let { id -> tree.getText(id).toString() } == "B" } val interfaceB = JavaClassOverAst(interfaceBNode, tree, context) - assert(interfaceB.isInterface) { "B should be an interface" } + assertTrue(interfaceB.isInterface, "B should be an interface") // Check B.foo() return type val bFoo = interfaceB.methods.first { it.name.asString() == "foo" } val bFooReturnType = bFoo.returnType as JavaClassifierType - assert(bFooReturnType.classifierQualifiedName == "B.Y") { - "B.foo() should return B.Y, got ${bFooReturnType.classifierQualifiedName}" - } - assert(bFooReturnType.typeArguments.size == 1) { - "B.Y should have 1 type argument, got ${bFooReturnType.typeArguments.size}" - } + assertEquals("B.Y", bFooReturnType.classifierQualifiedName, "B.foo() should return B.Y") + assertEquals(1, bFooReturnType.typeArguments.size, "B.Y should have 1 type argument") // Check the wildcard type argument val bWildcard = bFooReturnType.typeArguments[0] - assert(bWildcard is JavaWildcardType) { - "Expected JavaWildcardType, got ${bWildcard?.javaClass}" - } + assertTrue(bWildcard is JavaWildcardType, "Expected JavaWildcardType, got ${bWildcard?.javaClass}") val bWildcardType = bWildcard as JavaWildcardType - assert(bWildcardType.isExtends) { "Should be '? extends'" } - assert(bWildcardType.bound != null) { "Wildcard should have a bound" } + assertTrue(bWildcardType.isExtends, "Should be '? extends'") + assertNotNull(bWildcardType.bound) { "Wildcard should have a bound" } val bBound = bWildcardType.bound as JavaClassifierType - assert(bBound.classifierQualifiedName == "B") { - "Wildcard bound should be B, got ${bBound.classifierQualifiedName}" - } + assertEquals("B", bBound.classifierQualifiedName, "Wildcard bound should be B") // Find class BImpl val bImplNode = classes.first { tree.findChildByType(it, JavaSyntaxTokenType.IDENTIFIER)?.let { id -> tree.getText(id).toString() } == "BImpl" } val bImpl = JavaClassOverAst(bImplNode, tree, context) - assert(!bImpl.isInterface) { "BImpl should be a class" } + assertFalse(bImpl.isInterface, "BImpl should be a class") // Check BImpl.foo() return type val bImplFoo = bImpl.methods.first { it.name.asString() == "foo" } val bImplFooReturnType = bImplFoo.returnType as JavaClassifierType - assert(bImplFooReturnType.classifierQualifiedName == "B.Y") { - "BImpl.foo() should return B.Y, got ${bImplFooReturnType.classifierQualifiedName}" - } - assert(bImplFooReturnType.typeArguments.size == 1) { - "B.Y should have 1 type argument, got ${bImplFooReturnType.typeArguments.size}" - } + assertEquals("B.Y", bImplFooReturnType.classifierQualifiedName, "BImpl.foo() should return B.Y") + assertEquals(1, bImplFooReturnType.typeArguments.size, "B.Y should have 1 type argument") // Check the wildcard type argument val bImplWildcard = bImplFooReturnType.typeArguments[0] - assert(bImplWildcard is JavaWildcardType) { - "Expected JavaWildcardType, got ${bImplWildcard?.javaClass}" - } + assertTrue(bImplWildcard is JavaWildcardType, "Expected JavaWildcardType, got ${bImplWildcard?.javaClass}") val bImplWildcardType = bImplWildcard as JavaWildcardType - assert(bImplWildcardType.isExtends) { "Should be '? extends'" } - assert(bImplWildcardType.bound != null) { "Wildcard should have a bound" } + assertTrue(bImplWildcardType.isExtends, "Should be '? extends'") + assertNotNull(bImplWildcardType.bound) { "Wildcard should have a bound" } val bImplBound = bImplWildcardType.bound as JavaClassifierType - assert(bImplBound.classifierQualifiedName == "B") { - "Wildcard bound should be B, got ${bImplBound.classifierQualifiedName}" - } + assertEquals("B", bImplBound.classifierQualifiedName, "Wildcard bound should be B") // Check that nested interface B.Y properly extends A.X val nestedY = interfaceB.findInnerClass(Name.identifier("Y")) - assert(nestedY != null) { "Should find nested interface Y in B" } - assert(nestedY!!.isInterface) { "Y should be an interface" } - assert(nestedY.supertypes.size == 1) { "Y should have 1 supertype (A.X), got ${nestedY.supertypes.size}" } + assertNotNull(nestedY) { "Should find nested interface Y in B" } + assertTrue(nestedY.isInterface, "Y should be an interface") + assertEquals(1, nestedY.supertypes.size, "Y should have 1 supertype (A.X)") val ySupertype = nestedY.supertypes.first() // Y extends A.X<U>, so supertype should be A.X with type argument U - assert(ySupertype.classifierQualifiedName == "A.X") { - "Y's supertype should be A.X, got ${ySupertype.classifierQualifiedName}" - } + assertEquals("A.X", ySupertype.classifierQualifiedName, "Y's supertype should be A.X") // Check that classifier is resolved for the return types // This is important for FIR to properly match method signatures - assert(aFooReturnType.classifier != null) { "A.foo() return type classifier should be resolved" } - assert(aFooReturnType.classifier == interfaceA.findInnerClass(Name.identifier("X"))) { - "A.foo() return type should resolve to A.X" - } + assertNotNull(aFooReturnType.classifier) { "A.foo() return type classifier should be resolved" } + assertEquals( + interfaceA.findInnerClass(Name.identifier("X")), + aFooReturnType.classifier, + "A.foo() return type should resolve to A.X", + ) - assert(bFooReturnType.classifier != null) { "B.foo() return type classifier should be resolved" } - assert(bFooReturnType.classifier == nestedY) { - "B.foo() return type should resolve to B.Y" - } + assertNotNull(bFooReturnType.classifier) { "B.foo() return type classifier should be resolved" } + assertEquals(nestedY, bFooReturnType.classifier, "B.foo() return type should resolve to B.Y") - assert(bImplFooReturnType.classifier != null) { "BImpl.foo() return type classifier should be resolved" } - assert(bImplFooReturnType.classifier == nestedY) { - "BImpl.foo() return type should resolve to B.Y" - } + assertNotNull(bImplFooReturnType.classifier) { "BImpl.foo() return type classifier should be resolved" } + assertEquals(nestedY, bImplFooReturnType.classifier, "BImpl.foo() return type should resolve to B.Y") } @Test @@ -253,37 +228,31 @@ // Test unbounded wildcard: List<?> val itemsField = javaClass.fields.first { it.name.asString() == "items" } val itemsType = itemsField.type as JavaClassifierType - assert(itemsType.typeArguments.size == 1) { "List should have 1 type argument" } + assertEquals(1, itemsType.typeArguments.size, "List should have 1 type argument") val unboundedWildcard = itemsType.typeArguments[0] - assert(unboundedWildcard is JavaWildcardType) { - "Expected JavaWildcardType for ?, got ${unboundedWildcard?.javaClass}" - } + assertTrue(unboundedWildcard is JavaWildcardType, "Expected JavaWildcardType for ?, got ${unboundedWildcard?.javaClass}") val unboundedType = unboundedWildcard as JavaWildcardType - assert(unboundedType.isExtends) { "Unbounded wildcard should have isExtends=true" } - assert(unboundedType.bound == null) { "Unbounded wildcard should have bound=null, got ${unboundedType.bound}" } + assertTrue(unboundedType.isExtends, "Unbounded wildcard should have isExtends=true") + assertNull(unboundedType.bound, "Unbounded wildcard should have bound=null") // Test explicit extends Object: List<? extends Object> val extendsField = javaClass.fields.first { it.name.asString() == "explicitExtends" } val extendsType = extendsField.type as JavaClassifierType val extendsWildcard = extendsType.typeArguments[0] as JavaWildcardType - assert(extendsWildcard.isExtends) { "? extends Object should have isExtends=true" } - assert(extendsWildcard.bound != null) { "? extends Object should have a bound" } + assertTrue(extendsWildcard.isExtends, "? extends Object should have isExtends=true") + assertNotNull(extendsWildcard.bound) { "? extends Object should have a bound" } val extendsBound = extendsWildcard.bound as JavaClassifierType - assert(extendsBound.classifierQualifiedName == "Object") { - "Bound should be Object, got ${extendsBound.classifierQualifiedName}" - } + assertEquals("Object", extendsBound.classifierQualifiedName) // Test super wildcard: List<? super String> val superField = javaClass.fields.first { it.name.asString() == "superWildcard" } val superType = superField.type as JavaClassifierType val superWildcard = superType.typeArguments[0] as JavaWildcardType - assert(!superWildcard.isExtends) { "? super String should have isExtends=false" } - assert(superWildcard.bound != null) { "? super String should have a bound" } + assertFalse(superWildcard.isExtends, "? super String should have isExtends=false") + assertNotNull(superWildcard.bound) { "? super String should have a bound" } val superBound = superWildcard.bound as JavaClassifierType - assert(superBound.classifierQualifiedName == "String") { - "Bound should be String, got ${superBound.classifierQualifiedName}" - } + assertEquals("String", superBound.classifierQualifiedName) } @Test @@ -298,32 +267,32 @@ """.trimIndent() val javaClass = parseFirstClass(source) - assert(javaClass.typeParameters.size == 1) { "Generic should have 1 type parameter" } - assert(javaClass.typeParameters.first().name.asString() == "T") + assertEquals(1, javaClass.typeParameters.size, "Generic should have 1 type parameter") + assertEquals("T", javaClass.typeParameters.first().name.asString()) // Check the static raw field val rawField = javaClass.fields.first { it.name.asString() == "raw" } val rawType = rawField.type as JavaClassifierType - assert(rawType.classifierQualifiedName == "Generic") { "Expected 'Generic', got ${rawType.classifierQualifiedName}" } - assert(rawType.typeArguments.isEmpty()) { "Raw type should have no type arguments" } + assertEquals("Generic", rawType.classifierQualifiedName) + assertTrue(rawType.typeArguments.isEmpty(), "Raw type should have no type arguments") // classifier should resolve to the containing class itself - assert(rawType.classifier != null) { "classifier should resolve to Generic class" } - assert(rawType.classifier == javaClass) { "classifier should be the same Generic class" } + assertNotNull(rawType.classifier) { "classifier should resolve to Generic class" } + assertEquals(javaClass, rawType.classifier, "classifier should be the same Generic class") // isRaw should be true because Generic has type params but no args provided - assert(rawType.isRaw) { "Expected isRaw=true for raw Generic field" } + assertTrue(rawType.isRaw, "Expected isRaw=true for raw Generic field") // Check the notRaw field (has explicit type argument) val notRawField = javaClass.fields.first { it.name.asString() == "notRaw" } val notRawType = notRawField.type as JavaClassifierType - assert(notRawType.classifierQualifiedName == "Generic") { "Expected 'Generic', got ${notRawType.classifierQualifiedName}" } - assert(notRawType.typeArguments.size == 1) { "notRaw should have 1 type argument, got ${notRawType.typeArguments.size}" } - assert(!notRawType.isRaw) { "Expected isRaw=false for Generic<String>" } + assertEquals("Generic", notRawType.classifierQualifiedName) + assertEquals(1, notRawType.typeArguments.size, "notRaw should have 1 type argument") + assertFalse(notRawType.isRaw, "Expected isRaw=false for Generic<String>") // Check the alsoRaw field (instance field, also raw) val alsoRawField = javaClass.fields.first { it.name.asString() == "alsoRaw" } val alsoRawType = alsoRawField.type as JavaClassifierType - assert(alsoRawType.typeArguments.isEmpty()) { "alsoRaw should have no type arguments" } - assert(alsoRawType.isRaw) { "Expected isRaw=true for raw alsoRaw field" } + assertTrue(alsoRawType.typeArguments.isEmpty(), "alsoRaw should have no type arguments") + assertTrue(alsoRawType.isRaw, "Expected isRaw=true for raw alsoRaw field") } @Test @@ -341,18 +310,18 @@ val fooMethod = javaClass.methods.first { it.name.asString() == "foo" } val fooParamType = fooMethod.valueParameters.first().type as JavaClassifierType // For external class via star import, classifier is null (not in local scope) - assert(fooParamType.classifier == null) { "External class List should have null classifier" } + assertNull(fooParamType.classifier, "External class List should have null classifier") // classifierQualifiedName returns "List" (unresolved via star import) - assert(fooParamType.classifierQualifiedName == "List") { "Expected 'List', got ${fooParamType.classifierQualifiedName}" } - assert(fooParamType.typeArguments.isEmpty()) { "Raw List should have no type args" } + assertEquals("List", fooParamType.classifierQualifiedName) + assertTrue(fooParamType.typeArguments.isEmpty(), "Raw List should have no type args") // isRaw returns false for external classes because we can't determine type params without FIR // FIR's type conversion handles this via fallback logic // This documents the current behavior - java-direct can't determine isRaw for external classes - assert(!fooParamType.isRaw) { "isRaw is false for external classes (FIR handles this)" } + assertFalse(fooParamType.isRaw, "isRaw is false for external classes (FIR handles this)") val barMethod = javaClass.methods.first { it.name.asString() == "bar" } val barParamType = barMethod.valueParameters.first().type as JavaClassifierType - assert(barParamType.typeArguments.size == 1) { "List<String> should have 1 type arg" } - assert(!barParamType.isRaw) { "List<String> should not be raw" } + assertEquals(1, barParamType.typeArguments.size, "List<String> should have 1 type arg") + assertFalse(barParamType.isRaw, "List<String> should not be raw") } }