Support basic light-classes basic with FIR for CLI
This commit is contained in:
@@ -0,0 +1,282 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.java
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.util.Pair
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import com.intellij.psi.impl.cache.ModifierFlags
|
||||||
|
import com.intellij.psi.impl.compiled.ClsClassImpl
|
||||||
|
import com.intellij.psi.impl.compiled.ClsFileImpl
|
||||||
|
import com.intellij.psi.impl.file.PsiPackageImpl
|
||||||
|
import com.intellij.psi.impl.java.stubs.*
|
||||||
|
import com.intellij.psi.impl.java.stubs.impl.*
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.psi.stubs.StubElement
|
||||||
|
import com.intellij.util.ArrayUtil
|
||||||
|
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.classId
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.superConeTypes
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.directExpansionType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.service
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.KotlinFinderMarker
|
||||||
|
|
||||||
|
class FirJavaElementFinder(
|
||||||
|
private val session: FirSession,
|
||||||
|
project: Project
|
||||||
|
) : PsiElementFinder(), KotlinFinderMarker {
|
||||||
|
private val psiManager = PsiManager.getInstance(project)
|
||||||
|
private val firProvider = session.service<FirProvider>()
|
||||||
|
|
||||||
|
override fun findPackage(qualifiedName: String): PsiPackage? {
|
||||||
|
if (firProvider.getClassNamesInPackage(FqName(qualifiedName)).isEmpty()) return null
|
||||||
|
return PsiPackageImpl(psiManager, qualifiedName)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getClasses(psiPackage: PsiPackage, scope: GlobalSearchScope): Array<PsiClass> {
|
||||||
|
return firProvider
|
||||||
|
.getClassNamesInPackage(FqName(psiPackage.qualifiedName))
|
||||||
|
.mapNotNull { findClass(psiPackage.qualifiedName + "." + it.identifier, scope) }
|
||||||
|
.toTypedArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun findClasses(qualifiedName: String, scope: GlobalSearchScope): Array<PsiClass> {
|
||||||
|
return findClass(qualifiedName, scope)?.let(::arrayOf) ?: emptyArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun findClass(qualifiedName: String, scope: GlobalSearchScope): PsiClass? {
|
||||||
|
val classId = ClassId.topLevel(FqName(qualifiedName))
|
||||||
|
|
||||||
|
val firClass =
|
||||||
|
firProvider.getFirClassifierByFqName(classId) as? FirRegularClass
|
||||||
|
?: return null
|
||||||
|
|
||||||
|
val ktFile = firClass.psi?.containingFile as KtFile
|
||||||
|
val fileStub = createJavaFileStub(classId.packageFqName, listOf(ktFile))
|
||||||
|
|
||||||
|
return buildStub(firClass, fileStub).psi
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildStub(firClass: FirRegularClass, parent: StubElement<*>): PsiClassStub<*> {
|
||||||
|
val classId = firClass.classId
|
||||||
|
val stub = PsiClassStubImpl<ClsClassImpl>(
|
||||||
|
JavaStubElementTypes.CLASS, parent, classId.asSingleFqName().asString(), firClass.name.identifier, null,
|
||||||
|
PsiClassStubImpl.packFlags(
|
||||||
|
false,
|
||||||
|
firClass.classKind == ClassKind.INTERFACE,
|
||||||
|
firClass.classKind == ClassKind.ENUM_CLASS, false, false,
|
||||||
|
firClass.classKind == ClassKind.ANNOTATION_CLASS, false, false,
|
||||||
|
false, false, false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
PsiModifierListStubImpl(stub, firClass.packFlags())
|
||||||
|
|
||||||
|
newTypeParameterList(
|
||||||
|
stub,
|
||||||
|
firClass.typeParameters.map { Pair(it.name.asString(), arrayOf(CommonClassNames.JAVA_LANG_OBJECT)) }
|
||||||
|
)
|
||||||
|
|
||||||
|
if (firClass.superTypeRefs.any { it !is FirResolvedTypeRef }) {
|
||||||
|
firClass.setCallbackOnSupertypesComputed {
|
||||||
|
stub.addSupertypesReferencesLists(firClass, session)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stub.addSupertypesReferencesLists(firClass, session)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (nestedClass in firClass.declarations.filterIsInstance<FirRegularClass>()) {
|
||||||
|
buildStub(nestedClass, stub)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stub
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirRegularClass.packFlags(): Int {
|
||||||
|
var flags = when (visibility) {
|
||||||
|
Visibilities.PRIVATE -> ModifierFlags.PRIVATE_MASK
|
||||||
|
Visibilities.PROTECTED -> ModifierFlags.PROTECTED_MASK
|
||||||
|
Visibilities.PUBLIC -> ModifierFlags.PUBLIC_MASK
|
||||||
|
else -> ModifierFlags.PACKAGE_LOCAL_MASK
|
||||||
|
}
|
||||||
|
|
||||||
|
flags = flags or when (modality) {
|
||||||
|
Modality.FINAL -> ModifierFlags.FINAL_MASK
|
||||||
|
Modality.ABSTRACT -> ModifierFlags.ABSTRACT_MASK
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classId.isNestedClass && !isInner) {
|
||||||
|
flags = flags or ModifierFlags.STATIC_MASK
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PsiClassStubImpl<*>.addSupertypesReferencesLists(firRegularClass: FirRegularClass, session: FirSession) {
|
||||||
|
require(firRegularClass.superTypeRefs.all { it is FirResolvedTypeRef }) {
|
||||||
|
"Supertypes for light class $qualifiedName are being added too early"
|
||||||
|
}
|
||||||
|
|
||||||
|
val isInterface = firRegularClass.classKind == ClassKind.INTERFACE
|
||||||
|
|
||||||
|
val interfaceNames = mutableListOf<String>()
|
||||||
|
var superName: String? = null
|
||||||
|
|
||||||
|
for (superConeType in firRegularClass.superConeTypes) {
|
||||||
|
val supertypeFirClass = superConeType.toFirClass(session) ?: continue
|
||||||
|
|
||||||
|
val canonicalString = superConeType.mapToCanonicalString(session)
|
||||||
|
|
||||||
|
if (isInterface || supertypeFirClass.classKind == ClassKind.INTERFACE) {
|
||||||
|
interfaceNames.add(canonicalString)
|
||||||
|
} else {
|
||||||
|
superName = canonicalString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isInterface) {
|
||||||
|
if (interfaceNames.isNotEmpty() && this.isAnnotationType) {
|
||||||
|
interfaceNames.remove(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION)
|
||||||
|
}
|
||||||
|
newReferenceList(JavaStubElementTypes.EXTENDS_LIST, this, ArrayUtil.toStringArray(interfaceNames))
|
||||||
|
newReferenceList(JavaStubElementTypes.IMPLEMENTS_LIST, this, ArrayUtil.EMPTY_STRING_ARRAY)
|
||||||
|
} else {
|
||||||
|
if (superName == null || "java/lang/Object" == superName || this.isEnum && "java/lang/Enum" == superName) {
|
||||||
|
newReferenceList(JavaStubElementTypes.EXTENDS_LIST, this, ArrayUtil.EMPTY_STRING_ARRAY)
|
||||||
|
} else {
|
||||||
|
newReferenceList(JavaStubElementTypes.EXTENDS_LIST, this, arrayOf(superName))
|
||||||
|
}
|
||||||
|
newReferenceList(JavaStubElementTypes.IMPLEMENTS_LIST, this, ArrayUtil.toStringArray(interfaceNames))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun newReferenceList(type: JavaClassReferenceListElementType, parent: StubElement<*>, types: Array<String>) {
|
||||||
|
PsiClassReferenceListStubImpl(type, parent, types)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun newTypeParameterList(parent: StubElement<*>, parameters: List<Pair<String, Array<String>>>) {
|
||||||
|
val listStub = PsiTypeParameterListStubImpl(parent)
|
||||||
|
for (parameter in parameters) {
|
||||||
|
val parameterStub = PsiTypeParameterStubImpl(listStub, parameter.first)
|
||||||
|
newReferenceList(JavaStubElementTypes.EXTENDS_BOUND_LIST, parameterStub, parameter.second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createJavaFileStub(packageFqName: FqName, files: Collection<KtFile>): PsiJavaFileStub {
|
||||||
|
val javaFileStub = PsiJavaFileStubImpl(packageFqName.asString(), /*compiled = */true)
|
||||||
|
javaFileStub.psiFactory = ClsStubPsiFactory.INSTANCE
|
||||||
|
|
||||||
|
val fakeFile = object : ClsFileImpl(files.first().viewProvider) {
|
||||||
|
override fun getStub() = javaFileStub
|
||||||
|
|
||||||
|
override fun getPackageName() = packageFqName.asString()
|
||||||
|
|
||||||
|
override fun isPhysical() = false
|
||||||
|
|
||||||
|
override fun getText(): String {
|
||||||
|
return files.singleOrNull()?.text ?: super.getText()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
javaFileStub.psi = fakeFile
|
||||||
|
return javaFileStub
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConeClassLikeType.toFirClass(session: FirSession): FirRegularClass? {
|
||||||
|
return when (this) {
|
||||||
|
is ConeAbbreviatedType -> this.directExpansionType(session)?.toFirClass(session)
|
||||||
|
else -> (this.lookupTag.toSymbol(session) as? FirClassSymbol)?.fir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// JVM TYPE MAPPING
|
||||||
|
// TODO: reuse other type mapping implementations when possible
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
private const val ERROR_TYPE_STUB = CommonClassNames.JAVA_LANG_OBJECT
|
||||||
|
|
||||||
|
private fun ConeKotlinType.mapToCanonicalString(session: FirSession): String {
|
||||||
|
return when (this) {
|
||||||
|
is ConeClassLikeType -> mapToCanonicalString(session)
|
||||||
|
is ConeTypeParameterType -> lookupTag.name.asString()
|
||||||
|
is ConeTypeVariableType, is ConeFlexibleType, is ConeCapturedType, is ConeDefinitelyNotNullType, is ConeIntersectionType ->
|
||||||
|
error("Unexpected type: $this [${this::class}]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConeClassLikeType.mapToCanonicalString(session: FirSession): String {
|
||||||
|
return when (this) {
|
||||||
|
is ConeAbbreviatedType -> this.directExpansionType(session)?.mapToCanonicalString(session) ?: ERROR_TYPE_STUB
|
||||||
|
is ConeClassType -> mapToCanonicalString(session)
|
||||||
|
is ConeClassErrorType -> ERROR_TYPE_STUB
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConeClassType.mapToCanonicalString(session: FirSession): String {
|
||||||
|
if (lookupTag.classId == StandardClassIds.Array) {
|
||||||
|
return when (val typeProjection = typeArguments[0]) {
|
||||||
|
is ConeStarProjection -> CommonClassNames.JAVA_LANG_OBJECT
|
||||||
|
is ConeTypedProjection -> {
|
||||||
|
if (typeProjection.kind == ProjectionKind.IN)
|
||||||
|
CommonClassNames.JAVA_LANG_VOID
|
||||||
|
else
|
||||||
|
(typeProjection.type as ConeClassLikeType).mapToCanonicalString(session)
|
||||||
|
}
|
||||||
|
else -> ERROR_TYPE_STUB
|
||||||
|
} + "[]"
|
||||||
|
}
|
||||||
|
|
||||||
|
val context = ConeTypeCheckerContext(false, session)
|
||||||
|
|
||||||
|
with(context) {
|
||||||
|
val typeConstructor = typeConstructor()
|
||||||
|
typeConstructor.getPrimitiveType()?.let { return JvmPrimitiveType.get(it).wrapperFqName.asString() }
|
||||||
|
typeConstructor.getPrimitiveArrayType()?.let { return JvmPrimitiveType.get(it).javaKeywordName + "[]" }
|
||||||
|
val kotlinClassFqName = typeConstructor.getClassFqNameUnsafe() ?: return ERROR_TYPE_STUB
|
||||||
|
val mapped = JavaToKotlinClassMap.mapKotlinToJava(kotlinClassFqName)?.asSingleFqName() ?: kotlinClassFqName
|
||||||
|
|
||||||
|
return mapped.toString() +
|
||||||
|
typeArguments.takeIf { it.isNotEmpty() }
|
||||||
|
?.joinToString(separator = ", ", prefix = "<", postfix = ">") { it.mapToCanonicalString(session) }
|
||||||
|
.orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConeKotlinTypeProjection.mapToCanonicalString(session: FirSession): String {
|
||||||
|
return when (this) {
|
||||||
|
is ConeStarProjection -> "?"
|
||||||
|
is ConeTypedProjection -> {
|
||||||
|
val wildcard = when (kind) {
|
||||||
|
ProjectionKind.STAR -> error("Should be handled in the case above")
|
||||||
|
ProjectionKind.IN -> "? super "
|
||||||
|
ProjectionKind.OUT -> "? extends "
|
||||||
|
ProjectionKind.INVARIANT -> ""
|
||||||
|
}
|
||||||
|
|
||||||
|
wildcard + type.mapToCanonicalString(session)
|
||||||
|
}
|
||||||
|
else -> ERROR_TYPE_STUB
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.java
|
package org.jetbrains.kotlin.fir.java
|
||||||
|
|
||||||
|
import com.intellij.openapi.extensions.Extensions
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.PsiElementFinder
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
@@ -52,6 +54,10 @@ class FirJavaModuleBasedSession(
|
|||||||
FirCorrespondingSupertypesCache::class,
|
FirCorrespondingSupertypesCache::class,
|
||||||
FirCorrespondingSupertypesCache(this)
|
FirCorrespondingSupertypesCache(this)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Extensions.getArea(sessionProvider.project)
|
||||||
|
.getExtensionPoint(PsiElementFinder.EP_NAME)
|
||||||
|
.registerExtension(FirJavaElementFinder(this, sessionProvider.project))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,4 +57,7 @@ class FirJavaClass internal constructor(
|
|||||||
superTypeRefs.addAll(newSupertypes)
|
superTypeRefs.addAll(newSupertypes)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setCallbackOnSupertypesComputed(callback: () -> Unit) =
|
||||||
|
error("Supertypes computation should happen just before the instance is published")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.fir.resolve
|
package org.jetbrains.kotlin.fir.resolve
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
|
||||||
import org.jetbrains.kotlin.fir.service
|
import org.jetbrains.kotlin.fir.service
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
|
||||||
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
abstract class FirProvider : FirSymbolProvider() {
|
abstract class FirProvider : FirSymbolProvider() {
|
||||||
abstract fun getFirClassifierByFqName(fqName: ClassId): FirMemberDeclaration?
|
abstract fun getFirClassifierByFqName(fqName: ClassId): FirClassLikeDeclaration<*>?
|
||||||
|
|
||||||
abstract override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>?
|
abstract override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>?
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
|||||||
import org.jetbrains.kotlin.fir.resolve.buildDefaultUseSiteScope
|
import org.jetbrains.kotlin.fir.resolve.buildDefaultUseSiteScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.*
|
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
@@ -46,6 +48,10 @@ class FirProviderImpl(val session: FirSession) : FirProvider() {
|
|||||||
return state.classifierContainerFileMap[fqName] ?: error("Couldn't find container for $fqName")
|
return state.classifierContainerFileMap[fqName] ?: error("Couldn't find container for $fqName")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getClassNamesInPackage(fqName: FqName): Set<Name> {
|
||||||
|
return state.classesInPackage[fqName] ?: emptySet()
|
||||||
|
}
|
||||||
|
|
||||||
fun recordFile(file: FirFile) {
|
fun recordFile(file: FirFile) {
|
||||||
recordFile(file, state)
|
recordFile(file, state)
|
||||||
}
|
}
|
||||||
@@ -64,6 +70,10 @@ class FirProviderImpl(val session: FirSession) : FirProvider() {
|
|||||||
state.classifierMap[classId] = regularClass
|
state.classifierMap[classId] = regularClass
|
||||||
state.classifierContainerFileMap[classId] = file
|
state.classifierContainerFileMap[classId] = file
|
||||||
|
|
||||||
|
if (!classId.isNestedClass && !classId.isLocal) {
|
||||||
|
state.classesInPackage.getOrPut(classId.packageFqName, ::mutableSetOf).add(classId.shortClassName)
|
||||||
|
}
|
||||||
|
|
||||||
regularClass.acceptChildren(this)
|
regularClass.acceptChildren(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,6 +112,7 @@ class FirProviderImpl(val session: FirSession) : FirProvider() {
|
|||||||
val fileMap = mutableMapOf<FqName, List<FirFile>>()
|
val fileMap = mutableMapOf<FqName, List<FirFile>>()
|
||||||
val classifierMap = mutableMapOf<ClassId, FirClassLikeDeclaration<*>>()
|
val classifierMap = mutableMapOf<ClassId, FirClassLikeDeclaration<*>>()
|
||||||
val classifierContainerFileMap = mutableMapOf<ClassId, FirFile>()
|
val classifierContainerFileMap = mutableMapOf<ClassId, FirFile>()
|
||||||
|
val classesInPackage = mutableMapOf<FqName, MutableSet<Name>>()
|
||||||
val callableMap = mutableMapOf<CallableId, List<FirCallableSymbol<*>>>()
|
val callableMap = mutableMapOf<CallableId, List<FirCallableSymbol<*>>>()
|
||||||
val callableContainerMap = mutableMapOf<ConeCallableSymbol, FirFile>()
|
val callableContainerMap = mutableMapOf<ConeCallableSymbol, FirFile>()
|
||||||
|
|
||||||
@@ -117,6 +128,7 @@ class FirProviderImpl(val session: FirSession) : FirProvider() {
|
|||||||
classifierContainerFileMap.putAll(other.classifierContainerFileMap)
|
classifierContainerFileMap.putAll(other.classifierContainerFileMap)
|
||||||
callableMap.putAll(other.callableMap)
|
callableMap.putAll(other.callableMap)
|
||||||
callableContainerMap.putAll(other.callableContainerMap)
|
callableContainerMap.putAll(other.callableContainerMap)
|
||||||
|
classesInPackage.putAll(other.classesInPackage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -25,6 +25,10 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
|||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirTopLevelDeclaredMemberScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirTopLevelDeclaredMemberScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||||
import org.jetbrains.kotlin.fir.symbols.*
|
import org.jetbrains.kotlin.fir.symbols.*
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.*
|
import org.jetbrains.kotlin.fir.types.impl.*
|
||||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||||
@@ -1028,4 +1032,4 @@ internal inline var FirExpression.resultType: FirTypeRef
|
|||||||
get() = typeRef
|
get() = typeRef
|
||||||
set(type) {
|
set(type) {
|
||||||
replaceTypeRef(type)
|
replaceTypeRef(type)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.types
|
package org.jetbrains.kotlin.fir.types
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||||
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
||||||
import org.jetbrains.kotlin.fir.declarations.superConeTypes
|
import org.jetbrains.kotlin.fir.declarations.superConeTypes
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
@@ -17,6 +19,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.ConeTypeVariableTypeConstructor
|
|||||||
import org.jetbrains.kotlin.fir.resolve.calls.hasNullableSuperType
|
import org.jetbrains.kotlin.fir.resolve.calls.hasNullableSuperType
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.firSafeNullable
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
||||||
import org.jetbrains.kotlin.fir.service
|
import org.jetbrains.kotlin.fir.service
|
||||||
import org.jetbrains.kotlin.fir.symbols.*
|
import org.jetbrains.kotlin.fir.symbols.*
|
||||||
@@ -26,13 +29,18 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
|||||||
import org.jetbrains.kotlin.fir.types.impl.ConeAbbreviatedTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeAbbreviatedTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
||||||
|
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||||
import org.jetbrains.kotlin.types.checker.convertVariance
|
import org.jetbrains.kotlin.types.checker.convertVariance
|
||||||
import org.jetbrains.kotlin.types.model.*
|
import org.jetbrains.kotlin.types.model.*
|
||||||
|
|
||||||
class ErrorTypeConstructor(val reason: String) : TypeConstructorMarker
|
class ErrorTypeConstructor(val reason: String) : TypeConstructorMarker
|
||||||
|
|
||||||
interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, TypeCheckerProviderContext {
|
interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, TypeCheckerProviderContext, TypeSystemCommonBackendContext {
|
||||||
val session: FirSession
|
val session: FirSession
|
||||||
|
|
||||||
override fun TypeConstructorMarker.isIntegerLiteralTypeConstructor(): Boolean {
|
override fun TypeConstructorMarker.isIntegerLiteralTypeConstructor(): Boolean {
|
||||||
@@ -431,6 +439,70 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun TypeConstructorMarker.toFirRegularClass(): FirRegularClass? {
|
||||||
|
if (this !is ConeClassLikeSymbol) return null
|
||||||
|
return this.firSafeNullable()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean {
|
||||||
|
val firRegularClass = toFirRegularClass() ?: return false
|
||||||
|
|
||||||
|
return firRegularClass.modality == Modality.FINAL ||
|
||||||
|
firRegularClass.classKind == ClassKind.ENUM_ENTRY ||
|
||||||
|
firRegularClass.classKind == ClassKind.ANNOTATION_CLASS
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.hasAnnotation(fqName: FqName): Boolean {
|
||||||
|
// TODO support annotations
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.getAnnotationFirstArgumentValue(fqName: FqName): Any? {
|
||||||
|
// TODO support annotations
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker? {
|
||||||
|
return this as? FirTypeParameterSymbol
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun TypeConstructorMarker.isInlineClass(): Boolean {
|
||||||
|
return toFirRegularClass()?.isInline == true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker {
|
||||||
|
require(this is ConeTypeParameterSymbol)
|
||||||
|
return this.firSafeNullable<FirTypeParameter>()?.bounds?.getOrNull(0)?.let { (it as? FirResolvedTypeRef)?.type }
|
||||||
|
?: ConeClassTypeImpl(
|
||||||
|
ConeClassLikeLookupTagImpl(ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.any.toSafe())), emptyArray(), true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.getSubstitutedUnderlyingType(): KotlinTypeMarker? {
|
||||||
|
// TODO: support inline classes
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun TypeConstructorMarker.getPrimitiveType() =
|
||||||
|
getClassFqNameUnsafe()?.let(KotlinBuiltIns.FQ_NAMES.fqNameToPrimitiveType::get)
|
||||||
|
|
||||||
|
override fun TypeConstructorMarker.getPrimitiveArrayType() =
|
||||||
|
getClassFqNameUnsafe()?.let(KotlinBuiltIns.FQ_NAMES.arrayClassFqNameToPrimitiveType::get)
|
||||||
|
|
||||||
|
override fun TypeConstructorMarker.isUnderKotlinPackage() =
|
||||||
|
getClassFqNameUnsafe()?.startsWith(Name.identifier("kotlin")) == true
|
||||||
|
|
||||||
|
override fun TypeConstructorMarker.getClassFqNameUnsafe(): FqNameUnsafe? {
|
||||||
|
return toFirRegularClass()?.symbol?.toLookupTag()?.classId?.asSingleFqName()?.toUnsafe()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun TypeParameterMarker.getName() = (this as ConeTypeParameterSymbol).name
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean {
|
||||||
|
val classKind = typeConstructor().toFirRegularClass()?.classKind ?: return false
|
||||||
|
return classKind == ClassKind.ANNOTATION_CLASS || classKind == ClassKind.INTERFACE
|
||||||
|
}
|
||||||
|
|
||||||
override fun TypeConstructorMarker.isError(): Boolean {
|
override fun TypeConstructorMarker.isError(): Boolean {
|
||||||
return this is ErrorTypeConstructor
|
return this is ErrorTypeConstructor
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// FILE: K1.kt
|
||||||
|
class K2: J1() {
|
||||||
|
fun bar() {
|
||||||
|
foo()
|
||||||
|
baz()
|
||||||
|
|
||||||
|
superClass()
|
||||||
|
superI()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: J1.java
|
||||||
|
public class J1 extends KFirst {
|
||||||
|
void baz() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: K2.kt
|
||||||
|
open class KFirst : SuperClass(), SuperI {
|
||||||
|
fun foo() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: K3.kt
|
||||||
|
abstract class SuperClass {
|
||||||
|
fun superClass() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SuperI {
|
||||||
|
fun superI() {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
FILE: K1.kt
|
||||||
|
public final class K2 : R|J1| {
|
||||||
|
public constructor(): R|K2| {
|
||||||
|
super<R|J1|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun bar(): R|kotlin/Unit| {
|
||||||
|
this@R|/KFirst|.R|/KFirst.foo|()
|
||||||
|
this@R|/J1|.R|/J1.baz|()
|
||||||
|
this@R|/SuperClass|.R|/SuperClass.superClass|()
|
||||||
|
this@R|/SuperI|.R|/SuperI.superI|()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
FILE: K2.kt
|
||||||
|
public open class KFirst : R|SuperClass|, R|SuperI| {
|
||||||
|
public constructor(): R|KFirst| {
|
||||||
|
super<R|SuperClass|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun foo(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
FILE: K3.kt
|
||||||
|
public abstract class SuperClass : R|kotlin/Any| {
|
||||||
|
public constructor(): R|SuperClass| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun superClass(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public abstract interface SuperI : R|kotlin/Any| {
|
||||||
|
public open fun superI(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
// FILE: K1.kt
|
||||||
|
class KSub : J1()
|
||||||
|
|
||||||
|
fun main(k: KSub, vString: SuperClass<String>.NestedInSuperClass, vInt: SuperClass<Int>.NestedInSuperClass) {
|
||||||
|
k.getImpl().nestedI(vString)
|
||||||
|
|
||||||
|
// TODO: Support parametrisized inner classes
|
||||||
|
k.getImpl().nestedI(vInt)
|
||||||
|
k.getNestedSubClass().nested("")
|
||||||
|
k.getNestedSubClass().nested(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: J1.java
|
||||||
|
public class J1 extends KFirst {
|
||||||
|
|
||||||
|
public class NestedSubClass extends NestedInSuperClass {}
|
||||||
|
public abstract class NestedIImpl implements NestedInI<NestedInSuperClass> {}
|
||||||
|
|
||||||
|
public NestedIImpl getImpl() { return null; }
|
||||||
|
public NestedSubClass getNestedSubClass() { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: K2.kt
|
||||||
|
open class KFirst : SuperClass<String>(), SuperI<Int>
|
||||||
|
|
||||||
|
// FILE: K3.kt
|
||||||
|
abstract class SuperClass<T> {
|
||||||
|
inner open class NestedInSuperClass {
|
||||||
|
fun nested(x: T) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SuperI<E> {
|
||||||
|
interface NestedInI<F> {
|
||||||
|
fun nestedI(f: F) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
FILE: K1.kt
|
||||||
|
public final class KSub : R|J1| {
|
||||||
|
public constructor(): R|KSub| {
|
||||||
|
super<R|J1|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final fun main(k: R|KSub|, vString: R|SuperClass.NestedInSuperClass<kotlin/String>|, vInt: R|SuperClass.NestedInSuperClass<kotlin/Int>|): R|kotlin/Unit| {
|
||||||
|
R|<local>/k|.R|/J1.getImpl|().R|FakeOverride</SuperI.NestedInI.nestedI: R|kotlin/Unit|>|(R|<local>/vString|)
|
||||||
|
R|<local>/k|.R|/J1.getImpl|().R|FakeOverride</SuperI.NestedInI.nestedI: R|kotlin/Unit|>|(R|<local>/vInt|)
|
||||||
|
R|<local>/k|.R|/J1.getNestedSubClass|().<Inapplicable(INAPPLICABLE): [/SuperClass.NestedInSuperClass.nested]>#(String())
|
||||||
|
R|<local>/k|.R|/J1.getNestedSubClass|().<Inapplicable(INAPPLICABLE): [/SuperClass.NestedInSuperClass.nested]>#(Int(1))
|
||||||
|
}
|
||||||
|
FILE: K2.kt
|
||||||
|
public open class KFirst : R|SuperClass<kotlin/String>|, R|SuperI<kotlin/Int>| {
|
||||||
|
public constructor(): R|KFirst| {
|
||||||
|
super<R|SuperClass<kotlin/String>|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
FILE: K3.kt
|
||||||
|
public abstract class SuperClass<T> : R|kotlin/Any| {
|
||||||
|
public constructor<T>(): R|SuperClass<T>| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public open inner class NestedInSuperClass : R|kotlin/Any| {
|
||||||
|
public constructor(): R|SuperClass.NestedInSuperClass| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun nested(x: R|T|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public abstract interface SuperI<E> : R|kotlin/Any| {
|
||||||
|
public abstract interface NestedInI<F> : R|kotlin/Any| {
|
||||||
|
public open fun nestedI(f: R|F|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// FILE: K1.kt
|
||||||
|
open class KFirst() {
|
||||||
|
fun foo() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: J1.java
|
||||||
|
public class J1 extends KFirst {
|
||||||
|
void baz() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: K2.kt
|
||||||
|
class K2: J1() {
|
||||||
|
fun bar() {
|
||||||
|
foo()
|
||||||
|
baz()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
FILE: K1.kt
|
||||||
|
public open class KFirst : R|kotlin/Any| {
|
||||||
|
public constructor(): R|KFirst| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun foo(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
FILE: K2.kt
|
||||||
|
public final class K2 : R|J1| {
|
||||||
|
public constructor(): R|K2| {
|
||||||
|
super<R|J1|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun bar(): R|kotlin/Unit| {
|
||||||
|
this@R|/KFirst|.R|/KFirst.foo|()
|
||||||
|
this@R|/J1|.R|/J1.baz|()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// FILE: K1.kt
|
||||||
|
open class KFirst<T: java.io.Serializable>() {
|
||||||
|
fun foo(t: T): T = t
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: J1.java
|
||||||
|
public class J1 extends KFirst<Integer> {
|
||||||
|
void baz() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: K2.kt
|
||||||
|
class K2: J1() {
|
||||||
|
fun bar() {
|
||||||
|
foo(1)
|
||||||
|
baz()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
FILE: K1.kt
|
||||||
|
public open class KFirst<T : R|java/io/Serializable|> : R|kotlin/Any| {
|
||||||
|
public constructor<T : R|java/io/Serializable|>(): R|KFirst<T>| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun foo(t: R|T|): R|T| {
|
||||||
|
^foo R|<local>/t|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
FILE: K2.kt
|
||||||
|
public final class K2 : R|J1| {
|
||||||
|
public constructor(): R|K2| {
|
||||||
|
super<R|J1|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun bar(): R|kotlin/Unit| {
|
||||||
|
this@R|/KFirst|.R|FakeOverride</KFirst.foo: R|kotlin/Int|>|(Int(1))
|
||||||
|
this@R|/J1|.R|/J1.baz|()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// FILE: K1.kt
|
||||||
|
class KotlinClass
|
||||||
|
|
||||||
|
// FILE: JavaClass.java
|
||||||
|
public class JavaClass {
|
||||||
|
public static void baz(KotlinClass k) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: K2.kt
|
||||||
|
fun main() {
|
||||||
|
JavaClass.baz(KotlinClass())
|
||||||
|
JavaClass.baz("")
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
FILE: K1.kt
|
||||||
|
public final class KotlinClass : R|kotlin/Any| {
|
||||||
|
public constructor(): R|KotlinClass| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
FILE: K2.kt
|
||||||
|
public final fun main(): R|kotlin/Unit| {
|
||||||
|
Q|JavaClass|.R|/JavaClass.baz|(R|/KotlinClass.KotlinClass|())
|
||||||
|
Q|JavaClass|.<Inapplicable(INAPPLICABLE): [/JavaClass.baz]>#(String())
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// FILE: K1.kt
|
||||||
|
class KotlinClass<T>
|
||||||
|
|
||||||
|
// FILE: JavaClass.java
|
||||||
|
public class JavaClass {
|
||||||
|
public static void baz(KotlinClass<Integer> k) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: K2.kt
|
||||||
|
fun main() {
|
||||||
|
JavaClass.baz(KotlinClass())
|
||||||
|
JavaClass.baz(KotlinClass<Int>())
|
||||||
|
JavaClass.baz(KotlinClass<String>())
|
||||||
|
JavaClass.baz("")
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
FILE: K1.kt
|
||||||
|
public final class KotlinClass<T> : R|kotlin/Any| {
|
||||||
|
public constructor<T>(): R|KotlinClass<T>| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
FILE: K2.kt
|
||||||
|
public final fun main(): R|kotlin/Unit| {
|
||||||
|
Q|JavaClass|.R|/JavaClass.baz|(R|/KotlinClass.KotlinClass|<R|ft<kotlin/Int, kotlin/Int?>!|>())
|
||||||
|
Q|JavaClass|.R|/JavaClass.baz|(R|/KotlinClass.KotlinClass|<R|kotlin/Int|>())
|
||||||
|
Q|JavaClass|.<Inapplicable(INAPPLICABLE): [/JavaClass.baz]>#(R|/KotlinClass.KotlinClass|<R|kotlin/String|>())
|
||||||
|
Q|JavaClass|.<Inapplicable(INAPPLICABLE): [/JavaClass.baz]>#(String())
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// FILE: K1.kt
|
||||||
|
open class KotlinOuter {
|
||||||
|
inner open class KotlinInner {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: J1.java
|
||||||
|
public class J1 extends KotlinOuter {
|
||||||
|
public class J2 extends KotlinInner {
|
||||||
|
public void bazbaz() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void baz() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: K2.kt
|
||||||
|
class K2: J1() {
|
||||||
|
fun main() {
|
||||||
|
bar()
|
||||||
|
baz()
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class K3 : J2() {
|
||||||
|
fun main() {
|
||||||
|
foo()
|
||||||
|
bazbaz()
|
||||||
|
bar()
|
||||||
|
baz()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
FILE: K1.kt
|
||||||
|
public open class KotlinOuter : R|kotlin/Any| {
|
||||||
|
public constructor(): R|KotlinOuter| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public open inner class KotlinInner : R|kotlin/Any| {
|
||||||
|
public constructor(): R|KotlinOuter.KotlinInner| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun foo(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun bar(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
FILE: K2.kt
|
||||||
|
public final class K2 : R|J1| {
|
||||||
|
public constructor(): R|K2| {
|
||||||
|
super<R|J1|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun main(): R|kotlin/Unit| {
|
||||||
|
this@R|/KotlinOuter|.R|/KotlinOuter.bar|()
|
||||||
|
this@R|/J1|.R|/J1.baz|()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final inner class K3 : R|J1.J2| {
|
||||||
|
public constructor(): R|K2.K3| {
|
||||||
|
super<R|J1.J2|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun main(): R|kotlin/Unit| {
|
||||||
|
this@R|/KotlinOuter.KotlinInner|.R|/KotlinOuter.KotlinInner.foo|()
|
||||||
|
this@R|/J1.J2|.R|/J1.J2.bazbaz|()
|
||||||
|
this@R|/KotlinOuter|.R|/KotlinOuter.bar|()
|
||||||
|
this@R|/J1|.R|/J1.baz|()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface A<T, V : CharSequence>
|
||||||
|
|
||||||
|
class B : A<Int, String>
|
||||||
|
|
||||||
|
// LIGHT_CLASS_FQ_NAME: A, B
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
public interface A <T extends java.lang.Object, V extends java.lang.Object> extends java.lang.Object {
|
||||||
|
}
|
||||||
|
public final class B implements A<java.lang.Integer, java.lang.String> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
interface A<T>
|
||||||
|
|
||||||
|
class B<E> {
|
||||||
|
inner class C : A<E>
|
||||||
|
class D : A<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
// LIGHT_CLASS_FQ_NAME: B
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
public final class B <E extends java.lang.Object> extends java.lang.Object {
|
||||||
|
public final class C implements A<E> {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class D implements A<java.lang.String> {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// FILE: a.kt
|
||||||
|
package a
|
||||||
|
interface A
|
||||||
|
|
||||||
|
// FILE: b.kt
|
||||||
|
package b
|
||||||
|
interface B : a.A
|
||||||
|
|
||||||
|
class C : B
|
||||||
|
|
||||||
|
// LIGHT_CLASS_FQ_NAME: b.B, b.C
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
public interface B extends a.A {
|
||||||
|
}
|
||||||
|
public final class C implements b.B {
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
interface A<T>
|
||||||
|
interface Pair<T1, T2>
|
||||||
|
interface Triple<T1, T2, T3>
|
||||||
|
|
||||||
|
class B1 : A<String>
|
||||||
|
class B2 : A<Pair<in String, out String>>
|
||||||
|
class B3 : A<A<*>>
|
||||||
|
class B4 : A<A<String>>
|
||||||
|
class B5 : A<List<A<*>>>
|
||||||
|
class B6 : A<Int>
|
||||||
|
class B7 : A<IntArray>
|
||||||
|
class B8 : A<Array<String>>
|
||||||
|
class B9 : A<Array<Int>>
|
||||||
|
class B10 : A<Array<IntArray>>
|
||||||
|
|
||||||
|
// LIGHT_CLASS_FQ_NAME: B1, B2, B3, B4, B5, B6, B7, B8, B9, B10
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
public final class B1 implements A<java.lang.String> {
|
||||||
|
}
|
||||||
|
public final class B2 implements A<Pair<? super java.lang.String, ? extends java.lang.String>> {
|
||||||
|
}
|
||||||
|
public final class B3 implements A<A<?>> {
|
||||||
|
}
|
||||||
|
public final class B4 implements A<A<java.lang.String>> {
|
||||||
|
}
|
||||||
|
public final class B5 implements A<java.util.List<A<?>>> {
|
||||||
|
}
|
||||||
|
public final class B6 implements A<java.lang.Integer> {
|
||||||
|
}
|
||||||
|
public final class B7 implements A<int[]> {
|
||||||
|
}
|
||||||
|
public final class B8 implements A<java.lang.String[]> {
|
||||||
|
}
|
||||||
|
public final class B9 implements A<java.lang.Integer[]> {
|
||||||
|
}
|
||||||
|
public final class B10 implements A<int[][]> {
|
||||||
|
}
|
||||||
+10
-5
@@ -22,11 +22,8 @@ import org.jetbrains.kotlin.fir.resolve.FirProvider
|
|||||||
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.platform.js.JsPlatforms
|
|
||||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||||
import org.jetbrains.kotlin.platform.konan.KonanPlatforms
|
|
||||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -35,7 +32,7 @@ import java.util.*
|
|||||||
abstract class AbstractFirDiagnosticsSmokeTest : BaseDiagnosticsTest() {
|
abstract class AbstractFirDiagnosticsSmokeTest : BaseDiagnosticsTest() {
|
||||||
override fun analyzeAndCheck(testDataFile: File, files: List<TestFile>) {
|
override fun analyzeAndCheck(testDataFile: File, files: List<TestFile>) {
|
||||||
try {
|
try {
|
||||||
analyzeAndCheckUnhandled(files)
|
analyzeAndCheckUnhandled(testDataFile, files)
|
||||||
} catch (t: AssertionError) {
|
} catch (t: AssertionError) {
|
||||||
throw t
|
throw t
|
||||||
} catch (t: Throwable) {
|
} catch (t: Throwable) {
|
||||||
@@ -52,7 +49,7 @@ abstract class AbstractFirDiagnosticsSmokeTest : BaseDiagnosticsTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun analyzeAndCheckUnhandled(files: List<TestFile>) {
|
protected open fun analyzeAndCheckUnhandled(testDataFile: File, files: List<TestFile>) {
|
||||||
val groupedByModule = files.groupBy(TestFile::module)
|
val groupedByModule = files.groupBy(TestFile::module)
|
||||||
|
|
||||||
val modules = createModules(groupedByModule)
|
val modules = createModules(groupedByModule)
|
||||||
@@ -93,6 +90,14 @@ abstract class AbstractFirDiagnosticsSmokeTest : BaseDiagnosticsTest() {
|
|||||||
|
|
||||||
doFirResolveTestBench(firFiles, FirTotalResolveTransformer().transformers, gc = false)
|
doFirResolveTestBench(firFiles, FirTotalResolveTransformer().transformers, gc = false)
|
||||||
|
|
||||||
|
checkResultingFirFiles(firFiles, testDataFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun checkResultingFirFiles(
|
||||||
|
firFiles: MutableList<FirFile>,
|
||||||
|
testDataFile: File
|
||||||
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
abstract class AbstractFirDiagnosticsTest : AbstractFirDiagnosticsSmokeTest() {
|
||||||
|
|
||||||
|
override fun checkResultingFirFiles(
|
||||||
|
firFiles: MutableList<FirFile>,
|
||||||
|
testDataFile: File
|
||||||
|
) {
|
||||||
|
val firFileDump = StringBuilder().also { stringBuilder ->
|
||||||
|
firFiles.map {
|
||||||
|
it.accept(FirRenderer(stringBuilder), null)
|
||||||
|
}
|
||||||
|
}.toString()
|
||||||
|
val expectedPath = testDataFile.path.replace(".kt", ".txt")
|
||||||
|
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firFileDump)
|
||||||
|
}
|
||||||
|
}
|
||||||
+79
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath;
|
||||||
|
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||||
|
import org.jetbrains.kotlin.test.TargetBackend;
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("compiler/fir/resolve/testData/diagnostics")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInDiagnostics() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/diagnostics"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/fir/resolve/testData/diagnostics/j+k")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class J_k extends AbstractFirDiagnosticsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJ_k() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/diagnostics/j+k"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("KJKComplexHierarchy.kt")
|
||||||
|
public void testKJKComplexHierarchy() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/j+k/KJKComplexHierarchy.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("KJKComplexHierarchyWithNested.kt")
|
||||||
|
public void testKJKComplexHierarchyWithNested() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/j+k/KJKComplexHierarchyWithNested.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("KJKInheritance.kt")
|
||||||
|
public void testKJKInheritance() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/j+k/KJKInheritance.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("KJKInheritanceGeneric.kt")
|
||||||
|
public void testKJKInheritanceGeneric() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/j+k/KJKInheritanceGeneric.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("KotlinClassParameter.kt")
|
||||||
|
public void testKotlinClassParameter() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/j+k/KotlinClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("KotlinClassParameterGeneric.kt")
|
||||||
|
public void testKotlinClassParameterGeneric() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/j+k/KotlinClassParameterGeneric.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("outerInnerClasses.kt")
|
||||||
|
public void testOuterInnerClasses() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/j+k/outerInnerClasses.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.java
|
||||||
|
|
||||||
|
import com.intellij.openapi.extensions.Extensions
|
||||||
|
import com.intellij.psi.PsiElementFinder
|
||||||
|
import com.intellij.psi.impl.compiled.ClsClassImpl
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.fir.AbstractFirDiagnosticsSmokeTest
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
abstract class AbstractFirLightClassesTest : AbstractFirDiagnosticsSmokeTest() {
|
||||||
|
override fun checkResultingFirFiles(firFiles: MutableList<FirFile>, testDataFile: File) {
|
||||||
|
super.checkResultingFirFiles(firFiles, testDataFile)
|
||||||
|
|
||||||
|
val ourFinders =
|
||||||
|
Extensions.getArea(project).getExtensionPoint(PsiElementFinder.EP_NAME).extensions.filterIsInstance<FirJavaElementFinder>()
|
||||||
|
|
||||||
|
assertNotEmpty(ourFinders)
|
||||||
|
|
||||||
|
val stringBuilder = StringBuilder()
|
||||||
|
|
||||||
|
for (qualifiedName in InTextDirectivesUtils.findListWithPrefixes(testDataFile.readText(), "// LIGHT_CLASS_FQ_NAME: ")) {
|
||||||
|
val fqName = FqName(qualifiedName)
|
||||||
|
val packageName = fqName.parent().asString()
|
||||||
|
|
||||||
|
val ourFinder = ourFinders.firstOrNull { finder -> finder.findPackage(packageName) != null }
|
||||||
|
assertNotNull("PsiPackage for ${fqName.parent()} was not found", ourFinder)
|
||||||
|
ourFinder!!
|
||||||
|
|
||||||
|
val psiPackage = ourFinder.findPackage(fqName.parent().asString())
|
||||||
|
assertNotNull("PsiPackage for ${fqName.parent()} is null", psiPackage)
|
||||||
|
|
||||||
|
val psiClass = assertInstanceOf(
|
||||||
|
ourFinder.findClass(qualifiedName, GlobalSearchScope.allScope(project)),
|
||||||
|
ClsClassImpl::class.java
|
||||||
|
)
|
||||||
|
|
||||||
|
psiClass.appendMirrorText(0, stringBuilder)
|
||||||
|
stringBuilder.appendln()
|
||||||
|
}
|
||||||
|
|
||||||
|
val expectedPath = testDataFile.path.replace(".kt", ".txt")
|
||||||
|
KotlinTestUtils.assertEqualsToFile(File(expectedPath), stringBuilder.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+51
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.java;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath;
|
||||||
|
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||||
|
import org.jetbrains.kotlin.test.TargetBackend;
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("compiler/fir/resolve/testData/lightClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public class FirLightClassesTestGenerated extends AbstractFirLightClassesTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInLightClasses() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/lightClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericClasses.kt")
|
||||||
|
public void testGenericClasses() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/lightClasses/genericClasses.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nestedClasses.kt")
|
||||||
|
public void testNestedClasses() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/lightClasses/nestedClasses.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/lightClasses/simple.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeMapping.kt")
|
||||||
|
public void testTypeMapping() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/lightClasses/typeMapping.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,6 +36,8 @@ interface FirRegularClass : FirClass, @VisitedSupertype FirClassLikeDeclaration<
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun replaceSupertypes(newSupertypes: List<FirTypeRef>): FirRegularClass
|
fun replaceSupertypes(newSupertypes: List<FirTypeRef>): FirRegularClass
|
||||||
|
|
||||||
|
fun setCallbackOnSupertypesComputed(callback: () -> Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
val FirRegularClass.classId get() = symbol.classId
|
val FirRegularClass.classId get() = symbol.classId
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ open class FirClassImpl(
|
|||||||
override fun replaceSupertypes(newSupertypes: List<FirTypeRef>): FirRegularClass {
|
override fun replaceSupertypes(newSupertypes: List<FirTypeRef>): FirRegularClass {
|
||||||
superTypeRefs.clear()
|
superTypeRefs.clear()
|
||||||
superTypeRefs.addAll(newSupertypes)
|
superTypeRefs.addAll(newSupertypes)
|
||||||
|
callbackOnSupertypesComputed?.invoke()
|
||||||
|
callbackOnSupertypesComputed = null
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,4 +78,10 @@ open class FirClassImpl(
|
|||||||
companionObject = declarations.asSequence().filterIsInstance<FirRegularClass>().firstOrNull { it.isCompanion }
|
companionObject = declarations.asSequence().filterIsInstance<FirRegularClass>().firstOrNull { it.isCompanion }
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var callbackOnSupertypesComputed: (() -> Unit)? = null
|
||||||
|
|
||||||
|
override fun setCallbackOnSupertypesComputed(callback: () -> Unit) {
|
||||||
|
callbackOnSupertypesComputed = callback
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-1
@@ -54,9 +54,17 @@ class FirEnumEntryImpl(
|
|||||||
override fun replaceSupertypes(newSupertypes: List<FirTypeRef>): FirRegularClass {
|
override fun replaceSupertypes(newSupertypes: List<FirTypeRef>): FirRegularClass {
|
||||||
superTypeRefs.clear()
|
superTypeRefs.clear()
|
||||||
superTypeRefs.addAll(newSupertypes)
|
superTypeRefs.addAll(newSupertypes)
|
||||||
|
callbackOnSupertypesComputed?.invoke()
|
||||||
|
callbackOnSupertypesComputed = null
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var callbackOnSupertypesComputed: (() -> Unit)? = null
|
||||||
|
|
||||||
|
override fun setCallbackOnSupertypesComputed(callback: () -> Unit) {
|
||||||
|
callbackOnSupertypesComputed = callback
|
||||||
|
}
|
||||||
|
|
||||||
override fun replaceTypeRef(newTypeRef: FirTypeRef) {
|
override fun replaceTypeRef(newTypeRef: FirTypeRef) {
|
||||||
typeRef = newTypeRef
|
typeRef = newTypeRef
|
||||||
}
|
}
|
||||||
@@ -85,4 +93,4 @@ class FirEnumEntryImpl(
|
|||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.codegen.flags.AbstractWriteFlagsTest
|
|||||||
import org.jetbrains.kotlin.codegen.ir.*
|
import org.jetbrains.kotlin.codegen.ir.*
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
|
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
|
||||||
|
import org.jetbrains.kotlin.fir.java.AbstractFirLightClassesTest
|
||||||
import org.jetbrains.kotlin.fir.java.AbstractFirTypeEnhancementTest
|
import org.jetbrains.kotlin.fir.java.AbstractFirTypeEnhancementTest
|
||||||
import org.jetbrains.kotlin.fir.java.AbstractOwnFirTypeEnhancementTest
|
import org.jetbrains.kotlin.fir.java.AbstractOwnFirTypeEnhancementTest
|
||||||
import org.jetbrains.kotlin.generators.tests.generator.testGroup
|
import org.jetbrains.kotlin.generators.tests.generator.testGroup
|
||||||
@@ -487,6 +488,19 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testGroup("compiler/fir/resolve/tests", "compiler/fir/resolve/testData") {
|
||||||
|
|
||||||
|
testClass<AbstractFirDiagnosticsTest> {
|
||||||
|
model("diagnostics")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testGroup("compiler/fir/resolve/tests", "compiler/fir/resolve/testData") {
|
||||||
|
testClass<AbstractFirLightClassesTest> {
|
||||||
|
model("lightClasses")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
testGroup("compiler/fir/fir2ir/tests", "compiler/testData") {
|
testGroup("compiler/fir/fir2ir/tests", "compiler/testData") {
|
||||||
testClass<AbstractFir2IrTextTest> {
|
testClass<AbstractFir2IrTextTest> {
|
||||||
model("ir/irText")
|
model("ir/irText")
|
||||||
|
|||||||
Reference in New Issue
Block a user