From 151890dde5a80bbcceb5ffed71b3a063c636c089 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Thu, 23 Apr 2020 14:56:05 +0700 Subject: [PATCH] Add test for overloading expect MemberDescriptors discrimination Issue #KT-38298 --- .../kotlin/gradle/ImportAndCheckNavigation.kt | 115 ++++++++++++++++++ .../build.gradle.kts | 49 ++++++++ .../gradle.properties | 2 + .../settings.gradle.kts | 16 +++ .../src/linuxArm64Main/kotlin/arm64.kt | 13 ++ .../src/linuxMain/kotlin/common.kt | 13 ++ .../src/linuxX64Main/kotlin/x64.kt | 13 ++ 7 files changed, 221 insertions(+) create mode 100644 idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/ImportAndCheckNavigation.kt create mode 100644 idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/build.gradle.kts create mode 100644 idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/gradle.properties create mode 100644 idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/settings.gradle.kts create mode 100644 idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/src/linuxArm64Main/kotlin/arm64.kt create mode 100644 idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/src/linuxMain/kotlin/common.kt create mode 100644 idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/src/linuxX64Main/kotlin/x64.kt diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/ImportAndCheckNavigation.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/ImportAndCheckNavigation.kt new file mode 100644 index 00000000000..c9a0a15cf6f --- /dev/null +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/ImportAndCheckNavigation.kt @@ -0,0 +1,115 @@ +/* + * Copyright 2010-2020 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.gradle + +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.* +import com.intellij.psi.util.PsiTreeUtil +import com.intellij.testFramework.runInEdtAndGet +import org.jetbrains.kotlin.idea.codeInsight.gradle.MultiplePluginVersionGradleImportingTestCase +import org.jetbrains.kotlin.idea.core.util.toPsiFile +import org.jetbrains.kotlin.idea.util.application.runReadAction +import org.jetbrains.kotlin.psi.KtTreeVisitorVoid +import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.plugins.gradle.tooling.annotation.PluginTargetVersions +import org.junit.Test + +// TODO: run this test on the Gradle plugin from the current build +// 1. specify appropriate 'pluginVersion' in [PluginTargetVersions] +// 2. avoid using fixed Gradle plugin version in testdata +class ImportAndCheckNavigation : MultiplePluginVersionGradleImportingTestCase() { + + @Test + @PluginTargetVersions(gradleVersion = "5.0+", pluginVersion = "1.3.50+") + fun testNavigationToCommonizedLibrary() { + val files = configureAndImportProject() + + files.forEach { vFile -> + val referencesToTest = vFile.collectReferencesToTest() + referencesToTest.forEach { (psiReference, expectedElementText) -> + runReadAction { + val referencedElement = psiReference.resolve() + assertNotNull( + "PSI reference \"${psiReference.canonicalText}\" in ${vFile.relPath} can't be resolved", + referencedElement + ) + + val referencedElementText = referencedElement!!.text + assertTrue( + "Resolved reference \"${psiReference.canonicalText}\" from ${vFile.relPath} does not " + + "contain \"$expectedElementText\", instead it contains \"$referencedElementText\"", + expectedElementText in referencedElementText + ) + } + } + } + } + + override fun testDataDirName() = "importAndCheckNavigation" + + private fun configureAndImportProject(): List { + val files = configureByFiles() + importProject() + return files + } + + private fun VirtualFile.collectReferencesToTest(): Map { + if (extension != "kt") return emptyMap() + + val referencesToTest = mutableMapOf() + + runInEdtAndGet { + val psiFile = toPsiFile(project) + assertNotNull( + "Can't get PSI file for $relPath", + psiFile + ) + + psiFile!!.accept(object : KtTreeVisitorVoid() { + override fun visitComment(comment: PsiComment) { + val commentText = comment.text ?: return + + val unwrappedCommentText = if (commentText.startsWith("/*")) { + commentText.removePrefix("/*").removeSuffix("*/") + } else { + commentText.removePrefix("//") + }.trim(Char::isWhitespace) + + if (unwrappedCommentText.startsWith("NAVIGATION-TARGET:")) { + val expectedElementText = unwrappedCommentText.substringAfter("NAVIGATION-TARGET:").trimStart(Char::isWhitespace) + assertTrue( + "Empty expected element text in $relPath in comment \"$commentText\" at offset ${comment.startOffset}", + expectedElementText.isNotEmpty() + ) + + val nextElement = PsiTreeUtil.skipSiblingsForward( + comment, + PsiWhiteSpace::class.java, PsiComment::class.java + ) + assertNotNull( + "Next element not found in $relPath after comment \"$commentText\" at offset ${comment.startOffset}", + nextElement + ) + + val reference = nextElement!!.findReferenceAt(0) + assertNotNull( + "Can find PSI reference for \"${nextElement.text}\" in $relPath at offset ${nextElement.startOffset}", + reference + ) + + referencesToTest[reference!!] = expectedElementText + } + } + }) + + } + + return referencesToTest + } + + private val VirtualFile.relPath: String + get() = canonicalPath?.removePrefix(projectPath)?.trimStart('/', '\\') ?: name +} diff --git a/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/build.gradle.kts b/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/build.gradle.kts new file mode 100644 index 00000000000..491d55a8b5b --- /dev/null +++ b/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/build.gradle.kts @@ -0,0 +1,49 @@ +buildscript { + repositories { + maven("https://dl.bintray.com/kotlin/kotlin-dev") // TODO: use the Gradle plugin from the current build + mavenCentral() + } + + dependencies { + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.0-dev-7568") // TODO: use the Gradle plugin from the current build + } +} + +plugins { + kotlin("multiplatform") +} + +repositories { + maven("https://dl.bintray.com/kotlin/kotlin-dev") // TODO: use the Gradle plugin from the current build + mavenCentral() +} + +kotlin { + val commonMain by sourceSets.getting { + dependencies { + implementation(kotlin("stdlib-common")) + implementation(kotlin("stdlib")) + } + } + + val commonTest by sourceSets.getting { + dependencies { + implementation(kotlin("test-common")) + implementation(kotlin("test-annotations-common")) + } + } + + // there is no Linux HMPP shortcut preset, so need to configure targets and common source sets manually + val linuxMain by sourceSets.creating { dependsOn(commonMain) } + val linuxTest by sourceSets.creating { dependsOn(commonTest) } + + linuxX64 { + compilations["main"].defaultSourceSet.dependsOn(linuxMain) + compilations["test"].defaultSourceSet.dependsOn(linuxTest) + } + + linuxArm64 { + compilations["main"].defaultSourceSet.dependsOn(linuxMain) + compilations["test"].defaultSourceSet.dependsOn(linuxTest) + } +} diff --git a/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/gradle.properties b/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/gradle.properties new file mode 100644 index 00000000000..1d0d44f1d8e --- /dev/null +++ b/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/gradle.properties @@ -0,0 +1,2 @@ +kotlin.mpp.enableGranularSourceSetsMetadata=true +kotlin.native.enableDependencyPropagation=false diff --git a/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/settings.gradle.kts b/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/settings.gradle.kts new file mode 100644 index 00000000000..dd27e7f771f --- /dev/null +++ b/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/settings.gradle.kts @@ -0,0 +1,16 @@ +pluginManagement { + resolutionStrategy { + eachPlugin { + if (requested.id.name == "multiplatform") { + useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.0-dev-7568") // TODO: use the Gradle plugin from the current build + } + } + } + + repositories { + maven("https://dl.bintray.com/kotlin/kotlin-dev") // TODO: use the Gradle plugin from the current build + gradlePluginPortal() + } +} + +rootProject.name = "test" diff --git a/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/src/linuxArm64Main/kotlin/arm64.kt b/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/src/linuxArm64Main/kotlin/arm64.kt new file mode 100644 index 00000000000..e00f840e1dc --- /dev/null +++ b/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/src/linuxArm64Main/kotlin/arm64.kt @@ -0,0 +1,13 @@ +package arm64 + +import kotlinx.cinterop.CPointer +import platform.posix.FILE +import platform.posix.fopen +import platform.posix.fprintf +import platform.zlib.uInt + +fun test() { + val file: CPointer< /* NAVIGATION-TARGET:typealias FILE = */ FILE> = /* NAVIGATION-TARGET:external fun fopen */ fopen("file.txt", "r") ?: return + fun f1(): /* NAVIGATION-TARGET:typealias uInt = */ uInt = TODO() + /* NAVIGATION-TARGET:external fun fprintf */ fprintf(null, "") +} diff --git a/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/src/linuxMain/kotlin/common.kt b/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/src/linuxMain/kotlin/common.kt new file mode 100644 index 00000000000..f5bd6f5ec14 --- /dev/null +++ b/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/src/linuxMain/kotlin/common.kt @@ -0,0 +1,13 @@ +package common + +import kotlinx.cinterop.CPointer +import platform.posix.FILE +import platform.posix.fopen +import platform.posix.fprintf +import platform.zlib.uInt + +fun test() { + val file: CPointer< /* NAVIGATION-TARGET:expect class FILE */ FILE> = /* NAVIGATION-TARGET:external expect fun fopen */ fopen("file.txt", "r") ?: return + fun f1(): /* NAVIGATION-TARGET:expect class uInt */ uInt = TODO() + /* NAVIGATION-TARGET:external expect fun fprintf */ fprintf(null, "") +} diff --git a/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/src/linuxX64Main/kotlin/x64.kt b/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/src/linuxX64Main/kotlin/x64.kt new file mode 100644 index 00000000000..0211b9ee48c --- /dev/null +++ b/idea/testData/gradle/importAndCheckNavigation/navigationToCommonizedLibrary/src/linuxX64Main/kotlin/x64.kt @@ -0,0 +1,13 @@ +package x64 + +import kotlinx.cinterop.CPointer +import platform.posix.FILE +import platform.posix.fopen +import platform.posix.fprintf +import platform.zlib.uInt + +fun test() { + val file: CPointer< /* NAVIGATION-TARGET:typealias FILE = */ FILE> = /* NAVIGATION-TARGET:external fun fopen */ fopen("file.txt", "r") ?: return + fun f1(): /* NAVIGATION-TARGET:typealias uInt = */ uInt = TODO() + /* NAVIGATION-TARGET:external fun fprintf */ fprintf(null, "") +}