diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendNativeDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendNativeDiagnosticsTestGenerated.java new file mode 100644 index 00000000000..9480b408c14 --- /dev/null +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendNativeDiagnosticsTestGenerated.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.test.runners; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("compiler/testData/diagnostics/nativeTests") +@TestDataPath("$PROJECT_ROOT") +public class FirOldFrontendNativeDiagnosticsTestGenerated extends AbstractFirNativeDiagnosticsTest { + @Test + public void testAllFilesPresentInNativeTests() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/nativeTests"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("identifiers.kt") + public void testIdentifiers() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/identifiers.kt"); + } + + @Test + @TestMetadata("objCName.kt") + public void testObjCName() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName.kt"); + } + + @Test + @TestMetadata("sharedImmutable.kt") + public void testSharedImmutable() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/sharedImmutable.kt"); + } + + @Test + @TestMetadata("threadLocal.kt") + public void testThreadLocal() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/threadLocal.kt"); + } + + @Test + @TestMetadata("throws.kt") + public void testThrows() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/throws.kt"); + } + + @Test + @TestMetadata("throwsClash.kt") + public void testThrowsClash() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/throwsClash.kt"); + } + + @Test + @TestMetadata("topLevelSingleton.kt") + public void testTopLevelSingleton() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/topLevelSingleton.kt"); + } +} diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendNativeDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendNativeDiagnosticsWithLightTreeTestGenerated.java new file mode 100644 index 00000000000..265b9ac194d --- /dev/null +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendNativeDiagnosticsWithLightTreeTestGenerated.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.test.runners; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("compiler/testData/diagnostics/nativeTests") +@TestDataPath("$PROJECT_ROOT") +public class FirOldFrontendNativeDiagnosticsWithLightTreeTestGenerated extends AbstractFirNativeDiagnosticsWithLightTreeTest { + @Test + public void testAllFilesPresentInNativeTests() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/nativeTests"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("identifiers.kt") + public void testIdentifiers() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/identifiers.kt"); + } + + @Test + @TestMetadata("objCName.kt") + public void testObjCName() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName.kt"); + } + + @Test + @TestMetadata("sharedImmutable.kt") + public void testSharedImmutable() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/sharedImmutable.kt"); + } + + @Test + @TestMetadata("threadLocal.kt") + public void testThreadLocal() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/threadLocal.kt"); + } + + @Test + @TestMetadata("throws.kt") + public void testThrows() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/throws.kt"); + } + + @Test + @TestMetadata("throwsClash.kt") + public void testThrowsClash() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/throwsClash.kt"); + } + + @Test + @TestMetadata("topLevelSingleton.kt") + public void testTopLevelSingleton() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/topLevelSingleton.kt"); + } +} diff --git a/compiler/fir/checkers/build.gradle.kts b/compiler/fir/checkers/build.gradle.kts index e637f5f47ad..f67b4a58ebb 100644 --- a/compiler/fir/checkers/build.gradle.kts +++ b/compiler/fir/checkers/build.gradle.kts @@ -37,6 +37,7 @@ val generationRoot = projectDir.resolve("gen") val platformGenerationRoots = listOf( "checkers.jvm", "checkers.js", + "checkers.native", ).map { projectDir.resolve(it).resolve("gen") } val generateCheckersComponents by tasks.registering(NoDebugJavaExec::class) { diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt index 3d6344bfc2a..59523c8e015 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.types.FirTypeRef import java.io.File import org.jetbrains.kotlin.fir.builder.SYNTAX_DIAGNOSTIC_LIST +import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.NATIVE_DIAGNOSTICS_LIST import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.ErrorListDiagnosticListRenderer fun main(args: Array) { @@ -97,11 +98,13 @@ fun main(args: Array) { val jvmGenerationPath = File(arguments.getOrElse(1) { "compiler/fir/checkers/checkers.jvm/gen" }) val jsGenerationPath = File(arguments.getOrElse(2) { "compiler/fir/checkers/checkers.js/gen" }) + val nativeGenerationPath = File(arguments.getOrElse(3) { "compiler/fir/checkers/checkers.native/gen" }) val rawFirGenerationPath = File("compiler/fir/raw-fir/raw-fir.common/gen") generateDiagnostics(generationPath, "$basePackage.diagnostics", DIAGNOSTICS_LIST, starImportsToAdd = setOf(ErrorListDiagnosticListRenderer.BASE_PACKAGE, ErrorListDiagnosticListRenderer.DIAGNOSTICS_PACKAGE)) generateDiagnostics(jvmGenerationPath, "$basePackage.diagnostics.jvm", JVM_DIAGNOSTICS_LIST, starImportsToAdd = setOf(ErrorListDiagnosticListRenderer.BASE_PACKAGE, ErrorListDiagnosticListRenderer.DIAGNOSTICS_PACKAGE)) generateDiagnostics(jsGenerationPath, "$basePackage.diagnostics.js", JS_DIAGNOSTICS_LIST, starImportsToAdd = setOf(ErrorListDiagnosticListRenderer.BASE_PACKAGE, ErrorListDiagnosticListRenderer.DIAGNOSTICS_PACKAGE)) + generateDiagnostics(nativeGenerationPath, "$basePackage.diagnostics.native", NATIVE_DIAGNOSTICS_LIST, starImportsToAdd = setOf(ErrorListDiagnosticListRenderer.BASE_PACKAGE, ErrorListDiagnosticListRenderer.DIAGNOSTICS_PACKAGE)) generateDiagnostics(rawFirGenerationPath, "org.jetbrains.kotlin.fir.builder", SYNTAX_DIAGNOSTIC_LIST, starImportsToAdd = setOf(ErrorListDiagnosticListRenderer.DIAGNOSTICS_PACKAGE)) } diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirNativeDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirNativeDiagnosticsList.kt new file mode 100644 index 00000000000..6d0f83bb2bc --- /dev/null +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirNativeDiagnosticsList.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.checkers.generator.diagnostics + +import org.jetbrains.kotlin.fir.PrivateForInline +import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.DiagnosticList + +@Suppress("UNUSED_VARIABLE", "LocalVariableName", "ClassName", "unused") +@OptIn(PrivateForInline::class) +object NATIVE_DIAGNOSTICS_LIST : DiagnosticList("FirNativeErrors") { + val ALL by object : DiagnosticGroup("All") { + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/checkers.native/build.gradle.kts b/compiler/fir/checkers/checkers.native/build.gradle.kts new file mode 100644 index 00000000000..65f103341bb --- /dev/null +++ b/compiler/fir/checkers/checkers.native/build.gradle.kts @@ -0,0 +1,38 @@ +import org.jetbrains.kotlin.ideaExt.idea + +plugins { + kotlin("jvm") + id("jps-compatible") +} + +dependencies { + api(project(":compiler:fir:checkers")) + + /* + * We can't remove this dependency until we use + * diagnostics framework from FE 1.0 + */ + implementation(project(":compiler:frontend")) + implementation(project(":compiler:psi")) + + compileOnly(project(":kotlin-reflect-api")) + compileOnly(intellijCore()) +} + +sourceSets { + "main" { + projectDefault() + this.java.srcDir("gen") + } + "test" { none() } +} + +val compileKotlin by tasks +compileKotlin.dependsOn(":compiler:fir:checkers:generateCheckersComponents") + +if (kotlinBuildProperties.isInJpsBuildIdeaSync) { + apply(plugin = "idea") + idea { + this.module.generatedSourceDirs.add(projectDir.resolve("gen")) + } +} diff --git a/compiler/fir/checkers/checkers.native/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/native/FirNativeErrors.kt b/compiler/fir/checkers/checkers.native/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/native/FirNativeErrors.kt new file mode 100644 index 00000000000..29df22941dd --- /dev/null +++ b/compiler/fir/checkers/checkers.native/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/native/FirNativeErrors.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.diagnostics.native + +import org.jetbrains.kotlin.diagnostics.* +import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory +import org.jetbrains.kotlin.fir.analysis.diagnostics.* + +/* + * This file was generated automatically + * DO NOT MODIFY IT MANUALLY + */ + +object FirNativeErrors { + // All + + init { + RootDiagnosticRendererFactory.registerFactory(FirNativeErrorsDefaultMessages) + } +} diff --git a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/diagnostics/native/FirNativeErrorsDefaultMessages.kt b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/diagnostics/native/FirNativeErrorsDefaultMessages.kt new file mode 100644 index 00000000000..fa372a22a39 --- /dev/null +++ b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/diagnostics/native/FirNativeErrorsDefaultMessages.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.diagnostics.native + +import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap +import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory + +object FirNativeErrorsDefaultMessages : BaseDiagnosticRendererFactory() { + override val MAP = KtDiagnosticFactoryToRendererMap("FIR") +} \ No newline at end of file diff --git a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/NativeDeclarationCheckers.kt b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/NativeDeclarationCheckers.kt new file mode 100644 index 00000000000..360dbea43b6 --- /dev/null +++ b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/NativeDeclarationCheckers.kt @@ -0,0 +1,11 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.native.checkers + +import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers + +object NativeDeclarationCheckers : DeclarationCheckers() { +} \ No newline at end of file diff --git a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/NativeExpressionCheckers.kt b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/NativeExpressionCheckers.kt new file mode 100644 index 00000000000..8d49edf033f --- /dev/null +++ b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/NativeExpressionCheckers.kt @@ -0,0 +1,11 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.native.checkers + +import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers + +object NativeExpressionCheckers : ExpressionCheckers() { +} \ No newline at end of file diff --git a/compiler/fir/entrypoint/build.gradle.kts b/compiler/fir/entrypoint/build.gradle.kts index e2ffc4f5cef..4a14cd99220 100644 --- a/compiler/fir/entrypoint/build.gradle.kts +++ b/compiler/fir/entrypoint/build.gradle.kts @@ -13,6 +13,7 @@ dependencies { api(project(":compiler:fir:checkers")) api(project(":compiler:fir:checkers:checkers.jvm")) api(project(":compiler:fir:checkers:checkers.js")) + api(project(":compiler:fir:checkers:checkers.native")) // TODO: do not use GeneratorExtensions in `FirAnalyzerFacade.convertToIr`, and make this an 'implementation' dependency. api(project(":compiler:ir.psi2ir")) diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CheckersContainers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CheckersContainers.kt index 18f373e9d59..64d44dc552c 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CheckersContainers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CheckersContainers.kt @@ -11,6 +11,8 @@ import org.jetbrains.kotlin.fir.analysis.js.checkers.JsExpressionCheckers import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmDeclarationCheckers import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmExpressionCheckers import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmTypeCheckers +import org.jetbrains.kotlin.fir.analysis.native.checkers.NativeDeclarationCheckers +import org.jetbrains.kotlin.fir.analysis.native.checkers.NativeExpressionCheckers import org.jetbrains.kotlin.fir.session.FirSessionConfigurator fun FirSessionConfigurator.registerCommonCheckers() { @@ -35,3 +37,8 @@ fun FirSessionConfigurator.registerJsCheckers() { useCheckers(JsDeclarationCheckers) useCheckers(JsExpressionCheckers) } + +fun FirSessionConfigurator.registerNativeCheckers() { + useCheckers(NativeDeclarationCheckers) + useCheckers(NativeExpressionCheckers) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/nativeTests/identifiers.fir.kt b/compiler/testData/diagnostics/nativeTests/identifiers.fir.kt new file mode 100644 index 00000000000..a9c275ac3de --- /dev/null +++ b/compiler/testData/diagnostics/nativeTests/identifiers.fir.kt @@ -0,0 +1,68 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -MISSING_DEPENDENCY_SUPERCLASS + +// FIXME: rename identifiers.kt + +// FILE: 1.kt +package `check.pkg` + +// FILE: 2.kt +package totally.normal.pkg + +class `Check.Class` +class NormalClass { + fun `check$member`() {} +} + +object `Check;Object` +object NormalObject + +data class Pair(val first: Int, val `next,one`: Int) + +object Delegate { + operator fun getValue(thisRef: Any?, property: kotlin.reflect.KProperty<*>): Any? = null +} + +fun `check(function`() { + val `check)variable` = 1 + val `check[delegated[variable` by Delegate + + val normalVariable = 2 + val normalDelegatedVariable by Delegate + + val (check, `destructuring]declaration`) = Pair(1, 2) +} + +fun normalFunction() {} + +val `check{property` = 1 +val `check}delegated}property` by Delegate +val normalProperty = 2 +val normalDelegatedProperty by Delegate + +fun checkValueParameter(`check/parameter`: Int) {} + +fun <`check checkTypeParameter() {} + +enum class `Check>Enum>Entry` { + `CHECK:ENUM:ENTRY`; +} + +typealias `check\typealias` = Any + +fun `check&`() {} + +fun `check~`() {} + +fun `check*`() {} + +fun `check?`() {} + +fun `check#`() {} + +fun `check|`() {} + +fun `check§`() {} + +fun `check%`() {} + +fun `check@`() {} diff --git a/compiler/testData/diagnostics/nativeTests/objCName.fir.kt b/compiler/testData/diagnostics/nativeTests/objCName.fir.kt new file mode 100644 index 00000000000..f9ba2193997 --- /dev/null +++ b/compiler/testData/diagnostics/nativeTests/objCName.fir.kt @@ -0,0 +1,179 @@ +// FILE: kotlin.kt +package kotlin.native + +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.PROPERTY, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.FUNCTION +) +@Retention(AnnotationRetention.BINARY) +@MustBeDocumented +public annotation class ObjCName(val name: String = "", val swiftName: String = "", val exact: Boolean = false) + +// FILE: test.kt +@ObjCName("ObjCClass", "SwiftClass") +open class KotlinClass { + @ObjCName("objCProperty") + open var kotlinProperty: Int = 0 + @ObjCName(swiftName = "swiftFunction") + open fun @receiver:ObjCName("objCReceiver") Int.kotlinFunction( + @ObjCName("objCParam") kotlinParam: Int + ): Int = this + kotlinParam +} + +@ObjCName("ObjCSubClass", "SwiftSubClass") +class KotlinSubClass: KotlinClass() { + @ObjCName("objCProperty") + override var kotlinProperty: Int = 1 + @ObjCName(swiftName = "swiftFunction") + override fun @receiver:ObjCName("objCReceiver") Int.kotlinFunction( + @ObjCName("objCParam") kotlinParam: Int + ): Int = this + kotlinParam * 2 +} + +@ObjCName() +val invalidObjCName: Int = 0 + +@ObjCName("validName", "invalid.name") +val invalidCharactersObjCNameA: Int = 0 + +@ObjCName("invalid.name", "validName") +val invalidCharactersObjCNameB: Int = 0 + +@ObjCName("validName1", "1validName") +val invalidFirstCharacterObjCNameA: Int = 0 + +@ObjCName("1validName", "validName1") +val invalidFirstCharacterObjCNameB: Int = 0 + +@ObjCName(swiftName = "SwiftMissingExactName", exact = true) +class MissingExactName + +interface KotlinInterfaceA { + @ObjCName("objCPropertyA", "swiftPropertyA") + var kotlinPropertyA: Int + @ObjCName("objCPropertyB", "swiftPropertyB") + var kotlinPropertyB: Int + @ObjCName("objCPropertyB") + var kotlinPropertyC: Int + @ObjCName(swiftName ="swiftPropertyB") + var kotlinPropertyD: Int + var kotlinPropertyE: Int + var kotlinPropertyF: Int + + @ObjCName("objCFunctionA", "swiftFunctionA") + fun @receiver:ObjCName("objCReceiver", "swiftReceiver") Int.kotlinFunctionA( + @ObjCName("objCParam", "swiftParam") kotlinParam: Int + ): Int + @ObjCName("objCFunctionB", "swiftFunctionB") + fun @receiver:ObjCName("objCReceiver", "swiftReceiver") Int.kotlinFunctionB( + @ObjCName("objCParam", "swiftParam") kotlinParam: Int + ): Int + @ObjCName("objCFunctionC", "swiftFunctionC") + fun @receiver:ObjCName("objCReceiver", "swiftReceiver") Int.kotlinFunctionC( + @ObjCName("objCParam", "swiftParam") kotlinParam: Int + ): Int + @ObjCName("objCFunctionD", "swiftFunctionD") + fun @receiver:ObjCName("objCReceiver", "swiftReceiver") Int.kotlinFunctionD( + @ObjCName("objCParam", "swiftParam") kotlinParam: Int + ): Int + @ObjCName("objCFunctionE", "swiftFunctionE") + fun Int.kotlinFunctionE(@ObjCName("objCParam", "swiftParam") kotlinParam: Int): Int +} + +interface KotlinInterfaceB { + @ObjCName("objCPropertyA", "swiftPropertyA") + var kotlinPropertyA: Int + @ObjCName("objCPropertyBB", "swiftPropertyB") + var kotlinPropertyB: Int + @ObjCName(swiftName ="swiftPropertyC") + var kotlinPropertyC: Int + @ObjCName("objCPropertyD") + var kotlinPropertyD: Int + @ObjCName("objCPropertyE") + var kotlinPropertyE: Int + var kotlinPropertyF: Int + + @ObjCName("objCFunctionA", "swiftFunctionA") + fun @receiver:ObjCName("objCReceiver", "swiftReceiver") Int.kotlinFunctionA( + @ObjCName("objCParam", "swiftParam") kotlinParam: Int + ): Int + @ObjCName("objCFunctionBB", "swiftFunctionB") + fun @receiver:ObjCName("objCReceiver", "swiftReceiver") Int.kotlinFunctionB( + @ObjCName("objCParam", "swiftParam") kotlinParam: Int + ): Int + @ObjCName("objCFunctionC", "swiftFunctionC") + fun @receiver:ObjCName("objCReceiverC", "swiftReceiver") Int.kotlinFunctionC( + @ObjCName("objCParam", "swiftParam") kotlinParam: Int + ): Int + @ObjCName("objCFunctionD", "swiftFunctionD") + fun @receiver:ObjCName("objCReceiver", "swiftReceiver") Int.kotlinFunctionD( + @ObjCName("objCParamD", "swiftParam") kotlinParam: Int + ): Int + fun @receiver:ObjCName("objCFunctionE", "swiftFunctionE") Int.kotlinFunctionE( + @ObjCName("objCParam", "swiftParam") kotlinParam: Int + ): Int +} + +class KotlinOverrideClass: KotlinInterfaceA, KotlinInterfaceB { + override var kotlinPropertyA: Int = 0 + override var kotlinPropertyB: Int = 0 + override var kotlinPropertyC: Int = 0 + override var kotlinPropertyD: Int = 0 + override var kotlinPropertyE: Int = 0 + override var kotlinPropertyF: Int = 0 + + override fun Int.kotlinFunctionA(kotlinParam: Int): Int = this + kotlinParam + override fun Int.kotlinFunctionB(kotlinParam: Int): Int = this + kotlinParam + override fun Int.kotlinFunctionC(kotlinParam: Int): Int = this + kotlinParam + override fun Int.kotlinFunctionD(kotlinParam: Int): Int = this + kotlinParam + override fun Int.kotlinFunctionE(kotlinParam: Int): Int = this + kotlinParam +} + +@ObjCName("ObjCExactChecks", exact = true) +class ExactChecks { + @ObjCName("objCProperty", exact = true) + var property: Int = 0 + @ObjCName("objCFunction", exact = true) + fun @receiver:ObjCName("objCReceiver", exact = true) Int.function( + @ObjCName("objCParam", exact = true) param: Int + ): Int = this * param +} + +@ObjCName("ObjCEnumExactChecks", exact = true) +enum class EnumExactChecks { + @ObjCName("objCEntryOne", exact = true) + ENTRY_ONE, + @ObjCName("objCEntryTwo") + ENTRY_TWO +} + +open class Base { + @ObjCName("foo1") + open fun foo() {} +} + +interface I { + @ObjCName("foo2") + fun foo() +} + +open class Derived : Base(), I + +open class Derived2 : Derived() { + override fun foo() {} +} + +private const val exact = false +private const val objcName = "nonLiteralArgsObjC" + +@ObjCName( + objcName, + "nonLiteralArgs" + "Swift", + exact +) +val nonLiteralArgs: Int = 0 + +@ObjCName("invalidArgsObjC", false, "not a boolean") +val invalidArgs: Int = 0 diff --git a/compiler/testData/diagnostics/nativeTests/sharedImmutable.fir.kt b/compiler/testData/diagnostics/nativeTests/sharedImmutable.fir.kt new file mode 100644 index 00000000000..1fbe4c85f9a --- /dev/null +++ b/compiler/testData/diagnostics/nativeTests/sharedImmutable.fir.kt @@ -0,0 +1,145 @@ +// FILE: annotation.kt +package kotlin.native.concurrent + +import kotlin.reflect.KProperty + +@Target(AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.BINARY) +annotation class SharedImmutable + +@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS) +@Retention(AnnotationRetention.BINARY) +annotation class ThreadLocal + +// FILE: test.kt +import kotlin.native.concurrent.SharedImmutable +import kotlin.native.concurrent.ThreadLocal +import kotlin.reflect.KProperty + +fun println(value: Int) {} +fun println(value: String) {} +fun println(value: Point) {} + +data class Point(val x: Double, val y: Double) +@SharedImmutable +val point1 = Point(1.0, 1.0) + +@SharedImmutable +var point2 = Point(2.0, 2.0) + +class Date(@SharedImmutable val month: Int, @SharedImmutable var day:Int) +class Person(val name: String) { + @SharedImmutable + var surname: String? = null +} + +class Figure { + @SharedImmutable + val cornerPoint: Point + get() = point1 +} + +@SharedImmutable +var age = 20 + get() { + println("Age is: $field") + return field + } + set(value) { + println(value) + } + +var globalAge = 30 +@SharedImmutable +var age1 = 20 + get() { + println("Age is: $field") + return field + } + set(value) { + globalAge = value + } + +@SharedImmutable +val age2 = 20 + get() { + println("Age is: $field") + return field + } + +@SharedImmutable +var point3: Point + get() = point2 + set(value) { + point2 = value + } + +@SharedImmutable +var point4: Point + get() = point2 + set(value) { + println(value) + } + +@ThreadLocal +var point0 = Point(2.0, 2.0) + +@SharedImmutable +var point5: Point + get() = point0 + set(value) { + point0 = value + } + + +class Delegate { + var value = 20 + operator fun getValue(thisRef: Any?, property: KProperty<*>): Int { + println("Get") + return value + } + + operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) { + println("Set") + } +} + +@SharedImmutable +var property: Int by Delegate() + +class Delegate1 { + var value = 20 + operator fun getValue(thisRef: Any?, property: KProperty<*>): Int { + return value + } + + operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) { + this.value = value + } +} + +@SharedImmutable +var property1: Int by Delegate1() + +var globalValue: Int = 20 + +class Delegate2 { + + operator fun getValue(thisRef: Any?, property: KProperty<*>): Int { + return globalValue + } + + operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) { + println(value) + } +} + +@SharedImmutable +var property2: Int by Delegate2() + +@SharedImmutable +val someValue: Int + get() = 20 + +@SharedImmutable +val someValueWithDelegate by Delegate() diff --git a/compiler/testData/diagnostics/nativeTests/threadLocal.fir.kt b/compiler/testData/diagnostics/nativeTests/threadLocal.fir.kt new file mode 100644 index 00000000000..498524e9446 --- /dev/null +++ b/compiler/testData/diagnostics/nativeTests/threadLocal.fir.kt @@ -0,0 +1,71 @@ +// FILE: annotation.kt +package kotlin.native.concurrent + +@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS) +@Retention(AnnotationRetention.BINARY) +annotation class ThreadLocal + +// FILE: test.kt +import kotlin.native.concurrent.ThreadLocal +import kotlin.reflect.KProperty + +data class Point(val x: Double, val y: Double) + +class Person(val name: String) { + @ThreadLocal + var surname: String? = null +} + +abstract class Information { + abstract var field: String +} + +@ThreadLocal +class Person1(val name: String) { + var surname: String? = null + @ThreadLocal + val extraInfo: Information = object : Information() { + override var field: String = "extra info" + } +} + +@ThreadLocal +val extraInfo: Information = object : Information() { + override var field: String = "extra info" +} + +@ThreadLocal +val point1 = Point(1.0, 1.0) + +@ThreadLocal +val cornerPoint: Point + get() = point1 + +@ThreadLocal +val person = Person1("aaaaa") + +class Delegate { + val value: Int = 10 + operator fun getValue(thisRef: Any?, property: KProperty<*>): Int { + return value + } + + operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) { + } +} + +@ThreadLocal +var field1: Int by Delegate() + +@ThreadLocal +object WithDelegate { + var field1: Int by Delegate() +} + +class Bar { + @ThreadLocal + object SomeObject { + var field1: Int = 10 + var field2: String? = null + } +} diff --git a/compiler/testData/diagnostics/nativeTests/throws.fir.kt b/compiler/testData/diagnostics/nativeTests/throws.fir.kt new file mode 100644 index 00000000000..19bd221be31 --- /dev/null +++ b/compiler/testData/diagnostics/nativeTests/throws.fir.kt @@ -0,0 +1,371 @@ +// FILE: kotlin.kt +package kotlin + +import kotlin.reflect.KClass + +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR) +@Retention(AnnotationRetention.SOURCE) +public annotation class Throws(vararg val exceptionClasses: KClass) + +public open class Exception : Throwable() + +public open class RuntimeException : Exception() + +public open class IllegalStateException : RuntimeException() + +// FILE: native.kt +package kotlin.native + +@Deprecated("") +public typealias Throws = kotlin.Throws + +// FILE: CancellationException.kt +package kotlin.coroutines.cancellation + +public open class CancellationException() : IllegalStateException() + +// FILE: test.kt +import kotlin.coroutines.cancellation.CancellationException + +class Exception1 : Throwable() +class Exception2 : Throwable() +class Exception3 : Throwable() + +@Throws +fun foo() {} + +@Throws() +fun throwsEmptyParens() {} + +@Throws(UnresolvedException::class) +fun throwsUnresolved() {} + +@Throws(exceptionClasses = UnresolvedException::class) +fun throwsNamedUnresolved() {} + +@Throws(exceptionClasses = []) +fun throwsNamedEmptyLiteral() {} + +@Throws(exceptionClasses = arrayOf()) +fun throwsNamedEmptyArrayOf() {} + +@Throws(*[]) +fun throwsSpreadEmptyLiteral() {} + +@Throws(*arrayOf()) +fun throwsSpreadEmptyArrayOf() {} + +@Throws(exceptionClasses = [UE::class]) +fun throwsNamedLiteralWithUnresolved() {} + +@Throws(exceptionClasses = arrayOf(UE::class)) +fun throwsNamedArrayOfUnresolved() {} + +@Throws(*[UE::class]) +fun throwsSpreadLiteralWithUnresolved() {} + +@Throws(*arrayOf(UE::class)) +fun throwsSpreadArrayOfUnresolved() {} + +typealias UEAlias = UE + +@Throws(UEAlias::class) +fun throwsTypealiasToUnresolved() {} + +interface Base0 { + fun foo() +} + +class ThrowsOnOverride : Base0 { + @Throws(Exception1::class) override fun foo() {} +} + +interface Base1 { + @Throws(Exception1::class) fun foo() +} + +class InheritsThrowsAndNoThrows : Base0, Base1 { + override fun foo() {} +} + +class OverridesThrowsAndNoThrows : Base0, Base1 { + @Throws(Exception1::class) override fun foo() {} +} + +class SameThrowsOnOverride : Base1 { + @Throws(Exception1::class) override fun foo() {} +} + +class DifferentThrowsOnOverride : Base1 { + @Throws(Exception2::class) override fun foo() {} +} + +class HasThrowsWithEmptyListOnOverride : Base1 { + @Throws override fun foo() {} +} + +interface Base2 { + @Throws(Exception2::class) fun foo() +} + +open class InheritsDifferentThrows1 : Base1, Base2 { + override fun foo() {} +} + +open class OverridesDifferentThrows1_1 : Base1, Base2 { + @Throws(Exception1::class) override fun foo() {} +} + +open class OverridesDifferentThrows1_2 : Base1, Base2 { + @Throws(Exception2::class) override fun foo() {} +} + +open class OverridesDifferentThrows1_3 : Base1, Base2 { + @Throws(Exception1::class, Exception2::class) override fun foo() {} +} + +class InheritsDifferentThrowsThroughSameClass1 : InheritsDifferentThrows1() { + override fun foo() {} +} + +class OverridesDifferentThrowsThroughSameClass1 : InheritsDifferentThrows1() { + @Throws(Exception1::class) override fun foo() {} +} + +class OverridesDifferentThrowsThroughSameClass2 : InheritsDifferentThrows1() { + @Throws(Exception2::class) override fun foo() {} +} + +interface Base3 { + @Throws(Exception3::class) fun foo() +} + +class InheritsDifferentThrows2 : InheritsDifferentThrows1(), Base3 { + override fun foo() {} +} + +class OverridesDifferentThrows2 : InheritsDifferentThrows1(), Base3 { + @Throws(Exception3::class) override fun foo() {} +} + +open class OverridesDifferentThrows3 : Base1, Base2 { + @Throws(Exception3::class) override fun foo() {} +} + +class InheritsDifferentThrows3 : OverridesDifferentThrows3() { + override fun foo() {} +} + +class OverrideDifferentThrows4 : OverridesDifferentThrows3() { + override fun foo() {} +} + +class OverrideDifferentThrows5 : OverridesDifferentThrows3() { + @Throws(Exception3::class) override fun foo() {} +} + +class OverrideDifferentThrows6 : OverridesDifferentThrows3() { + @Throws(Exception1::class) override fun foo() {} +} + +interface Base4 { + @Throws(Exception1::class) fun foo() +} + +class InheritsSameThrows : Base1, Base4 { + override fun foo() {} +} + +class OverridesSameThrows : Base1, Base4 { + @Throws(Exception1::class) override fun foo() {} +} + +class OverrideDifferentThrows7 : Base1, Base4 { + @Throws(Exception2::class) override fun foo() {} +} + +class OverrideDifferentThrows8 : Base1, Base3 { + @Throws(Exception2::class) override fun foo() {} +} + +interface Base5 { + @Throws(Exception1::class, Exception2::class) fun foo() +} + +interface Base6 { + @Throws(Exception2::class, Exception1::class) fun foo() +} + +class InheritsSameThrowsMultiple : Base5, Base6 { + override fun foo() {} +} + +class OverridesSameThrowsMultiple1 : Base5, Base6 { + @Throws(Exception1::class, Exception2::class) override fun foo() {} +} + +class OverridesSameThrowsMultiple2 : Base5, Base6 { + @Throws(Exception2::class, Exception1::class) override fun foo() {} +} + +class OverridesDifferentThrowsMultiple : Base5, Base6 { + @Throws(Exception1::class) override fun foo() {} +} + +fun withLocalClass() { + class LocalException : Throwable() + + abstract class Base7 { + @Throws(Exception1::class, LocalException::class) abstract fun foo() + } + + class InheritsDifferentThrowsLocal : Base1, Base7() { + override fun foo() {} + } + + class OverridesDifferentThrowsLocal : Base1, Base7() { + @Throws(Exception1::class, LocalException::class) override fun foo() {} + } +} + +interface ThrowsOnFakeOverride : Base1 + +class InheritThrowsOnFakeOverride : ThrowsOnFakeOverride { + override fun foo() {} +} + +class OverrideDifferentThrowsOnFakeOverride : ThrowsOnFakeOverride { + @Throws(Exception2::class) override fun foo() {} +} + +interface IncompatibleThrowsOnFakeOverride : Base1, Base2 + +class OverrideIncompatibleThrowsOnFakeOverride1 : IncompatibleThrowsOnFakeOverride { + @Throws(Exception1::class) override fun foo() {} +} + +class OverrideIncompatibleThrowsOnFakeOverride2 : IncompatibleThrowsOnFakeOverride { + @Throws(Exception2::class) override fun foo() {} +} + +class InheritIncompatibleThrowsOnFakeOverride : IncompatibleThrowsOnFakeOverride { + override fun foo() {} +} + +@Throws +suspend fun suspendThrowsNothing() {} + +interface SuspendFun { + suspend fun foo() +} + +class OverrideImplicitThrowsOnSuspendWithExplicit : SuspendFun { + // Although `SuspendFun.foo` effectively has `@Throws(CancellationException::class)`, + // overriding it with equal explicit `@Throws` is forbidden: + @Throws(CancellationException::class) override suspend fun foo() {} +} + +interface SuspendFunThrows { + @Throws(CancellationException::class) suspend fun foo() {} +} + +class InheritExplicitThrowsOnSuspend : SuspendFunThrows { + override suspend fun foo() {} +} + +@Throws(Exception1::class) +suspend fun suspendDoesNotThrowCancellationException1() {} + +@Throws(Exception1::class, Exception2::class) +suspend fun suspendDoesNotThrowCancellationException2() {} + +@Throws(UE::class) +suspend fun suspendThrowsUnresolved() {} + +@Throws(exceptionClasses = UE::class) +suspend fun suspendThrowsNamedUnresolved() {} + +@Throws(exceptionClasses = []) +suspend fun suspendThrowsNamedEmptyLiteral() {} + +@Throws(exceptionClasses = arrayOf()) +suspend fun suspendThrowsNamedEmptyArrayOf() {} + +@Throws(*[]) +suspend fun suspendThrowsSpreadEmptyLiteral() {} + +@Throws(*arrayOf()) +suspend fun suspendThrowsSpreadEmptyArrayOf() {} + +@Throws(exceptionClasses = [UE::class]) +suspend fun suspendThrowsNamedLiteralWithUnresolved() {} + +@Throws(exceptionClasses = arrayOf(UE::class)) +suspend fun suspendThrowsNamedArrayOfUnresolved() {} + +@Throws(*[UE::class]) +suspend fun suspendThrowsSpreadLiteralWithUnresolved() {} + +@Throws(*arrayOf(UE::class)) +suspend fun suspendThrowsSpreadArrayOfUnresolved() {} + +@Throws(UEAlias::class) +suspend fun suspendThrowsTypealiasToUnresolved() {} + +@Throws(Exception1::class, CancellationException::class) +suspend fun suspendThrowsCancellationException1() {} + +@Throws(CancellationException::class, Exception1::class) +suspend fun suspendThrowsCancellationException2() {} + +typealias CancellationExceptionAlias = CancellationException + +@Throws(CancellationExceptionAlias::class) +suspend fun suspendThrowsCancellationExceptionTypealias() {} + +@Throws(IllegalStateException::class) +suspend fun suspendThrowsIllegalStateException1() {} + +@Throws(Exception2::class, IllegalStateException::class) +suspend fun suspendThrowsIllegalStateException2() {} + +typealias IllegalStateExceptionAlias = IllegalStateException + +@Throws(IllegalStateExceptionAlias::class) +suspend fun suspendThrowsIllegalStateExceptionTypealias() {} + +@Throws(RuntimeException::class) +suspend fun suspendThrowsRuntimeException1() {} + +@Throws(RuntimeException::class, Exception3::class) +suspend fun suspendThrowsRuntimeException2() {} + +typealias RuntimeExceptionAlias = RuntimeException + +@Throws(RuntimeExceptionAlias::class) +suspend fun suspendThrowsRuntimeExceptionTypealias() {} + +@Throws(Exception::class) +suspend fun suspendThrowsException1() {} + +@Throws(Exception1::class, Exception::class) +suspend fun suspendThrowsException2() {} + +typealias ExceptionAlias = Exception + +@Throws(ExceptionAlias::class) +suspend fun suspendThrowsExceptionTypealias() {} + +@Throws(Throwable::class) +suspend fun suspendThrowsThrowable1() {} + +@Throws(Throwable::class, Exception2::class) +suspend fun suspendThrowsThrowable2() {} + +@Throws(Throwable::class, CancellationException::class) +suspend fun suspendThrowsThrowable3() {} + +typealias ThrowableAlias = Throwable + +@Throws(ThrowableAlias::class) +suspend fun suspendThrowsThrowableTypealias() {} diff --git a/compiler/testData/diagnostics/nativeTests/throwsClash.fir.kt b/compiler/testData/diagnostics/nativeTests/throwsClash.fir.kt new file mode 100644 index 00000000000..e7ffa029762 --- /dev/null +++ b/compiler/testData/diagnostics/nativeTests/throwsClash.fir.kt @@ -0,0 +1,179 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER +// FILE: throws.kt +package kotlin + +import kotlin.reflect.KClass + +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR) +@Retention(AnnotationRetention.SOURCE) +public annotation class Throws(vararg val ThrowableClasses: KClass) + +// FILE: native.kt +package kotlin.native + +@Deprecated("") +public typealias Throws = kotlin.Throws + +// FILE: main1.kt +package abc1 + +@Throws(Throwable::class) +fun foo1() {} + +@kotlin.Throws(Throwable::class) +fun foo2() {} + +@kotlin.native.Throws(Throwable::class) +fun foo3() {} + +fun foo5(x: Throws) {} +fun foo6(x: kotlin.Throws) {} +fun foo7(x: kotlin.native.Throws) {} + +// FILE: main2.kt +package abc2 + +import kotlin.native.Throws + +@Throws(Throwable::class) +fun foo1() {} + +@kotlin.Throws(Throwable::class) +fun foo2() {} + +@kotlin.native.Throws(Throwable::class) +fun foo3() {} + +fun foo5(x: Throws) {} +fun foo6(x: kotlin.Throws) {} +fun foo7(x: kotlin.native.Throws) {} + +// FILE: main3.kt +package abc3 + +import kotlin.Throws + +@Throws(Throwable::class) +fun foo1() {} + +@kotlin.Throws(Throwable::class) +fun foo2() {} + +@kotlin.native.Throws(Throwable::class) +fun foo3() {} + +fun foo5(x: Throws) {} +fun foo6(x: kotlin.Throws) {} +fun foo7(x: kotlin.native.Throws) {} + +// FILE: main4.kt +package abc4 + +import kotlin.Throws +import kotlin.native.Throws + +@Throws(Throwable::class) +fun foo1() {} + +@kotlin.Throws(Throwable::class) +fun foo2() {} + +@kotlin.native.Throws(Throwable::class) +fun foo3() {} + +fun foo5(x: Throws) {} +fun foo6(x: kotlin.Throws) {} +fun foo7(x: kotlin.native.Throws) {} + +// FILE: main5.kt +package abc5 + +import kotlin.native.* + +@Throws(Throwable::class) +fun foo1() {} + +@kotlin.Throws(Throwable::class) +fun foo2() {} + +@kotlin.native.Throws(Throwable::class) +fun foo3() {} + +fun foo5(x: Throws) {} +fun foo6(x: kotlin.Throws) {} +fun foo7(x: kotlin.native.Throws) {} + +// FILE: main6.kt +package abc6 + +import kotlin.* + +@Throws(Throwable::class) +fun foo1() {} + +@kotlin.Throws(Throwable::class) +fun foo2() {} + +@kotlin.native.Throws(Throwable::class) +fun foo3() {} + +fun foo5(x: Throws) {} +fun foo6(x: kotlin.Throws) {} +fun foo7(x: kotlin.native.Throws) {} + +// FILE: main7.kt +package abc7 + +import kotlin.* +import kotlin.native.* + +@Throws(Throwable::class) +fun foo1() {} + +@kotlin.Throws(Throwable::class) +fun foo2() {} + +@kotlin.native.Throws(Throwable::class) +fun foo3() {} + +fun foo5(x: Throws) {} +fun foo6(x: kotlin.Throws) {} +fun foo7(x: kotlin.native.Throws) {} + +// FILE: main8.kt +package abc8 + +import kotlin.* +import kotlin.native.Throws + +@Throws(Throwable::class) +fun foo1() {} + +@kotlin.Throws(Throwable::class) +fun foo2() {} + +@kotlin.native.Throws(Throwable::class) +fun foo3() {} + +fun foo5(x: Throws) {} +fun foo6(x: kotlin.Throws) {} +fun foo7(x: kotlin.native.Throws) {} + +// FILE: main9.kt +package abc9 + +import kotlin.native.* +import kotlin.Throws + +@Throws(Throwable::class) +fun foo1() {} + +@kotlin.Throws(Throwable::class) +fun foo2() {} + +@kotlin.native.Throws(Throwable::class) +fun foo3() {} + +fun foo5(x: Throws) {} +fun foo6(x: kotlin.Throws) {} +fun foo7(x: kotlin.native.Throws) {} diff --git a/compiler/testData/diagnostics/nativeTests/topLevelSingleton.fir.kt b/compiler/testData/diagnostics/nativeTests/topLevelSingleton.fir.kt new file mode 100644 index 00000000000..ef896bced45 --- /dev/null +++ b/compiler/testData/diagnostics/nativeTests/topLevelSingleton.fir.kt @@ -0,0 +1,114 @@ +// FILE: annotation.kt +package kotlin.native.concurrent + +@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS) +@Retention(AnnotationRetention.BINARY) +annotation class ThreadLocal + +// FILE: test.kt +import kotlin.native.concurrent.ThreadLocal + +import kotlin.reflect.KProperty + +class Delegate { + val value: Int = 10 + operator fun getValue(thisRef: Any?, property: KProperty<*>): Int { + return value + } + + operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) { + } +} + +class AtomicInt(var value: Int) +object Foo { + var field1: Int = 10 + val backer2 = AtomicInt(0) + var field2: Int + get() = backer2.value + set(value: Int) { backer2.value = value } +} + +object Foo1 { + var field1: Int = 10 + set(value: Int) { backer2.value = value } + val backer2 = AtomicInt(0) +} + +object WithDelegate { + var field1: Int by Delegate() +} + +@ThreadLocal +object Bar { + var field1: Int = 10 + var field2: String? = null +} + +class Foo2 { + companion object { + var field1: Int = 10 + val backer2 = AtomicInt(0) + var field2: Int + get() = backer2.value + set(value: Int) { + backer2.value = value + } + } +} + +class Bar2 { + @ThreadLocal + companion object { + var field1: Int = 10 + var field2: String? = null + } +} + +@ThreadLocal +enum class Color(var rgb: Int) { + RED(0xFF0000), + GREEN(0x00FF00), + BLUE(0x0000FF) +} + +enum class Color1(var rgb: Int) { + RED(0xFF0000), + GREEN(0x00FF00), + BLUE(0x0000FF); + + init { this.rgb += 1 } +} + +@ThreadLocal +var a = 3 +enum class Color2() { + RED(), + GREEN(), + BLUE(); + + var rgb: Int = 2 + set(value: Int) { + a = value + } +} + +enum class Color3() { + RED(), + GREEN(), + BLUE(); + + var field1: Int by Delegate() +} + +enum class Color4 { + RED { + var a = 2 + override fun foo() { a = 42 } + }, + GREEN, + BLUE; + open fun foo() {} +} + +var topLevelProperty = "Global var" diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsNativeTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsNativeTestGenerated.java index 43291945d8c..564468ac9ff 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsNativeTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsNativeTestGenerated.java @@ -21,7 +21,7 @@ import java.util.regex.Pattern; public class DiagnosticsNativeTestGenerated extends AbstractDiagnosticsNativeTest { @Test public void testAllFilesPresentInNativeTests() throws Exception { - KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/nativeTests"), Pattern.compile("^(.+)\\.kt$"), null, true); + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/nativeTests"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } @Test diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt index 169e3799e0b..1375f68f918 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt @@ -99,8 +99,8 @@ class FirFrontendFacade( val isCommonOrJvm = module.targetPlatform.isJvm() || module.targetPlatform.isCommon() - val dependencyList: DependencyListForCliModule = buildDependencyList(module, moduleName, moduleInfoProvider, analyzerServices) { - if (isCommonOrJvm) { + val dependencyList = buildDependencyList(module, moduleName, moduleInfoProvider, analyzerServices) { + if (isCommonOrJvm || module.targetPlatform.isNative()) { configureJvmDependencies(configuration) } else { configureJsDependencies(module, testServices) @@ -109,35 +109,47 @@ class FirFrontendFacade( val projectEnvironment: VfsBasedProjectEnvironment? - if (isCommonOrJvm) { - val packagePartProviderFactory = compilerConfigurationProvider.getPackagePartProviderFactory(module) - projectEnvironment = VfsBasedProjectEnvironment( - project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL), - ) { packagePartProviderFactory.invoke(it) } - val projectFileSearchScope = PsiBasedProjectFileSearchScope(ProjectScope.getLibrariesScope(project)) - val packagePartProvider = projectEnvironment.getPackagePartProvider(projectFileSearchScope) + when { + isCommonOrJvm -> { + val packagePartProviderFactory = compilerConfigurationProvider.getPackagePartProviderFactory(module) + projectEnvironment = VfsBasedProjectEnvironment( + project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL), + ) { packagePartProviderFactory.invoke(it) } + val projectFileSearchScope = PsiBasedProjectFileSearchScope(ProjectScope.getLibrariesScope(project)) + val packagePartProvider = projectEnvironment.getPackagePartProvider(projectFileSearchScope) - FirSessionFactory.createLibrarySession( - moduleName, - moduleInfoProvider.firSessionProvider, - dependencyList, - projectEnvironment, - projectFileSearchScope, - packagePartProvider, - languageVersionSettings, - ) - } else { - projectEnvironment = null - - FirJsSessionFactory.createLibrarySession( - moduleName, - moduleInfoProvider.firSessionProvider, - dependencyList, - module, - testServices, - configuration, - languageVersionSettings, - ) + FirSessionFactory.createLibrarySession( + moduleName, + moduleInfoProvider.firSessionProvider, + dependencyList, + projectEnvironment, + projectFileSearchScope, + packagePartProvider, + languageVersionSettings, + ) + } + module.targetPlatform.isJs() -> { + projectEnvironment = null + FirJsSessionFactory.createLibrarySession( + moduleName, + moduleInfoProvider.firSessionProvider, + dependencyList, + module, + testServices, + configuration, + languageVersionSettings, + ) + } + module.targetPlatform.isNative() -> { + projectEnvironment = null + FirNativeSessionFactory.createLibrarySession( + moduleName, + moduleInfoProvider.firSessionProvider, + dependencyList, + languageVersionSettings, + ) + } + else -> error("Unsupported") } val mainModuleData = FirModuleDataImpl( @@ -175,6 +187,15 @@ class FirFrontendFacade( sessionConfigurator, ) } + module.targetPlatform.isNative() -> { + FirNativeSessionFactory.createModuleBasedSession( + mainModuleData, + moduleInfoProvider.firSessionProvider, + extensionRegistrars, + languageVersionSettings, + init = sessionConfigurator + ) + } else -> error("Unsupported") } diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirNativeSessionFactory.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirNativeSessionFactory.kt new file mode 100644 index 00000000000..02e70d22535 --- /dev/null +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirNativeSessionFactory.kt @@ -0,0 +1,84 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.test.frontend.fir + +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.fir.* +import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper +import org.jetbrains.kotlin.fir.checkers.registerNativeCheckers +import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar +import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider +import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirBuiltinSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCloneableSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirDependenciesSymbolProviderImpl +import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider +import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper +import org.jetbrains.kotlin.fir.session.FirAbstractSessionFactory +import org.jetbrains.kotlin.fir.session.FirSessionConfigurator +import org.jetbrains.kotlin.name.Name + +object FirNativeSessionFactory : FirAbstractSessionFactory() { + fun createLibrarySession( + mainModuleName: Name, + sessionProvider: FirProjectSessionProvider, + dependencyListForCliModule: DependencyListForCliModule, + languageVersionSettings: LanguageVersionSettings + ): FirSession { + val moduleDataProvider = dependencyListForCliModule.moduleDataProvider + return createLibrarySession( + mainModuleName, + sessionProvider, + moduleDataProvider, + languageVersionSettings, + null, + createKotlinScopeProvider = { FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope } }, + createProviders = { session, builtinsModuleData, kotlinScopeProvider -> + listOf( + FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), + FirCloneableSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), + FirDependenciesSymbolProviderImpl(session), + ) + }) + } + + fun createModuleBasedSession( + moduleData: FirModuleData, + sessionProvider: FirProjectSessionProvider, + extensionRegistrars: List, + languageVersionSettings: LanguageVersionSettings, + init: FirSessionConfigurator.() -> Unit + ): FirSession { + return createModuleBasedSession( + moduleData, + sessionProvider, + extensionRegistrars, + languageVersionSettings, + null, + null, + init, + registerExtraComponents = { it.registerExtraComponentsForModuleBased() }, + registerExtraCheckers = { it.registerNativeCheckers() }, + createKotlinScopeProvider = { FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope } }, + createProviders = { _, _, symbolProvider, generatedSymbolsProvider, dependenciesSymbolProvider -> + listOfNotNull( + symbolProvider, + generatedSymbolsProvider, + dependenciesSymbolProvider, + ) + } + ) + } + + @OptIn(SessionConfiguration::class) + fun FirSession.registerExtraComponentsForModuleBased() { + register(FirVisibilityChecker::class, FirVisibilityChecker.Default) + register(ConeCallConflictResolverFactory::class, NativeCallConflictResolverFactory) + register(FirPlatformClassMapper::class, FirPlatformClassMapper.Default) + register(FirSyntheticNamesProvider::class, FirNativeSyntheticNamesProvider) + register(FirOverridesBackwardCompatibilityHelper::class, FirOverridesBackwardCompatibilityHelper.Default()) + } +} \ No newline at end of file diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirNativeSyntheticNamesProvider.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirNativeSyntheticNamesProvider.kt new file mode 100644 index 00000000000..3463189d55b --- /dev/null +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirNativeSyntheticNamesProvider.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.test.frontend.fir + +import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticNamesProvider +import org.jetbrains.kotlin.load.java.setMethodName +import org.jetbrains.kotlin.name.Name + +object FirNativeSyntheticNamesProvider : FirSyntheticNamesProvider() { + override fun possibleGetterNamesByPropertyName(name: Name): List = emptyList() + override fun setterNameByGetterName(name: Name): Name = setMethodName(getMethodName = name) + override fun possiblePropertyNamesByAccessorName(name: Name): List = emptyList() +} \ No newline at end of file diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/NativeCallConflictResolverFactory.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/NativeCallConflictResolverFactory.kt new file mode 100644 index 00000000000..2a52ad280d4 --- /dev/null +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/NativeCallConflictResolverFactory.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.test.frontend.fir + +import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents +import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory +import org.jetbrains.kotlin.fir.resolve.calls.ConeCompositeConflictResolver +import org.jetbrains.kotlin.fir.resolve.calls.ConeIntegerOperatorConflictResolver +import org.jetbrains.kotlin.fir.resolve.calls.ConeOverloadConflictResolver +import org.jetbrains.kotlin.fir.resolve.calls.jvm.ConeEquivalentCallConflictResolver +import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents +import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator + +object NativeCallConflictResolverFactory : ConeCallConflictResolverFactory() { + override fun create( + typeSpecificityComparator: TypeSpecificityComparator, + components: InferenceComponents, + transformerComponents: BodyResolveComponents + ): ConeCompositeConflictResolver { + val specificityComparator = TypeSpecificityComparator.NONE + return ConeCompositeConflictResolver( + ConeOverloadConflictResolver(specificityComparator, components, transformerComponents), + ConeEquivalentCallConflictResolver(specificityComparator, components, transformerComponents), + ConeIntegerOperatorConflictResolver(specificityComparator, components, transformerComponents) + ) + } +} diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/runners/AbstractDiagnosticsNativeTest.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/runners/AbstractDiagnosticsNativeTest.kt index 0b86c5b92e1..87fa649d23d 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/runners/AbstractDiagnosticsNativeTest.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/runners/AbstractDiagnosticsNativeTest.kt @@ -6,24 +6,34 @@ package org.jetbrains.kotlin.test.runners import org.jetbrains.kotlin.platform.konan.NativePlatforms +import org.jetbrains.kotlin.test.Constructor import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder import org.jetbrains.kotlin.test.builders.classicFrontendHandlersStep -import org.jetbrains.kotlin.test.builders.classicFrontendStep +import org.jetbrains.kotlin.test.builders.firHandlersStep +import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives +import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade +import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler import org.jetbrains.kotlin.test.frontend.classic.handlers.DeclarationsDumpHandler import org.jetbrains.kotlin.test.frontend.classic.handlers.OldNewInferenceMetaInfoProcessor -import org.jetbrains.kotlin.test.model.DependencyKind -import org.jetbrains.kotlin.test.model.FrontendKinds +import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade +import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact +import org.jetbrains.kotlin.test.model.* import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider +import org.jetbrains.kotlin.test.frontend.fir.handlers.* + +abstract class AbstractDiagnosticsNativeTestBase> : AbstractKotlinCompilerTest() { + abstract val targetFrontend: FrontendKind + abstract val frontend: Constructor> + abstract fun handlersSetup(builder: TestConfigurationBuilder) -abstract class AbstractDiagnosticsNativeTest : AbstractKotlinCompilerTest() { override fun TestConfigurationBuilder.configuration() { globalDefaults { - frontend = FrontendKinds.ClassicFrontend + frontend = targetFrontend targetPlatform = NativePlatforms.unspecifiedNativePlatform dependencyKind = DependencyKind.Source } @@ -42,8 +52,27 @@ abstract class AbstractDiagnosticsNativeTest : AbstractKotlinCompilerTest() { ::CoroutineHelpersSourceFilesProvider, ) - classicFrontendStep() - classicFrontendHandlersStep { + facadeStep(frontend) + + handlersSetup(this) + + forTestsMatching("testData/diagnostics/nativeTests/*") { + defaultDirectives { + +LanguageSettingsDirectives.ALLOW_KOTLIN_PACKAGE + } + } + } +} + +abstract class AbstractDiagnosticsNativeTest : AbstractDiagnosticsNativeTestBase() { + override val targetFrontend: FrontendKind + get() = FrontendKinds.ClassicFrontend + + override val frontend: Constructor> + get() = ::ClassicFrontendFacade + + override fun handlersSetup(builder: TestConfigurationBuilder) { + builder.classicFrontendHandlersStep { useHandlers( ::DeclarationsDumpHandler, ::ClassicDiagnosticsHandler, @@ -51,3 +80,44 @@ abstract class AbstractDiagnosticsNativeTest : AbstractKotlinCompilerTest() { } } } + +abstract class AbstractFirNativeDiagnosticsTest : AbstractDiagnosticsNativeTestBase() { + override val targetFrontend: FrontendKind + get() = FrontendKinds.FIR + + override val frontend: Constructor> + get() = ::FirFrontendFacade + + override fun handlersSetup(builder: TestConfigurationBuilder) { + builder.firHandlersStep { + useHandlers( + ::FirDiagnosticsHandler, + ::FirDumpHandler, + ::FirCfgDumpHandler, + ::FirCfgConsistencyHandler, + ::FirNoImplicitTypesHandler, + ::FirScopeDumpHandler, + ) + } + } + + override fun configure(builder: TestConfigurationBuilder) { + super.configure(builder) + + builder.forTestsMatching("compiler/testData/diagnostics/*") { + configurationForClassicAndFirTestsAlongside() + } + } +} + +abstract class AbstractFirNativeDiagnosticsWithLightTreeTest : AbstractFirNativeDiagnosticsTest() { + override fun configure(builder: TestConfigurationBuilder) { + super.configure(builder) + with(builder) { + defaultDirectives { + +FirDiagnosticsDirectives.USE_LIGHT_TREE + } + } + } +} + diff --git a/compiler/tests-for-compiler-generator/tests/org/jetbrains/kotlin/test/generators/GenerateJUnit5CompilerTests.kt b/compiler/tests-for-compiler-generator/tests/org/jetbrains/kotlin/test/generators/GenerateJUnit5CompilerTests.kt index 2bc4f8990a3..ac27569f8b4 100644 --- a/compiler/tests-for-compiler-generator/tests/org/jetbrains/kotlin/test/generators/GenerateJUnit5CompilerTests.kt +++ b/compiler/tests-for-compiler-generator/tests/org/jetbrains/kotlin/test/generators/GenerateJUnit5CompilerTests.kt @@ -46,7 +46,7 @@ fun generateJUnit5CompilerTests(args: Array) { } testClass { - model("diagnostics/nativeTests") + model("diagnostics/nativeTests", excludedPattern = excludedFirTestdataPattern) } testClass { @@ -217,6 +217,18 @@ fun generateJUnit5CompilerTests(args: Array) { model("diagnostics/foreignAnnotationsTests/java8Tests", excludedPattern = excludedFirTestdataPattern) model("diagnostics/foreignAnnotationsTests/java11Tests", excludedPattern = excludedFirTestdataPattern) } + + testClass( + suiteTestClassName = "FirOldFrontendNativeDiagnosticsTestGenerated" + ) { + model("diagnostics/nativeTests", excludedPattern = excludedFirTestdataPattern) + } + + testClass( + suiteTestClassName = "FirOldFrontendNativeDiagnosticsWithLightTreeTestGenerated" + ) { + model("diagnostics/nativeTests", excludedPattern = excludedFirTestdataPattern) + } } testGroup(testsRoot = "compiler/fir/fir2ir/tests-gen", testDataRoot = "compiler/testData") { diff --git a/settings.gradle b/settings.gradle index 5a884b3e140..7e2c7e5bcae 100644 --- a/settings.gradle +++ b/settings.gradle @@ -16,7 +16,7 @@ pluginManagement { maven { url "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-dependencies" } } } - + plugins { id "de.undercouch.download" version "5.1.0" } @@ -342,6 +342,7 @@ include ":compiler:fir", ":compiler:fir:checkers", ":compiler:fir:checkers:checkers.jvm", ":compiler:fir:checkers:checkers.js", + ":compiler:fir:checkers:checkers.native", ":compiler:fir:checkers:checkers-component-generator", ":compiler:fir:entrypoint", ":compiler:fir:analysis-tests",