Analysis API: add KtType.isDenotable()
This commit is contained in:
+16
@@ -15,6 +15,9 @@ import org.jetbrains.kotlin.analysis.api.withValidityAssertion
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
||||
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
|
||||
import org.jetbrains.kotlin.load.java.sam.JavaSingleAbstractMethodUtils
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.types.DefinitelyNotNullType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
|
||||
internal class KtFe10TypeInfoProvider(
|
||||
@@ -37,4 +40,17 @@ internal class KtFe10TypeInfoProvider(
|
||||
require(type is KtFe10Type)
|
||||
return TypeUtils.isNullableType(type.type)
|
||||
}
|
||||
|
||||
override fun isDenotable(type: KtType): Boolean {
|
||||
require(type is KtFe10Type)
|
||||
val kotlinType = type.type
|
||||
return kotlinType.isDenotable()
|
||||
}
|
||||
|
||||
private fun KotlinType.isDenotable(): Boolean {
|
||||
if (this is DefinitelyNotNullType) return false
|
||||
return constructor.isDenotable &&
|
||||
constructor.declarationDescriptor?.name != SpecialNames.NO_NAME_PROVIDED &&
|
||||
arguments.all { it.type.isDenotable() }
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -27,6 +27,9 @@ import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.extension
|
||||
import kotlin.io.path.nameWithoutExtension
|
||||
|
||||
object KtFe10FrontendApiTestConfiguratorService : FrontendApiTestConfiguratorService {
|
||||
override val testPrefix: String
|
||||
@@ -64,4 +67,10 @@ object KtFe10FrontendApiTestConfiguratorService : FrontendApiTestConfiguratorSer
|
||||
override fun doOutOfBlockModification(file: KtFile) {
|
||||
// TODO not supported yet
|
||||
}
|
||||
|
||||
override fun preprocessTestDataPath(path: Path): Path {
|
||||
val newPath = path.resolveSibling(path.nameWithoutExtension + "." + testPrefix + "." + path.extension)
|
||||
if (newPath.toFile().exists()) return newPath
|
||||
return path
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* 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.analysis.api.descriptors.test.components.typeProvider
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.test.KtFe10FrontendApiTestConfiguratorService
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.components.typeInfoProvider.AbstractIsDenotableTest
|
||||
|
||||
abstract class AbstractKtFe10IsDenotableTest : AbstractIsDenotableTest(KtFe10FrontendApiTestConfiguratorService)
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.analysis.api.descriptors.test.components.typeProvider;
|
||||
|
||||
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("analysis/analysis-api/testData/components/typeInfoProvider/isDenotable")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class KtFe10IsDenotableTestGenerated extends AbstractKtFe10IsDenotableTest {
|
||||
@Test
|
||||
public void testAllFilesPresentInIsDenotable() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/typeInfoProvider/isDenotable"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile(".*\\.descriptors\\.kt$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localTypes.kt")
|
||||
public void testLocalTypes() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/typeInfoProvider/isDenotable/localTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simpleTypes.kt")
|
||||
public void testSimpleTypes() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/typeInfoProvider/isDenotable/simpleTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smartcast.kt")
|
||||
public void testSmartcast() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/typeInfoProvider/isDenotable/smartcast.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("typeParameter.kt")
|
||||
public void testTypeParameter() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/typeInfoProvider/isDenotable/typeParameter.kt");
|
||||
}
|
||||
}
|
||||
+13
-3
@@ -5,16 +5,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.fir.components
|
||||
|
||||
import org.jetbrains.kotlin.fir.resolve.FirSamResolverImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.types.canBeNull
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtTypeInfoProvider
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.fir.types.KtFirType
|
||||
import org.jetbrains.kotlin.analysis.api.fir.types.PublicTypeApproximator
|
||||
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
||||
import org.jetbrains.kotlin.fir.resolve.FirSamResolverImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.types.canBeNull
|
||||
import org.jetbrains.kotlin.fir.types.functionClassKind
|
||||
import org.jetbrains.kotlin.fir.types.typeApproximator
|
||||
|
||||
internal class KtFirTypeInfoProvider(
|
||||
override val analysisSession: KtFirAnalysisSession,
|
||||
@@ -33,4 +35,12 @@ internal class KtFirTypeInfoProvider(
|
||||
}
|
||||
|
||||
override fun canBeNull(type: KtType): Boolean = (type as KtFirType).coneType.canBeNull
|
||||
|
||||
override fun isDenotable(type: KtType): Boolean {
|
||||
val coneType = (type as KtFirType).coneType
|
||||
return analysisSession.rootModuleSession.typeApproximator.approximateToSuperType(
|
||||
coneType,
|
||||
PublicTypeApproximator.PublicApproximatorConfiguration(false)
|
||||
) == null
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ internal object PublicTypeApproximator {
|
||||
return approximator.approximateToSuperType(type, PublicApproximatorConfiguration(approximateLocalTypes))
|
||||
}
|
||||
|
||||
private class PublicApproximatorConfiguration(
|
||||
internal class PublicApproximatorConfiguration(
|
||||
override val localTypes: Boolean
|
||||
) : TypeApproximatorConfiguration.AllFlexibleSameValue() {
|
||||
override val allFlexible: Boolean get() = false
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* 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.analysis.api.fir.components.typeProvider
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.fir.FirFrontendApiTestConfiguratorService
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.components.typeInfoProvider.AbstractIsDenotableTest
|
||||
|
||||
abstract class AbstractFirIsDenotableTest : AbstractIsDenotableTest(FirFrontendApiTestConfiguratorService)
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.analysis.api.fir.components.typeProvider;
|
||||
|
||||
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("analysis/analysis-api/testData/components/typeInfoProvider/isDenotable")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class FirIsDenotableTestGenerated extends AbstractFirIsDenotableTest {
|
||||
@Test
|
||||
public void testAllFilesPresentInIsDenotable() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/typeInfoProvider/isDenotable"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile(".*\\.descriptors\\.kt$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localTypes.kt")
|
||||
public void testLocalTypes() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/typeInfoProvider/isDenotable/localTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simpleTypes.kt")
|
||||
public void testSimpleTypes() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/typeInfoProvider/isDenotable/simpleTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smartcast.kt")
|
||||
public void testSmartcast() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/typeInfoProvider/isDenotable/smartcast.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("typeParameter.kt")
|
||||
public void testTypeParameter() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/typeInfoProvider/isDenotable/typeParameter.kt");
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -55,6 +55,8 @@ interface FrontendApiTestConfiguratorService {
|
||||
fun prepareTestFiles(files: List<KtFile>, module: TestModule, testServices: TestServices) {}
|
||||
|
||||
fun doOutOfBlockModification(file: KtFile)
|
||||
|
||||
fun preprocessTestDataPath(path: Path) : Path = path
|
||||
}
|
||||
|
||||
abstract class AbstractFrontendApiTest(val configurator: FrontendApiTestConfiguratorService) : TestWithDisposable() {
|
||||
@@ -138,7 +140,7 @@ abstract class AbstractFrontendApiTest(val configurator: FrontendApiTestConfigur
|
||||
}
|
||||
|
||||
protected fun runTest(@TestDataFile path: String) {
|
||||
testDataPath = Paths.get(path)
|
||||
testDataPath = configurator.preprocessTestDataPath(Paths.get(path))
|
||||
val testConfiguration = testConfiguration(path, configure)
|
||||
Disposer.register(disposable, testConfiguration.rootDisposable)
|
||||
val testServices = testConfiguration.testServices
|
||||
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.analysis.api.impl.base.test.components.typeInfoProvider
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import org.jetbrains.kotlin.analysis.api.impl.barebone.parentOfType
|
||||
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.FrontendApiTestConfiguratorService
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.test.framework.AbstractHLApiSingleFileTest
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtAnnotatedExpression
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil.deparenthesize
|
||||
import org.jetbrains.kotlin.psi.KtQualifiedExpression
|
||||
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives
|
||||
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
|
||||
import org.jetbrains.kotlin.test.model.TestFile
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.AdditionalSourceProvider
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.assertions
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractIsDenotableTest(configurator: FrontendApiTestConfiguratorService) : AbstractHLApiSingleFileTest(configurator) {
|
||||
val denotableName = Name.identifier("Denotable")
|
||||
val undenotableName = Name.identifier("Nondenotable")
|
||||
override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) {
|
||||
val actualText = buildString {
|
||||
ktFile.accept(object : KtTreeVisitorVoid() {
|
||||
override fun visitElement(element: PsiElement) {
|
||||
if (element is LeafPsiElement) {
|
||||
append(element.text)
|
||||
}
|
||||
super.visitElement(element)
|
||||
}
|
||||
|
||||
|
||||
override fun visitAnnotatedExpression(expression: KtAnnotatedExpression) {
|
||||
val base = expression.baseExpression
|
||||
if (base == null || expression.annotationEntries.none {
|
||||
it.shortName == denotableName || it.shortName == undenotableName
|
||||
}) {
|
||||
super.visitAnnotatedExpression(expression)
|
||||
return
|
||||
}
|
||||
|
||||
analyseForTest(expression) {
|
||||
val parent = expression.parentOfType<KtQualifiedExpression>()
|
||||
// Try locating the containing PSI that is a receiver of a qualified expression because the smart cast information
|
||||
// is only available at that level for FE1.0. For example, consider
|
||||
// ```
|
||||
// if (a is String) {
|
||||
// (@Denotable("...") a).length
|
||||
// }
|
||||
// ```
|
||||
// smart cast is available for `(@Denotable("...") a)` and not for `a` or `@Denotable("...") a`.
|
||||
val ktType = if (parent != null && deparenthesize(parent.receiverExpression) == deparenthesize(base)) {
|
||||
parent.receiverExpression.getKtType()
|
||||
} else {
|
||||
expression.getKtType()
|
||||
}
|
||||
val actualHasDenotableType = ktType?.isDenotable ?: error("${base.text} does not have a type.")
|
||||
when (actualHasDenotableType) {
|
||||
true -> append("@Denotable")
|
||||
false -> append("@Nondenotable")
|
||||
}
|
||||
append("(\"${ktType.render()}\") ")
|
||||
append(base.text)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
testServices.assertions.assertEqualsToFile(testDataPath, actualText)
|
||||
}
|
||||
|
||||
override fun configureTest(builder: TestConfigurationBuilder) {
|
||||
super.configureTest(builder)
|
||||
builder.useAdditionalSourceProviders(AbstractIsDenotableTest::TestHelperProvider)
|
||||
builder.defaultDirectives {
|
||||
+ConfigurationDirectives.WITH_STDLIB
|
||||
}
|
||||
}
|
||||
|
||||
private class TestHelperProvider(testServices: TestServices) : AdditionalSourceProvider(testServices) {
|
||||
override fun produceAdditionalFiles(globalDirectives: RegisteredDirectives, module: TestModule): List<TestFile> {
|
||||
return listOf(File("analysis/analysis-api/testData/helpers/isDenotable/helpers.kt").toTestFile())
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -19,9 +19,17 @@ public abstract class KtTypeInfoProvider : KtAnalysisSessionComponent() {
|
||||
public abstract fun isFunctionalInterfaceType(type: KtType): Boolean
|
||||
public abstract fun getFunctionClassKind(type: KtType): FunctionClassKind?
|
||||
public abstract fun canBeNull(type: KtType): Boolean
|
||||
public abstract fun isDenotable(type: KtType): Boolean
|
||||
}
|
||||
|
||||
public interface KtTypeInfoProviderMixIn : KtAnalysisSessionMixIn {
|
||||
/**
|
||||
* Returns true if this type is denotable. A denotable type is a type that can be written in Kotlin by end users. See
|
||||
* https://kotlinlang.org/spec/type-system.html#type-kinds for more details.
|
||||
*/
|
||||
public val KtType.isDenotable: Boolean
|
||||
get() = analysisSession.typeInfoProvider.isDenotable(this)
|
||||
|
||||
/**
|
||||
* Returns true if this type is a functional interface type, a.k.a. SAM type, e.g., Runnable.
|
||||
*/
|
||||
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
fun test() {
|
||||
class A
|
||||
@Denotable("A") A()
|
||||
@Denotable("kotlin.collections.List<A>") listOf(A())
|
||||
@Nondenotable("<no name provided>") object {}
|
||||
@Nondenotable("kotlin.collections.List<<no name provided>>") listOf(object {})
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fun test() {
|
||||
class A
|
||||
@Denotable("A") A()
|
||||
@Denotable("kotlin.collections.List<A>") listOf(A())
|
||||
@Nondenotable("<anonymous>") object {}
|
||||
@Nondenotable("kotlin.collections.List<<anonymous>>") listOf(object {})
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
interface A
|
||||
fun test(a: A) {
|
||||
@Denotable("kotlin.Int") 1
|
||||
@Denotable("kotlin.String") ""
|
||||
Denotable("A") a
|
||||
}
|
||||
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
fun test(a: Any?) {
|
||||
if (a is String) {
|
||||
(@Denotable("kotlin.String") a).length
|
||||
if (a is Int) {
|
||||
(@Denotable("kotlin.Int") a).inc()
|
||||
}
|
||||
if (a is String) {
|
||||
(@Denotable("kotlin.String") a).length
|
||||
}
|
||||
}
|
||||
if (a != null) {
|
||||
(@Denotable("kotlin.Any") a).hashCode()
|
||||
}
|
||||
if (a == null) {
|
||||
(@Denotable("kotlin.Any?") a).isNothing()
|
||||
}
|
||||
if (a is String || a is Int) {
|
||||
(@Denotable("kotlin.Any?") a).length
|
||||
(@Denotable("kotlin.Any?") a).inc()
|
||||
}
|
||||
@Nondenotable("(kotlin.Comparable<*> & java.io.Serializable)") if (true) {
|
||||
""
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
fun Nothing?.isNothing() {}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
fun test(a: Any?) {
|
||||
if (a is String) {
|
||||
(@Denotable("kotlin.String") a).length
|
||||
if (a is Int) {
|
||||
(@Nondenotable("(kotlin.String&kotlin.Int)") a).inc()
|
||||
}
|
||||
if (a is String) {
|
||||
(@Denotable("kotlin.String") a).length
|
||||
}
|
||||
}
|
||||
if (a != null) {
|
||||
(@Denotable("kotlin.Any") a).hashCode()
|
||||
}
|
||||
if (a == null) {
|
||||
(@Denotable("kotlin.Nothing?") a).isNothing()
|
||||
}
|
||||
if (a is String || a is Int) {
|
||||
(@Nondenotable("(kotlin.Comparable<(kotlin.String&kotlin.Int)>&java.io.Serializable)") a).length
|
||||
(@Nondenotable("(kotlin.Comparable<(kotlin.String&kotlin.Int)>&java.io.Serializable)") a).inc()
|
||||
}
|
||||
@Nondenotable("(kotlin.Comparable<*>&java.io.Serializable)") if (true) {
|
||||
""
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
fun Nothing?.isNothing() {}
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
interface A
|
||||
|
||||
fun <T> test(t: T) {
|
||||
@Denotable("T") t
|
||||
if (t != null) {
|
||||
(@Nondenotable("T & Any") t).equals("")
|
||||
}
|
||||
val outs = take(getOutProjection())
|
||||
@Denotable("A") outs
|
||||
|
||||
val ins = take(getInProjection())
|
||||
@Denotable(kotlin.Any?) ins
|
||||
}
|
||||
|
||||
fun getOutProjection(): MutableList<out A> {
|
||||
TODO()
|
||||
}
|
||||
|
||||
fun getInProjection(): MutableList<in A> {
|
||||
TODO()
|
||||
}
|
||||
|
||||
fun <T> take(l: MutableList<T>): T {
|
||||
TODO()
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
interface A
|
||||
|
||||
fun <T> test(t: T) {
|
||||
@Denotable("T") t
|
||||
if (t != null) {
|
||||
(@Nondenotable("T!!") t).equals("")
|
||||
}
|
||||
val outs = take(getOutProjection())
|
||||
@Denotable("A") outs
|
||||
|
||||
val ins = take(getInProjection())
|
||||
@Denotable(kotlin.Any?) ins
|
||||
}
|
||||
|
||||
fun getOutProjection(): MutableList<out A> {
|
||||
TODO()
|
||||
}
|
||||
|
||||
fun getInProjection(): MutableList<in A> {
|
||||
TODO()
|
||||
}
|
||||
|
||||
fun <T> take(l: MutableList<T>): T {
|
||||
TODO()
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
@Target(AnnotationTarget.EXPRESSION)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class Denotable(val type: String)
|
||||
|
||||
@Target(AnnotationTarget.EXPRESSION)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class Nondenotable(val type: String)
|
||||
|
||||
+5
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.analysis.api.descriptors.test.components.symbolDecla
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.test.components.typeCreator.AbstractKtFe10TypeParameterTypeTest
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.test.components.typeProvider.AbstractKtFe10HasCommonSubtypeTest
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.test.scopes.AbstractKtFe10SubstitutionOverridesUnwrappingTest
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.test.components.typeProvider.AbstractKtFe10IsDenotableTest
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.test.symbols.AbstractKtFe10SymbolByFqNameTest
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.test.symbols.AbstractKtFe10SymbolByPsiTest
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.test.symbols.AbstractKtFe10SymbolByReferenceTest
|
||||
@@ -46,6 +47,7 @@ import org.jetbrains.kotlin.analysis.api.fir.components.typeCreator.AbstractFirT
|
||||
import org.jetbrains.kotlin.analysis.api.fir.components.typeInfoProvider.AbstractFirFunctionClassKindTest
|
||||
import org.jetbrains.kotlin.analysis.api.fir.components.typeProvider.AbstractFirGetSuperTypesTest
|
||||
import org.jetbrains.kotlin.analysis.api.fir.components.typeProvider.AbstractFirHasCommonSubtypeTest
|
||||
import org.jetbrains.kotlin.analysis.api.fir.components.typeProvider.AbstractFirIsDenotableTest
|
||||
import org.jetbrains.kotlin.analysis.api.fir.scopes.AbstractFirDelegateMemberScopeTest
|
||||
import org.jetbrains.kotlin.analysis.api.fir.scopes.AbstractFirFileScopeTest
|
||||
import org.jetbrains.kotlin.analysis.api.fir.scopes.AbstractFirMemberScopeByFqNameTest
|
||||
@@ -257,6 +259,9 @@ private fun TestGroupSuite.generateAnalysisApiComponentsTests() {
|
||||
test(fir = AbstractFirGetSuperTypesTest::class, fe10 = null) {
|
||||
model("superTypes")
|
||||
}
|
||||
test(fir = AbstractFirIsDenotableTest::class, fe10 = AbstractKtFe10IsDenotableTest::class) {
|
||||
model("isDenotable", excludedPattern = ".*\\.descriptors\\.kt$")
|
||||
}
|
||||
}
|
||||
|
||||
component("typeProvider") {
|
||||
|
||||
Reference in New Issue
Block a user