mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-10 15:51:01 +00:00
Compare commits
25 Commits
rr/pdn_byt
...
semoro-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
667dc57a9f | ||
|
|
d31d29bb61 | ||
|
|
80e0da1751 | ||
|
|
ccceacd8cc | ||
|
|
379f564a98 | ||
|
|
2a4dbb3a2a | ||
|
|
b81716a918 | ||
|
|
f53001a6e1 | ||
|
|
7372bb2e5f | ||
|
|
abadfc50bd | ||
|
|
b99de17e40 | ||
|
|
f1374612ed | ||
|
|
11df6091fa | ||
|
|
d11a4f96f2 | ||
|
|
0b5a5c6d62 | ||
|
|
45d3e6eb97 | ||
|
|
b16d53c855 | ||
|
|
605cd838d5 | ||
|
|
c2caccc175 | ||
|
|
6e63310b68 | ||
|
|
67f2259e1a | ||
|
|
f76356a4fe | ||
|
|
de08dfbc7f | ||
|
|
d5228afa94 | ||
|
|
75d315f5c9 |
@@ -23,11 +23,12 @@ import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.file.PsiPackageImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import gnu.trove.THashMap
|
||||
import gnu.trove.THashSet
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndex
|
||||
import org.jetbrains.kotlin.cli.jvm.index.SingleJavaFileRootsIndex
|
||||
import org.jetbrains.kotlin.fir.concurrent.ConcurrentHashMapNonRecursiveComputeCache
|
||||
import org.jetbrains.kotlin.fir.concurrent.NonRecursiveCooperativeComputeCache
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
||||
@@ -41,6 +42,7 @@ import org.jetbrains.kotlin.resolve.jvm.KotlinCliJavaFileManager
|
||||
import org.jetbrains.kotlin.util.PerformanceCounter
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.util.*
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
|
||||
// TODO: do not inherit from CoreJavaFileManager to avoid accidental usage of its methods which do not use caches/indices
|
||||
// Currently, the only relevant usage of this class as CoreJavaFileManager is at CoreJavaDirectoryService.getPackage,
|
||||
@@ -50,7 +52,7 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
||||
private lateinit var index: JvmDependenciesIndex
|
||||
private lateinit var singleJavaFileRootsIndex: SingleJavaFileRootsIndex
|
||||
private lateinit var packagePartProviders: List<JvmPackagePartProvider>
|
||||
private val topLevelClassesCache: MutableMap<FqName, VirtualFile?> = THashMap()
|
||||
private val topLevelClassesCache = ConcurrentHashMapNonRecursiveComputeCache<FqName, VirtualFile?>()
|
||||
private val allScope = GlobalSearchScope.allScope(myPsiManager.project)
|
||||
private var useFastClassFilesReading = false
|
||||
|
||||
@@ -72,25 +74,30 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
||||
|
||||
private fun findVirtualFileForTopLevelClass(classId: ClassId, searchScope: GlobalSearchScope): VirtualFile? {
|
||||
val relativeClassName = classId.relativeClassName.asString()
|
||||
return topLevelClassesCache.getOrPut(classId.packageFqName.child(classId.relativeClassName.pathSegments().first())) {
|
||||
return topLevelClassesCache.lookup(classId.packageFqName.child(classId.relativeClassName.pathSegments().first())) {
|
||||
index.findClass(classId) { dir, type ->
|
||||
findVirtualFileGivenPackage(dir, relativeClassName, type)
|
||||
} ?: singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
||||
}?.takeIf { it in searchScope }
|
||||
|
||||
}
|
||||
|
||||
private val binaryCache: MutableMap<ClassId, JavaClass?> = THashMap()
|
||||
private val binaryCache: NonRecursiveCooperativeComputeCache<ClassId, JavaClass?> =
|
||||
NonRecursiveCooperativeComputeCache()
|
||||
private val signatureParsingComponent = BinaryClassSignatureParser()
|
||||
|
||||
fun findClass(classId: ClassId, searchScope: GlobalSearchScope): JavaClass? = findClass(JavaClassFinder.Request(classId), searchScope)
|
||||
|
||||
private val findVirtualFileLock = ReentrantLock()
|
||||
private val binaryCacheLock = ReentrantLock()
|
||||
|
||||
override fun findClass(request: JavaClassFinder.Request, searchScope: GlobalSearchScope): JavaClass? {
|
||||
val (classId, classFileContentFromRequest, outerClassFromRequest) = request
|
||||
val virtualFile = findVirtualFileForTopLevelClass(classId, searchScope) ?: return null
|
||||
|
||||
if (useFastClassFilesReading && virtualFile.extension == "class") {
|
||||
// We return all class files' names in the directory in knownClassNamesInPackage method, so one may request an inner class
|
||||
return binaryCache.getOrPut(classId) {
|
||||
return binaryCache.lookup(classId) {
|
||||
// Note that currently we implicitly suppose that searchScope for binary classes is constant and we do not use it
|
||||
// as a key in cache
|
||||
// This is a true assumption by now since there are two search scopes in compiler: one for sources and another one for binary
|
||||
@@ -100,7 +107,7 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
||||
classId.outerClassId?.let { outerClassId ->
|
||||
val outerClass = outerClassFromRequest ?: findClass(outerClassId, searchScope)
|
||||
|
||||
return if (outerClass is BinaryJavaClass)
|
||||
return@lookup if (outerClass is BinaryJavaClass)
|
||||
outerClass.findInnerClass(classId.shortClassName, classFileContentFromRequest)
|
||||
else
|
||||
outerClass?.findInnerClass(classId.shortClassName)
|
||||
@@ -108,7 +115,7 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
||||
|
||||
// Here, we assume the class is top-level
|
||||
val classContent = classFileContentFromRequest ?: virtualFile.contentsToByteArray()
|
||||
if (virtualFile.nameWithoutExtension.contains("$") && isNotTopLevelClass(classContent)) return@getOrPut null
|
||||
if (virtualFile.nameWithoutExtension.contains("$") && isNotTopLevelClass(classContent)) return@lookup null
|
||||
|
||||
val resolver = ClassifierResolutionContext { findClass(it, allScope) }
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ import org.jetbrains.kotlin.fir.java.FirLibrarySession
|
||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirStagesTransformerFactory
|
||||
import org.jetbrains.kotlin.fir.service
|
||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||
@@ -327,7 +327,7 @@ object KotlinToJVMBytecodeCompiler {
|
||||
|
||||
}
|
||||
val builder = RawFirBuilder(session, stubMode = false)
|
||||
val resolveTransformer = FirTotalResolveTransformer()
|
||||
val resolveTransformer = FirStagesTransformerFactory(session)
|
||||
val firFiles = ktFiles.map {
|
||||
val firFile = builder.buildFirFile(it)
|
||||
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
|
||||
|
||||
@@ -25,11 +25,38 @@ import gnu.trove.THashMap
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.util.*
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.concurrent.withLock
|
||||
|
||||
class JvmDependenciesIndexImpl(_roots: List<JavaRoot>) : JvmDependenciesIndex {
|
||||
override val indexedRoots: Sequence<JavaRoot>
|
||||
get() = local.get().indexedRoots
|
||||
|
||||
override fun <T : Any> findClass(
|
||||
classId: ClassId,
|
||||
acceptedRootTypes: Set<JavaRoot.RootType>,
|
||||
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
|
||||
): T? = local.get().findClass(classId, acceptedRootTypes, findClassGivenDirectory)
|
||||
|
||||
override fun traverseDirectoriesInPackage(
|
||||
packageFqName: FqName,
|
||||
acceptedRootTypes: Set<JavaRoot.RootType>,
|
||||
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
|
||||
) = local.get().traverseDirectoriesInPackage(packageFqName, acceptedRootTypes, continueSearch)
|
||||
|
||||
val local = object : ThreadLocal<JvmDependenciesIndexImplU>() {
|
||||
override fun initialValue(): JvmDependenciesIndexImplU {
|
||||
return JvmDependenciesIndexImplU(_roots)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// speeds up finding files/classes in classpath/java source roots
|
||||
// NOT THREADSAFE, needs to be adapted/removed if we want compiler to be multithreaded
|
||||
// the main idea of this class is for each package to store roots which contains it to avoid excessive file system traversal
|
||||
class JvmDependenciesIndexImpl(_roots: List<JavaRoot>) : JvmDependenciesIndex {
|
||||
class JvmDependenciesIndexImplU(_roots: List<JavaRoot>) : JvmDependenciesIndex {
|
||||
//these fields are computed based on _roots passed to constructor which are filled in later
|
||||
private val roots: List<JavaRoot> by lazy { _roots.toList() }
|
||||
|
||||
@@ -76,6 +103,7 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>) : JvmDependenciesIndex {
|
||||
search(TraverseRequest(packageFqName, acceptedRootTypes)) { dir, rootType ->
|
||||
if (continueSearch(dir, rootType)) null else Unit
|
||||
}
|
||||
Unit
|
||||
}
|
||||
|
||||
// findClassGivenDirectory MUST check whether the class with this classId exists in given package
|
||||
@@ -121,7 +149,7 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>) : JvmDependenciesIndex {
|
||||
// NOTE: indices manipulation instead of using caches.reversed() is here for performance reasons
|
||||
for (cacheIndex in caches.lastIndex downTo 0) {
|
||||
val cacheRootIndices = caches[cacheIndex].rootIndices
|
||||
for (i in 0..cacheRootIndices.size() - 1) {
|
||||
for (i in 0 until cacheRootIndices.size()) {
|
||||
val rootIndex = cacheRootIndices[i]
|
||||
if (rootIndex <= processedRootsUpTo) continue // roots with those indices have been processed by now
|
||||
|
||||
@@ -215,6 +243,7 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>) : JvmDependenciesIndex {
|
||||
return childDirectory
|
||||
}
|
||||
|
||||
|
||||
private fun cachesPath(path: List<String>): List<Cache> {
|
||||
val caches = ArrayList<Cache>(path.size + 1)
|
||||
caches.add(rootCache)
|
||||
|
||||
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
|
||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirStagesTransformerFactory
|
||||
import org.jetbrains.kotlin.ir.AbstractIrTextTestCase
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import java.io.File
|
||||
@@ -78,7 +78,7 @@ abstract class AbstractFir2IrTextTest : AbstractIrTextTestCase() {
|
||||
|
||||
val builder = RawFirBuilder(session, stubMode = false)
|
||||
|
||||
val resolveTransformer = FirTotalResolveTransformer()
|
||||
val resolveTransformer = FirStagesTransformerFactory(session)
|
||||
val firFiles = psiFiles.map {
|
||||
val firFile = builder.buildFirFile(it)
|
||||
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.java
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiPackage
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
@@ -19,6 +20,8 @@ import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod
|
||||
import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope
|
||||
import org.jetbrains.kotlin.fir.java.scopes.JavaClassUseSiteScope
|
||||
import org.jetbrains.kotlin.fir.concurrent.ConcurrentHashMapNonRecursiveComputeCache
|
||||
import org.jetbrains.kotlin.fir.concurrent.TransactionalCache
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirSuperTypeScope
|
||||
@@ -38,6 +41,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||
import org.jetbrains.kotlin.types.Variance.INVARIANT
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
|
||||
class JavaSymbolProvider(
|
||||
val session: FirSession,
|
||||
@@ -50,7 +54,12 @@ class JavaSymbolProvider(
|
||||
private fun findClass(
|
||||
classId: ClassId,
|
||||
content: KotlinClassFinder.Result.ClassFileContent?
|
||||
): JavaClass? = facade.findClass(JavaClassFinder.Request(classId, previouslyFoundClassFileContent = content?.content), searchScope)
|
||||
): JavaClass? = //findClassLock.withLock {
|
||||
facade.findClass(
|
||||
JavaClassFinder.Request(classId, previouslyFoundClassFileContent = content?.content),
|
||||
searchScope
|
||||
)
|
||||
//}
|
||||
|
||||
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> =
|
||||
emptyList()
|
||||
@@ -75,7 +84,7 @@ class JavaSymbolProvider(
|
||||
scopeSession: ScopeSession
|
||||
): JavaClassEnhancementScope {
|
||||
return scopeSession.getOrBuild(symbol, JAVA_ENHANCEMENT) {
|
||||
JavaClassEnhancementScope(useSiteSession, buildJavaUseSiteScope(symbol.fir, useSiteSession, scopeSession))
|
||||
JavaClassEnhancementScope(useSiteSession, this, buildJavaUseSiteScope(symbol.fir, useSiteSession, scopeSession))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,127 +143,151 @@ class JavaSymbolProvider(
|
||||
|
||||
override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>? = getFirJavaClass(classId)
|
||||
|
||||
val findClassLock = globalFindClassLock
|
||||
|
||||
val nClassCache = TransactionalCache<ClassId, ClassCacheRec?>()
|
||||
|
||||
data class ClassCacheRec(val symbol: FirClassLikeSymbol<*>, var foundClass: JavaClass?)
|
||||
|
||||
fun getFirJavaClass(classId: ClassId, content: KotlinClassFinder.Result.ClassFileContent? = null): FirClassLikeSymbol<*>? {
|
||||
if (!hasTopLevelClassOf(classId)) return null
|
||||
return classCache.lookupCacheOrCalculateWithPostCompute(classId, {
|
||||
val foundClass = findClass(classId, content)
|
||||
if (foundClass == null || foundClass.annotations.any { it.classId?.asSingleFqName() == JvmAnnotationNames.METADATA_FQ_NAME }) {
|
||||
null to null
|
||||
} else {
|
||||
FirClassSymbol(classId) to foundClass
|
||||
}
|
||||
}) { firSymbol, foundClass ->
|
||||
foundClass?.let { javaClass ->
|
||||
val javaTypeParameterStack = JavaTypeParameterStack()
|
||||
val parentFqName = classId.relativeClassName.parent()
|
||||
val isTopLevel = parentFqName.isRoot
|
||||
if (!isTopLevel) {
|
||||
val parentId = ClassId(classId.packageFqName, parentFqName, false)
|
||||
val parentClassSymbol = getClassLikeSymbolByFqName(parentId) as? FirClassSymbol
|
||||
val parentClass = parentClassSymbol?.fir
|
||||
if (parentClass is FirJavaClass) {
|
||||
javaTypeParameterStack.addStack(parentClass.javaTypeParameterStack)
|
||||
}
|
||||
return nClassCache.lookup(
|
||||
classId,
|
||||
{
|
||||
val foundClass = findClass(classId, content)
|
||||
if (foundClass == null || foundClass.annotations.any { it.classId?.asSingleFqName() == JvmAnnotationNames.METADATA_FQ_NAME }) {
|
||||
null
|
||||
} else {
|
||||
ClassCacheRec(FirClassSymbol(classId), foundClass)
|
||||
}
|
||||
FirJavaClass(
|
||||
session, firSymbol as FirClassSymbol, javaClass.name,
|
||||
javaClass.visibility, javaClass.modality,
|
||||
javaClass.classKind, isTopLevel = isTopLevel,
|
||||
isStatic = javaClass.isStatic,
|
||||
javaTypeParameterStack = javaTypeParameterStack
|
||||
).apply {
|
||||
this.typeParameters += foundClass.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaClass, javaTypeParameterStack)
|
||||
for (supertype in javaClass.supertypes) {
|
||||
superTypeRefs += supertype.toFirResolvedTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack)
|
||||
}
|
||||
// TODO: may be we can process fields & methods later.
|
||||
// However, they should be built up to override resolve stage
|
||||
for (javaField in javaClass.fields) {
|
||||
val fieldName = javaField.name
|
||||
val fieldId = CallableId(classId.packageFqName, classId.relativeClassName, fieldName)
|
||||
val fieldSymbol = FirFieldSymbol(fieldId)
|
||||
val returnType = javaField.type
|
||||
val firJavaField = FirJavaField(
|
||||
this@JavaSymbolProvider.session, fieldSymbol, fieldName,
|
||||
javaField.visibility, javaField.modality,
|
||||
returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack),
|
||||
isVar = !javaField.isFinal,
|
||||
isStatic = javaField.isStatic
|
||||
).apply {
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaField, javaTypeParameterStack)
|
||||
},
|
||||
{
|
||||
it?.let { (firSymbol, foundClass) ->
|
||||
val javaClass = foundClass!!
|
||||
it.foundClass = null
|
||||
val javaTypeParameterStack = JavaTypeParameterStack()
|
||||
val parentFqName = classId.relativeClassName.parent()
|
||||
val isTopLevel = parentFqName.isRoot
|
||||
if (!isTopLevel) {
|
||||
val parentId = ClassId(classId.packageFqName, parentFqName, false)
|
||||
val parentClassSymbol = getClassLikeSymbolByFqName(parentId) as? FirClassSymbol
|
||||
val parentClass = parentClassSymbol?.fir
|
||||
if (parentClass is FirJavaClass) {
|
||||
javaTypeParameterStack.addStack(parentClass.javaTypeParameterStack)
|
||||
}
|
||||
declarations += firJavaField
|
||||
}
|
||||
for (javaMethod in javaClass.methods) {
|
||||
val methodName = javaMethod.name
|
||||
val methodId = CallableId(classId.packageFqName, classId.relativeClassName, methodName)
|
||||
val methodSymbol = FirNamedFunctionSymbol(methodId)
|
||||
val returnType = javaMethod.returnType
|
||||
val firJavaMethod = FirJavaMethod(
|
||||
this@JavaSymbolProvider.session, methodSymbol, methodName,
|
||||
javaMethod.visibility, javaMethod.modality,
|
||||
returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack),
|
||||
isStatic = javaMethod.isStatic
|
||||
).apply {
|
||||
this.typeParameters += javaMethod.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaMethod, javaTypeParameterStack)
|
||||
for (valueParameter in javaMethod.valueParameters) {
|
||||
valueParameters += valueParameter.toFirValueParameters(
|
||||
this@JavaSymbolProvider.session, javaTypeParameterStack
|
||||
FirJavaClass(
|
||||
session, firSymbol as FirClassSymbol, javaClass.name,
|
||||
javaClass.visibility, javaClass.modality,
|
||||
javaClass.classKind, isTopLevel = isTopLevel,
|
||||
isStatic = javaClass.isStatic,
|
||||
javaTypeParameterStack = javaTypeParameterStack
|
||||
).apply {
|
||||
this.typeParameters += foundClass.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaClass, javaTypeParameterStack)
|
||||
for (supertype in javaClass.supertypes) {
|
||||
superTypeRefs += supertype.toFirResolvedTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack)
|
||||
}
|
||||
// TODO: may be we can process fields & methods later.
|
||||
// However, they should be built up to override resolve stage
|
||||
for (javaField in javaClass.fields) {
|
||||
val fieldName = javaField.name
|
||||
val fieldId = CallableId(classId.packageFqName, classId.relativeClassName, fieldName)
|
||||
val fieldSymbol = FirFieldSymbol(fieldId)
|
||||
val returnType = javaField.type
|
||||
val firJavaField = FirJavaField(
|
||||
this@JavaSymbolProvider.session, fieldSymbol, fieldName,
|
||||
javaField.visibility, javaField.modality,
|
||||
returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack),
|
||||
isVar = !javaField.isFinal,
|
||||
isStatic = javaField.isStatic
|
||||
).apply {
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaField, javaTypeParameterStack)
|
||||
}
|
||||
declarations += firJavaField
|
||||
}
|
||||
for (javaMethod in javaClass.methods) {
|
||||
val methodName = javaMethod.name
|
||||
val methodId = CallableId(classId.packageFqName, classId.relativeClassName, methodName)
|
||||
val methodSymbol = FirNamedFunctionSymbol(methodId)
|
||||
val returnType = javaMethod.returnType
|
||||
val firJavaMethod = FirJavaMethod(
|
||||
this@JavaSymbolProvider.session, methodSymbol, methodName,
|
||||
javaMethod.visibility, javaMethod.modality,
|
||||
returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack),
|
||||
isStatic = javaMethod.isStatic
|
||||
).apply {
|
||||
this.typeParameters += javaMethod.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaMethod, javaTypeParameterStack)
|
||||
for (valueParameter in javaMethod.valueParameters) {
|
||||
valueParameters += valueParameter.toFirValueParameters(
|
||||
this@JavaSymbolProvider.session, javaTypeParameterStack
|
||||
)
|
||||
}
|
||||
}
|
||||
declarations += firJavaMethod
|
||||
}
|
||||
val javaClassDeclaredConstructors = javaClass.constructors
|
||||
val constructorId = CallableId(classId.packageFqName, classId.relativeClassName, classId.shortClassName)
|
||||
|
||||
fun addJavaConstructor(
|
||||
visibility: Visibility = this.visibility,
|
||||
isPrimary: Boolean = false
|
||||
): FirJavaConstructor {
|
||||
val constructorSymbol = FirConstructorSymbol(constructorId)
|
||||
val classTypeParameters = javaClass.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
val firJavaConstructor = FirJavaConstructor(
|
||||
this@JavaSymbolProvider.session, constructorSymbol, visibility, isPrimary,
|
||||
FirResolvedTypeRefImpl(
|
||||
this@JavaSymbolProvider.session, null,
|
||||
firSymbol.constructType(
|
||||
classTypeParameters.map {
|
||||
ConeTypeParameterTypeImpl(
|
||||
it.symbol.toLookupTag(),
|
||||
false
|
||||
)
|
||||
}.toTypedArray(),
|
||||
false
|
||||
)
|
||||
)
|
||||
).apply {
|
||||
this.typeParameters += classTypeParameters
|
||||
}
|
||||
declarations += firJavaConstructor
|
||||
return firJavaConstructor
|
||||
}
|
||||
|
||||
if (javaClassDeclaredConstructors.isEmpty() && javaClass.classKind == ClassKind.CLASS) {
|
||||
addJavaConstructor(isPrimary = true)
|
||||
}
|
||||
for (javaConstructor in javaClassDeclaredConstructors) {
|
||||
addJavaConstructor(javaConstructor.visibility).apply {
|
||||
this.typeParameters += javaConstructor.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaConstructor, javaTypeParameterStack)
|
||||
for (valueParameter in javaConstructor.valueParameters) {
|
||||
valueParameters += valueParameter.toFirValueParameters(
|
||||
this@JavaSymbolProvider.session, javaTypeParameterStack
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
declarations += firJavaMethod
|
||||
}
|
||||
val javaClassDeclaredConstructors = javaClass.constructors
|
||||
val constructorId = CallableId(classId.packageFqName, classId.relativeClassName, classId.shortClassName)
|
||||
|
||||
fun addJavaConstructor(
|
||||
visibility: Visibility = this.visibility,
|
||||
isPrimary: Boolean = false
|
||||
): FirJavaConstructor {
|
||||
val constructorSymbol = FirConstructorSymbol(constructorId)
|
||||
val classTypeParameters = javaClass.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
val firJavaConstructor = FirJavaConstructor(
|
||||
this@JavaSymbolProvider.session, constructorSymbol, visibility, isPrimary,
|
||||
FirResolvedTypeRefImpl(
|
||||
this@JavaSymbolProvider.session, null,
|
||||
firSymbol.constructType(
|
||||
classTypeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(),
|
||||
false
|
||||
)
|
||||
)
|
||||
).apply {
|
||||
this.typeParameters += classTypeParameters
|
||||
}
|
||||
declarations += firJavaConstructor
|
||||
return firJavaConstructor
|
||||
}
|
||||
|
||||
if (javaClassDeclaredConstructors.isEmpty() && javaClass.classKind == ClassKind.CLASS) {
|
||||
addJavaConstructor(isPrimary = true)
|
||||
}
|
||||
for (javaConstructor in javaClassDeclaredConstructors) {
|
||||
addJavaConstructor(javaConstructor.visibility).apply {
|
||||
this.typeParameters += javaConstructor.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaConstructor, javaTypeParameterStack)
|
||||
for (valueParameter in javaConstructor.valueParameters) {
|
||||
valueParameters += valueParameter.toFirValueParameters(
|
||||
this@JavaSymbolProvider.session, javaTypeParameterStack
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
)?.symbol
|
||||
}
|
||||
|
||||
private fun findPackageUncached(fqName: FqName): PsiPackage? {
|
||||
return facade.findPackage(fqName.asString(), searchScope)
|
||||
}
|
||||
|
||||
val nPackageCache = ConcurrentHashMapNonRecursiveComputeCache<FqName, FqName?>()
|
||||
|
||||
override fun getPackage(fqName: FqName): FqName? {
|
||||
return packageCache.lookupCacheOrCalculate(fqName) {
|
||||
val facade = KotlinJavaPsiFacade.getInstance(project)
|
||||
val javaPackage = facade.findPackage(fqName.asString(), searchScope) ?: return@lookupCacheOrCalculate null
|
||||
return nPackageCache.lookup(fqName) {
|
||||
val javaPackage = findPackageUncached(fqName) ?: return@lookup null
|
||||
FqName(javaPackage.qualifiedName)
|
||||
}
|
||||
}
|
||||
@@ -266,16 +299,19 @@ class JavaSymbolProvider(
|
||||
.map { it.fir }
|
||||
}
|
||||
|
||||
private val knownClassNamesInPackage = mutableMapOf<FqName, Set<String>?>()
|
||||
private val knownClassNamesInPackage =
|
||||
ConcurrentHashMapNonRecursiveComputeCache<FqName, Set<String>?>()
|
||||
|
||||
private fun hasTopLevelClassOf(classId: ClassId): Boolean {
|
||||
val knownNames = knownClassNamesInPackage.getOrPut(classId.packageFqName) {
|
||||
val knownNames = knownClassNamesInPackage.lookup(classId.packageFqName) {
|
||||
facade.knownClassNamesInPackage(classId.packageFqName)
|
||||
} ?: return true
|
||||
return classId.relativeClassName.topLevelName() in knownNames
|
||||
}
|
||||
}
|
||||
|
||||
val globalFindClassLock = ReentrantLock()
|
||||
|
||||
fun FqName.topLevelName() =
|
||||
asString().substringBefore(".")
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirAbstractCallableMember
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFieldSymbol
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class FirJavaField(
|
||||
@@ -43,4 +44,8 @@ class FirJavaField(
|
||||
init {
|
||||
status.isStatic = isStatic
|
||||
}
|
||||
|
||||
override fun <D> transformChildrenWithoutAccessors(transformer: FirTransformer<D>, data: D) {
|
||||
transformChildren(transformer, data)
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,9 @@ import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.java.createConstant
|
||||
import org.jetbrains.kotlin.fir.java.topLevelName
|
||||
import org.jetbrains.kotlin.fir.concurrent.ConcurrentHashMapNonRecursiveComputeCache
|
||||
import org.jetbrains.kotlin.fir.concurrent.SynchronizedComputeCache
|
||||
import org.jetbrains.kotlin.fir.concurrent.TransactionalCache
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
@@ -52,7 +55,6 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
import org.jetbrains.kotlin.serialization.deserialization.getName
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
import org.jetbrains.kotlin.utils.getOrPutNullable
|
||||
|
||||
class KotlinDeserializedJvmSymbolsProvider(
|
||||
val session: FirSession,
|
||||
@@ -63,8 +65,11 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
private val javaClassFinder: JavaClassFinder
|
||||
) : AbstractFirSymbolProvider() {
|
||||
private val classesCache = HashMap<ClassId, FirClassSymbol>()
|
||||
private val typeAliasCache = HashMap<ClassId, FirTypeAliasSymbol?>()
|
||||
private val packagePartsCache = HashMap<FqName, Collection<PackagePartsCacheData>>()
|
||||
private val typeAliasCache =
|
||||
ConcurrentHashMapNonRecursiveComputeCache<ClassId, FirTypeAliasSymbol?>()
|
||||
private val packagePartsCache =
|
||||
SynchronizedComputeCache<FqName, Collection<PackagePartsCacheData>>()
|
||||
|
||||
|
||||
private val handledByJava = HashSet<ClassId>()
|
||||
|
||||
@@ -144,7 +149,7 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
): FirScope? {
|
||||
val symbol = this.getClassLikeSymbolByFqName(classId) as? FirClassSymbol ?: return null
|
||||
val symbol = this.findAndDeserializeClassInternal(classId)?.takeUnless { it.fromJava }?.symbol ?: return null
|
||||
|
||||
return symbol.fir.buildDefaultUseSiteScope(session, scopeSession)
|
||||
}
|
||||
@@ -156,7 +161,7 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
private fun findAndDeserializeTypeAlias(
|
||||
classId: ClassId
|
||||
): FirTypeAliasSymbol? {
|
||||
return typeAliasCache.getOrPutNullable(classId) {
|
||||
return typeAliasCache.lookup(classId) {
|
||||
getPackageParts(classId.packageFqName).firstNotNullResult { part ->
|
||||
val ids = part.typeAliasNameIndex[classId.shortClassName]
|
||||
if (ids == null || ids.isEmpty()) return@firstNotNullResult null
|
||||
@@ -306,56 +311,106 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
return loadAnnotation(annotationClassId, result)
|
||||
}
|
||||
|
||||
|
||||
private val nClassesCache = TransactionalCache<ClassId, ClassCacheRec?/* null | FirClassSymbol */>()
|
||||
|
||||
private data class ClassCacheRec(
|
||||
val symbol: FirClassSymbol,
|
||||
var binaryClass: KotlinJvmBinaryClass? = null,
|
||||
val fromJava: Boolean = false
|
||||
)
|
||||
|
||||
private val enumEntryCache = TransactionalCache<FirClassSymbol, Map<Name, FirClassSymbol>?>()
|
||||
|
||||
private fun findAndDeserializeClass(
|
||||
classId: ClassId,
|
||||
parentContext: FirDeserializationContext? = null
|
||||
): FirClassSymbol? {
|
||||
if (!hasTopLevelClassOf(classId)) return null
|
||||
if (classesCache.containsKey(classId)) return classesCache[classId]
|
||||
return findAndDeserializeClassInternal(classId, parentContext)?.symbol
|
||||
}
|
||||
|
||||
if (classId in handledByJava) return null
|
||||
private fun findAndDeserializeClassInternal(
|
||||
classId: ClassId,
|
||||
parentContext: FirDeserializationContext? = null
|
||||
): ClassCacheRec? {
|
||||
|
||||
val kotlinJvmBinaryClass = when (val result = kotlinClassFinder.findKotlinClassOrContent(classId)) {
|
||||
is KotlinClassFinder.Result.KotlinClass -> result.kotlinJvmBinaryClass
|
||||
is KotlinClassFinder.Result.ClassFileContent -> {
|
||||
handledByJava.add(classId)
|
||||
return javaSymbolProvider.getFirJavaClass(classId, result) as FirClassSymbol?
|
||||
}
|
||||
null -> null
|
||||
}
|
||||
if (kotlinJvmBinaryClass == null) {
|
||||
|
||||
fun tryLoadEnum(classId: ClassId): FirClassSymbol? {
|
||||
val outerClassId = classId.outerClassId ?: return null
|
||||
findAndDeserializeClass(outerClassId) ?: return null
|
||||
} else {
|
||||
if (kotlinJvmBinaryClass.classHeader.kind != KotlinClassHeader.Kind.CLASS) return null
|
||||
val (nameResolver, classProto) = kotlinJvmBinaryClass.readClassDataFrom() ?: return null
|
||||
|
||||
val symbol = FirClassSymbol(classId)
|
||||
deserializeClassToSymbol(
|
||||
classId, classProto, symbol, nameResolver, session,
|
||||
JvmBinaryAnnotationDeserializer(session),
|
||||
parentContext, this::findAndDeserializeClass
|
||||
)
|
||||
symbol.fir.declarations.filterIsInstance<FirEnumEntryImpl>().forEach {
|
||||
classesCache[it.symbol.classId] = it.symbol
|
||||
}
|
||||
classesCache[classId] = symbol
|
||||
val annotations = mutableListOf<FirAnnotationCall>()
|
||||
kotlinJvmBinaryClass.loadClassAnnotations(object : KotlinJvmBinaryClass.AnnotationVisitor {
|
||||
override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
return loadAnnotationIfNotSpecial(classId, annotations)
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
}
|
||||
|
||||
|
||||
}, null)
|
||||
(symbol.fir as FirAbstractAnnotatedElement).annotations += annotations
|
||||
val outerClass = findAndDeserializeClass(outerClassId) ?: return null
|
||||
return enumEntryCache.lookup(
|
||||
outerClass,
|
||||
{
|
||||
val enumEntries = outerClass.fir.declarations.filterIsInstance<FirEnumEntryImpl>()
|
||||
if (enumEntries.isNotEmpty()) {
|
||||
enumEntries.associate {
|
||||
it.name to it.symbol
|
||||
}
|
||||
} else null
|
||||
},
|
||||
{}
|
||||
)?.get(classId.shortClassName)
|
||||
}
|
||||
|
||||
return classesCache[classId]
|
||||
// }
|
||||
if (!hasTopLevelClassOf(classId)) return null
|
||||
|
||||
return nClassesCache.lookup(
|
||||
classId,
|
||||
{
|
||||
val kotlinJvmBinaryClass = when (val result = kotlinClassFinder.findKotlinClassOrContent(classId)) {
|
||||
is KotlinClassFinder.Result.KotlinClass -> result.kotlinJvmBinaryClass
|
||||
is KotlinClassFinder.Result.ClassFileContent -> {
|
||||
return@lookup (javaSymbolProvider.getFirJavaClass(classId, result) as FirClassSymbol?)?.let {
|
||||
ClassCacheRec(
|
||||
it,
|
||||
fromJava = true
|
||||
)
|
||||
}
|
||||
}
|
||||
null -> null
|
||||
}
|
||||
|
||||
if (kotlinJvmBinaryClass == null) {
|
||||
return@lookup tryLoadEnum(classId)?.let(::ClassCacheRec)
|
||||
// side-effect: loads enum
|
||||
|
||||
} else {
|
||||
if (kotlinJvmBinaryClass.classHeader.kind != KotlinClassHeader.Kind.CLASS) return@lookup null
|
||||
val (nameResolver, classProto) = kotlinJvmBinaryClass.readClassDataFrom() ?: return@lookup null
|
||||
|
||||
val symbol = FirClassSymbol(classId)
|
||||
deserializeClassToSymbol(
|
||||
classId, classProto, symbol, nameResolver, session,
|
||||
JvmBinaryAnnotationDeserializer(session),
|
||||
parentContext, this::findAndDeserializeClass
|
||||
)
|
||||
return@lookup ClassCacheRec(symbol, kotlinJvmBinaryClass)
|
||||
}
|
||||
|
||||
}, { rec ->
|
||||
if (rec != null) {
|
||||
val (symbol, binaryClass) = rec
|
||||
if (binaryClass == null) return@lookup
|
||||
val annotations = mutableListOf<FirAnnotationCall>()
|
||||
binaryClass.loadClassAnnotations(object : KotlinJvmBinaryClass.AnnotationVisitor {
|
||||
override fun visitAnnotation(
|
||||
classId: ClassId,
|
||||
source: SourceElement
|
||||
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
return loadAnnotationIfNotSpecial(classId, annotations)
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
}
|
||||
|
||||
|
||||
}, null)
|
||||
(symbol.fir as FirAbstractAnnotatedElement).annotations += annotations
|
||||
rec.binaryClass = null
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
private fun loadFunctionsByName(part: PackagePartsCacheData, name: Name): List<FirCallableSymbol<*>> {
|
||||
@@ -378,19 +433,25 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
}
|
||||
}
|
||||
|
||||
private val topLevelCallablesCache =
|
||||
ConcurrentHashMapNonRecursiveComputeCache<CallableId, List<FirCallableSymbol<*>>>()
|
||||
|
||||
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> {
|
||||
return getPackageParts(packageFqName).flatMap { part ->
|
||||
loadFunctionsByName(part, name) + loadPropertiesByName(part, name)
|
||||
return topLevelCallablesCache.lookup(CallableId(packageFqName, null, name)) {
|
||||
getPackageParts(packageFqName).flatMap { part ->
|
||||
loadFunctionsByName(part, name) + loadPropertiesByName(part, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getClassDeclaredMemberScope(classId: ClassId) =
|
||||
findRegularClass(classId)?.let {
|
||||
declaredMemberScope(it)
|
||||
findAndDeserializeClassInternal(classId)?.takeUnless { it.fromJava }?.let {
|
||||
declaredMemberScope(it.symbol.fir)
|
||||
}
|
||||
|
||||
private fun getPackageParts(packageFqName: FqName): Collection<PackagePartsCacheData> {
|
||||
return packagePartsCache.getOrPut(packageFqName) {
|
||||
|
||||
return packagePartsCache.lookup(packageFqName) {
|
||||
computePackagePartsInfos(packageFqName)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.utils.Jsr305State
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.concurrent.withLock
|
||||
|
||||
internal class EnhancementSignatureParts(
|
||||
private val typeQualifierResolver: FirAnnotationTypeQualifierResolver,
|
||||
@@ -46,6 +48,7 @@ internal class EnhancementSignatureParts(
|
||||
internal fun enhance(
|
||||
session: FirSession,
|
||||
jsr305State: Jsr305State,
|
||||
lock: ReentrantLock,
|
||||
predefined: TypeEnhancementInfo? = null
|
||||
): PartEnhancementResult {
|
||||
val qualifiers = computeIndexedQualifiersForOverride(session, jsr305State)
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirConstExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.java.declarations.*
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.*
|
||||
@@ -33,9 +34,11 @@ import org.jetbrains.kotlin.load.java.typeEnhancement.PredefinedFunctionEnhancem
|
||||
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.Jsr305State
|
||||
import kotlin.concurrent.withLock
|
||||
|
||||
class JavaClassEnhancementScope(
|
||||
private val session: FirSession,
|
||||
val symbolProvider: JavaSymbolProvider,
|
||||
private val useSiteScope: JavaClassUseSiteScope
|
||||
) : FirScope() {
|
||||
private val owner: FirRegularClass = useSiteScope.symbol.fir
|
||||
@@ -241,7 +244,14 @@ class JavaClassEnhancementScope(
|
||||
private fun StringBuilder.appendErasedType(typeRef: FirTypeRef) {
|
||||
when (typeRef) {
|
||||
is FirResolvedTypeRef -> appendConeType(typeRef.type)
|
||||
is FirJavaTypeRef -> appendConeType(typeRef.toNotNullConeKotlinType(session, javaTypeParameterStack))
|
||||
is FirJavaTypeRef -> //symbolProvider.findClassLock.withLock {
|
||||
appendConeType(
|
||||
typeRef.toNotNullConeKotlinType(
|
||||
session,
|
||||
javaTypeParameterStack
|
||||
)
|
||||
)
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,7 +288,7 @@ class JavaClassEnhancementScope(
|
||||
parameterContainer = ownerFunction,
|
||||
methodContext = memberContext,
|
||||
typeInSignature = TypeInSignature.Receiver
|
||||
).enhance(session, jsr305State)
|
||||
).enhance(session, jsr305State, symbolProvider.findClassLock)
|
||||
return signatureParts.type
|
||||
}
|
||||
|
||||
@@ -299,7 +309,7 @@ class JavaClassEnhancementScope(
|
||||
parameterContainer = ownerParameter,
|
||||
methodContext = memberContext,
|
||||
typeInSignature = TypeInSignature.ValueParameter(hasReceiver, index)
|
||||
).enhance(session, jsr305State, predefinedEnhancementInfo?.parametersInfo?.getOrNull(index))
|
||||
).enhance(session, jsr305State, symbolProvider.findClassLock, predefinedEnhancementInfo?.parametersInfo?.getOrNull(index))
|
||||
val firResolvedTypeRef = signatureParts.type
|
||||
val defaultValueExpression = when (val defaultValue = ownerParameter.getDefaultValueFromAnnotation()) {
|
||||
NullDefaultValue -> FirConstExpressionImpl(session, null, IrConstKind.Null, null)
|
||||
@@ -324,7 +334,7 @@ class JavaClassEnhancementScope(
|
||||
if (owner is FirJavaField) AnnotationTypeQualifierResolver.QualifierApplicabilityType.FIELD
|
||||
else AnnotationTypeQualifierResolver.QualifierApplicabilityType.METHOD_RETURN_TYPE,
|
||||
typeInSignature = TypeInSignature.Return
|
||||
).enhance(session, jsr305State, predefinedEnhancementInfo?.returnTypeInfo)
|
||||
).enhance(session, jsr305State, symbolProvider.findClassLock, predefinedEnhancementInfo?.returnTypeInfo)
|
||||
return signatureParts.type
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
|
||||
import org.jetbrains.kotlin.fir.java.toNotNullConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.*
|
||||
@@ -68,7 +68,7 @@ class JavaClassUseSiteScope(
|
||||
val types = base.typeParameters.map {
|
||||
ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
|
||||
}
|
||||
val substitution = ConeSubstitutorByMap(overriddenInJava.typeParameters.map { it.symbol }.zip(types).toMap())
|
||||
val substitution = substitutorByMap(overriddenInJava.typeParameters.map { it.symbol }.zip(types).toMap())
|
||||
if (!overriddenInJava.typeParameters.zip(base.typeParameters).all { (a, b) ->
|
||||
a.bounds.size == b.bounds.size && a.bounds.zip(b.bounds).all { (aBound, bBound) ->
|
||||
isEqualTypes(aBound, bBound, substitution)
|
||||
|
||||
@@ -18,9 +18,8 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.dump.MultiModuleHtmlFirDump
|
||||
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.concurrent.tcReg
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirStagesTransformerFactory
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
@@ -29,7 +28,6 @@ import java.io.File
|
||||
import java.io.PrintStream
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import kotlin.system.measureNanoTime
|
||||
|
||||
|
||||
private const val FAIL_FAST = true
|
||||
@@ -55,21 +53,16 @@ class FirResolveModularizedTotalKotlinTest : AbstractModularizedTest() {
|
||||
val session = createSession(environment, scope, librariesScope)
|
||||
val builder = RawFirBuilder(session, stubMode = false)
|
||||
|
||||
val totalTransformer = FirTotalResolveTransformer()
|
||||
val firFiles = ktFiles.toList().mapNotNull {
|
||||
var firFile: FirFile? = null
|
||||
val time = measureNanoTime {
|
||||
firFile = builder.buildFirFile(it)
|
||||
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile!!)
|
||||
}
|
||||
bench.countBuilder(builder, time)
|
||||
firFile
|
||||
}.toList()
|
||||
val factory = FirStagesTransformerFactory(session)
|
||||
val firFiles = bench.buildFiles(
|
||||
builder,
|
||||
ktFiles.toList()
|
||||
)
|
||||
|
||||
|
||||
println("Raw FIR up, files: ${firFiles.size}")
|
||||
|
||||
bench.processFiles(firFiles, totalTransformer.transformers)
|
||||
bench.processFiles(firFiles, factory)
|
||||
|
||||
dumpFir(moduleData, firFiles)
|
||||
dumpFirHtml(moduleData, firFiles)
|
||||
@@ -128,6 +121,7 @@ class FirResolveModularizedTotalKotlinTest : AbstractModularizedTest() {
|
||||
bench.report(System.out, errorTypeReports = false)
|
||||
|
||||
saveReport()
|
||||
tcReg.clear()
|
||||
if (FAIL_FAST) {
|
||||
bench.throwFailure()
|
||||
}
|
||||
|
||||
@@ -6,7 +6,11 @@
|
||||
package org.jetbrains.kotlin.fir
|
||||
|
||||
import org.jetbrains.kotlin.fir.types.ConeTypeContext
|
||||
import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache
|
||||
|
||||
private class SessionBasedTypeContext(override val session: FirSession) : ConeTypeContext
|
||||
private class SessionBasedTypeContext(
|
||||
override val session: FirSession,
|
||||
override val correspondingSupertypesCache: FirCorrespondingSupertypesCache?
|
||||
) : ConeTypeContext
|
||||
|
||||
val FirSession.typeContext: ConeTypeContext get() = SessionBasedTypeContext(this)
|
||||
val FirSession.typeContext: ConeTypeContext get() = SessionBasedTypeContext(this, null)
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* 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.concurrent
|
||||
|
||||
abstract class AbstractLookupCache<K : Any, V> {
|
||||
abstract fun lookup(key: K, compute: (K) -> V): V
|
||||
}
|
||||
|
||||
abstract class AbstractLateBindingLookupCache<K : Any, V> : AbstractLookupCache<K, V>() {
|
||||
abstract fun lookup(key: K, compute: (K) -> V, postCompute: (V) -> Unit): V
|
||||
override fun lookup(key: K, compute: (K) -> V): V {
|
||||
return lookup(key, compute) {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* 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.concurrent
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class ConcurrentHashMapNonRecursiveComputeCache<K : Any, V>(
|
||||
val storage: ConcurrentHashMap<K, V> = ConcurrentHashMap()
|
||||
) : AbstractLookupCache<K, V>() {
|
||||
|
||||
override fun lookup(key: K, compute: (K) -> V): V {
|
||||
return storage.computeIfAbsent(key, compute)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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.concurrent
|
||||
|
||||
import java.lang.RuntimeException
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.concurrent.withLock
|
||||
|
||||
class NonRecursiveCooperativeComputeCache<K : Any, V> : AbstractLookupCache<K, V>() {
|
||||
|
||||
val storage = ReadLockFreeOpenAddressingHashMap<K, Any>()
|
||||
|
||||
val index = AtomicInteger()
|
||||
|
||||
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
||||
class Computation(val index: Int) {
|
||||
var completed: Boolean = false
|
||||
|
||||
@Synchronized
|
||||
fun await() {
|
||||
while (!completed) (this as Object).wait()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun complete() {
|
||||
completed = true
|
||||
(this as Object).notifyAll()
|
||||
}
|
||||
}
|
||||
|
||||
val lock = ReentrantLock()
|
||||
|
||||
|
||||
private fun Computation.beginCompute(key: K): Any? {
|
||||
while (true) {
|
||||
val otherComputation: Computation = lock.withLock {
|
||||
val nv = storage[key]
|
||||
when (nv) {
|
||||
is Computation -> {
|
||||
if (!nv.completed && nv.index < this.index) {
|
||||
return@withLock nv
|
||||
}
|
||||
storage[key] = this
|
||||
return null
|
||||
}
|
||||
null -> {
|
||||
storage[key] = this
|
||||
return nv
|
||||
}
|
||||
else -> return nv
|
||||
}
|
||||
}
|
||||
otherComputation.await()
|
||||
}
|
||||
}
|
||||
|
||||
private fun Computation.commit(key: K, value: Any): Boolean {
|
||||
return try {
|
||||
lock.withLock {
|
||||
if (storage[key] !is Computation) return@withLock false
|
||||
storage[key] = value
|
||||
true
|
||||
}
|
||||
} finally {
|
||||
complete()
|
||||
}
|
||||
}
|
||||
|
||||
override tailrec fun lookup(key: K, compute: (K) -> V): V {
|
||||
val v = storage[key]
|
||||
|
||||
if (v != null && v !is Computation) return unbox(v)
|
||||
|
||||
val computation = Computation(index.getAndIncrement())
|
||||
val nv = computation.beginCompute(key)
|
||||
val computed: Any
|
||||
if (nv == null) {
|
||||
try {
|
||||
computed = compute(key) ?: NULL
|
||||
} catch (t: Throwable) {
|
||||
computation.complete()
|
||||
throw RuntimeException("Exception in computation", t)
|
||||
}
|
||||
if (!computation.commit(key, computed)) {
|
||||
return lookup(key, compute)
|
||||
}
|
||||
} else {
|
||||
computed = nv
|
||||
}
|
||||
return unbox(computed)
|
||||
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun unbox(v: Any): V = (if (v === NULL) null else v) as V
|
||||
}
|
||||
|
||||
private val NULL = Any()
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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.concurrent
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.sqrt
|
||||
|
||||
class ReadLockFreeOpenAddressingHashMap<K : Any, V> {
|
||||
@Volatile
|
||||
private var core = Core(128)
|
||||
|
||||
operator fun contains(key: K) = core.getKey(key) === NOT_FOUND
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
operator fun get(key: K): V? {
|
||||
val value = core.getKey(key)
|
||||
return if (value === NOT_FOUND) null else value as V
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be externally synchronized
|
||||
*/
|
||||
// @Synchronized
|
||||
operator fun set(key: K, value: V) {
|
||||
while (core.isOverpopulated() || !core.putKey(key, value))
|
||||
core = core.rehash(core.length())
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be externally synchronized
|
||||
*/
|
||||
// @Synchronized
|
||||
fun putAll(map: Map<K, V>) {
|
||||
for ((k, v) in map) {
|
||||
set(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
private class Core(
|
||||
capacity: Int
|
||||
) : AtomicReferenceArray<Any?>(2 * capacity) {
|
||||
init {
|
||||
require(capacity and (capacity - 1) == 0)
|
||||
}
|
||||
|
||||
|
||||
private val shift = Integer.numberOfLeadingZeros(capacity) + 1
|
||||
private val limit: Int = capacity / 8
|
||||
var size = 0
|
||||
|
||||
fun isOverpopulated(): Boolean {
|
||||
return size > (length() / 2 * DEFAULT_LOAD_FACTOR)
|
||||
}
|
||||
|
||||
fun getKey(key: Any): Any? {
|
||||
var index = index(key)
|
||||
repeat(limit) {
|
||||
when (get(index)) {
|
||||
null -> return NOT_FOUND
|
||||
key -> return get(index + 1)
|
||||
}
|
||||
index -= 2
|
||||
if (index < 0) index = length() - 2
|
||||
}
|
||||
return NOT_FOUND
|
||||
}
|
||||
|
||||
fun putKey(key: Any, value: Any?): Boolean {
|
||||
var index = index(key)
|
||||
repeat(limit) {
|
||||
when (get(index)) {
|
||||
null -> {
|
||||
lazySet(index + 1, value) // must be first!!!
|
||||
set(index, key)
|
||||
size++
|
||||
return true
|
||||
}
|
||||
key -> {
|
||||
set(index + 1, value)
|
||||
return true
|
||||
}
|
||||
}
|
||||
index -= 2
|
||||
if (index < 0) index = length() - 2
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
fun index(key: Any): Int = (key.hashCode() * MAGIC) ushr shift shl 1
|
||||
|
||||
}
|
||||
|
||||
private tailrec fun Core.rehash(capacity: Int): Core {
|
||||
val new = Core(capacity)
|
||||
for (i in 0 until length() step 2) {
|
||||
val key = get(i)
|
||||
if (key != null) {
|
||||
if (!new.putKey(key, get(i + 1)))
|
||||
return rehash(capacity * 2)
|
||||
}
|
||||
}
|
||||
return new
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private val MAGIC: Int = ((sqrt(5.0) - 1) * 2.0.pow(31)).toLong().toInt() // golden
|
||||
private val NOT_FOUND = Any()
|
||||
private const val DEFAULT_LOAD_FACTOR = 0.5
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.concurrent
|
||||
|
||||
import org.jetbrains.kotlin.fir.resolve.getOrPut
|
||||
|
||||
class SingleThreadLookupCache<K : Any, V> : AbstractLateBindingLookupCache<K, V>() {
|
||||
|
||||
val storage = mutableMapOf<K, Any>()
|
||||
|
||||
override fun lookup(key: K, compute: (K) -> V, postCompute: (V) -> Unit): V {
|
||||
return unbox(
|
||||
storage.getOrPut(
|
||||
key,
|
||||
{ compute(key) ?: NULL },
|
||||
{ postCompute(unbox(it)) }
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun unbox(v: Any): V = (if (v === NULL) null else v) as V
|
||||
|
||||
}
|
||||
|
||||
private val NULL = Any()
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.concurrent
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.concurrent.withLock
|
||||
|
||||
class SynchronizedComputeCache<K : Any, V>(val storage: ReadLockFreeOpenAddressingHashMap<K, Any> = ReadLockFreeOpenAddressingHashMap()) :
|
||||
AbstractLookupCache<K, V>() {
|
||||
|
||||
private val lock = ReentrantLock()
|
||||
|
||||
override fun lookup(key: K, compute: (K) -> V): V {
|
||||
val v = storage[key]
|
||||
return unbox(
|
||||
if (v == null) {
|
||||
assert(!lock.isHeldByCurrentThread) { "SynchronizedComputeCache doesn't support recursive calculation" }
|
||||
lock.withLock {
|
||||
val u = storage[key]
|
||||
if (u == null) {
|
||||
val computed = compute(key) ?: NULL
|
||||
storage[key] = computed
|
||||
computed
|
||||
} else {
|
||||
u
|
||||
}
|
||||
}
|
||||
} else v
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun unbox(v: Any): V = (if (v === NULL) null else v) as V
|
||||
}
|
||||
|
||||
private val NULL = Any()
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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.concurrent
|
||||
|
||||
import java.lang.RuntimeException
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.concurrent.getOrSet
|
||||
import kotlin.concurrent.withLock
|
||||
|
||||
val tcReg = mutableListOf<TransactionalCache<*, *>>()
|
||||
|
||||
class TransactionalCache<K : Any, V> : AbstractLateBindingLookupCache<K, V>() {
|
||||
init {
|
||||
tcReg += this
|
||||
}
|
||||
|
||||
val storage: ReadLockFreeOpenAddressingHashMap<K, Any> =
|
||||
ReadLockFreeOpenAddressingHashMap()
|
||||
|
||||
private var commits = 0L
|
||||
private var retries = 0L
|
||||
private var joins = 0L
|
||||
|
||||
fun stats(): String {
|
||||
return "Commits: $commits, Success: ${commits - retries}, Retries: $retries, Joins: $joins"
|
||||
}
|
||||
|
||||
private val transaction = ThreadLocal<Transaction<K>>()
|
||||
|
||||
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
||||
class Transaction<K>(
|
||||
val index: Int,
|
||||
val transactionStorage: MutableMap<K, Any>
|
||||
) {
|
||||
var completed = false
|
||||
@Synchronized
|
||||
fun await() {
|
||||
while (!completed) (this as Object).wait()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun complete() {
|
||||
completed = true
|
||||
(this as Object).notifyAll()
|
||||
}
|
||||
}
|
||||
|
||||
private val indexCounter = AtomicInteger()
|
||||
|
||||
private val lock = ReentrantLock()
|
||||
|
||||
private fun beginCompute(currentTransaction: Transaction<K>, key: K): Any? {
|
||||
while (true) {
|
||||
val v: Transaction<*> = lock.withLock {
|
||||
val v = storage[key]
|
||||
when (v) {
|
||||
is Transaction<*> -> {
|
||||
if (v.index < currentTransaction.index && !v.completed) {
|
||||
joins++
|
||||
return@withLock v
|
||||
}
|
||||
storage[key] = currentTransaction
|
||||
return null
|
||||
}
|
||||
null -> storage[key] = currentTransaction
|
||||
}
|
||||
return v
|
||||
}
|
||||
v.await()
|
||||
}
|
||||
}
|
||||
|
||||
private fun Transaction<K>.commit(): Boolean {
|
||||
return try {
|
||||
lock.withLock {
|
||||
commits++
|
||||
val canCommit = transactionStorage.keys.all {
|
||||
val v = storage[it]
|
||||
v is Transaction<*>?
|
||||
}
|
||||
|
||||
transaction.remove()
|
||||
|
||||
if (!canCommit) {
|
||||
retries++
|
||||
return@withLock false
|
||||
}
|
||||
|
||||
storage.putAll(transactionStorage)
|
||||
true
|
||||
}
|
||||
} finally {
|
||||
this.complete()
|
||||
}
|
||||
}
|
||||
|
||||
private fun Transaction<K>.abort() {
|
||||
this.complete()
|
||||
transaction.remove()
|
||||
}
|
||||
|
||||
override fun lookup(key: K, compute: (K) -> V): V {
|
||||
return lookup(key, compute, {})
|
||||
}
|
||||
|
||||
override tailrec fun lookup(key: K, compute: (K) -> V, postCompute: (V) -> Unit): V {
|
||||
|
||||
val v = storage[key]
|
||||
if (v != null && v !is Transaction<*>) return unbox(v)
|
||||
|
||||
|
||||
var startedTransaction = false
|
||||
val currentTransaction = transaction.getOrSet {
|
||||
startedTransaction = true
|
||||
Transaction(indexCounter.getAndIncrement(), mutableMapOf())
|
||||
}
|
||||
|
||||
val computed: Any
|
||||
val cached = currentTransaction.transactionStorage[key]
|
||||
if (cached != null)
|
||||
return unbox(cached)
|
||||
else {
|
||||
val nv = beginCompute(currentTransaction, key)
|
||||
if (nv == null) {
|
||||
try {
|
||||
computed = compute(key) as Any? ?: NULL
|
||||
currentTransaction.transactionStorage[key] = computed
|
||||
postCompute(unbox(computed))
|
||||
} catch (t: Throwable) {
|
||||
currentTransaction.abort()
|
||||
t.printStackTrace()
|
||||
throw RuntimeException("Exception in compute", t)
|
||||
}
|
||||
} else {
|
||||
computed = nv
|
||||
}
|
||||
}
|
||||
if (startedTransaction) {
|
||||
if (!currentTransaction.commit()) {
|
||||
return lookup(key, compute, postCompute)
|
||||
}
|
||||
}
|
||||
return unbox(computed)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun unbox(computed: Any) = (if (computed === NULL) null else computed) as V
|
||||
|
||||
|
||||
}
|
||||
|
||||
private val NULL = Any()
|
||||
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ fun resolveSubCallArgument(
|
||||
) {
|
||||
val candidate = argument.candidate() ?: return resolvePlainExpressionArgument(csBuilder, argument, expectedType, sink, isReceiver, isSafeCall, typeProvider)
|
||||
val type = sink.components.returnTypeCalculator.tryCalculateReturnType(candidate.symbol.firUnsafe()).coneTypeUnsafe<ConeKotlinType>()
|
||||
val argumentType = candidate.substitutor.substituteOrSelf(type)
|
||||
val argumentType = candidate.substitutor!!.substituteOrSelf(type)
|
||||
resolvePlainArgumentType(csBuilder, argumentType, expectedType, sink, isReceiver, isSafeCall)
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ internal fun Candidate.resolveArgument(
|
||||
|
||||
private fun Candidate.prepareExpectedType(session: FirSession, argument: FirExpression, parameter: FirValueParameter): ConeKotlinType {
|
||||
val expectedType = argument.getExpectedType(session, parameter/*, LanguageVersionSettings*/)
|
||||
return this.substitutor.substituteOrSelf(expectedType)
|
||||
return this.substitutor!!.substituteOrSelf(expectedType)
|
||||
}
|
||||
|
||||
internal fun FirExpression.getExpectedType(
|
||||
|
||||
@@ -33,9 +33,11 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.createCoroutineUnintercepted
|
||||
@@ -88,27 +90,111 @@ class CheckerSinkImpl(override val components: InferenceComponents, var continua
|
||||
}
|
||||
}
|
||||
|
||||
class CandidatePool {
|
||||
|
||||
class Candidate(
|
||||
val symbol: FirBasedSymbol<*>,
|
||||
val dispatchReceiverValue: ClassDispatchReceiverValue?,
|
||||
val implicitExtensionReceiverValue: ImplicitReceiverValue?,
|
||||
val explicitReceiverKind: ExplicitReceiverKind,
|
||||
private val inferenceComponents: InferenceComponents,
|
||||
private val baseSystem: ConstraintStorage,
|
||||
val callInfo: CallInfo
|
||||
) {
|
||||
val system by lazy {
|
||||
val system = inferenceComponents.createConstraintSystem()
|
||||
system.addOtherSystem(baseSystem)
|
||||
system
|
||||
val pool = ArrayList<PooledCandidate>()
|
||||
|
||||
private fun preAlloc(num: Int) {
|
||||
pool.ensureCapacity(num)
|
||||
repeat(num) {
|
||||
pool += PooledCandidate()
|
||||
}
|
||||
}
|
||||
lateinit var substitutor: ConeSubstitutor
|
||||
|
||||
fun new(): PooledCandidate {
|
||||
if (pool.isEmpty()) {
|
||||
preAlloc(16)
|
||||
}
|
||||
return pool.removeAt(pool.lastIndex)
|
||||
}
|
||||
|
||||
fun free(candidate: PooledCandidate) {
|
||||
candidate.reset()
|
||||
pool.add(candidate)
|
||||
}
|
||||
}
|
||||
|
||||
class PooledCandidate() {
|
||||
|
||||
var symbol: FirBasedSymbol<*>? = null
|
||||
var dispatchReceiverValue: ClassDispatchReceiverValue? = null
|
||||
var implicitExtensionReceiverValue: ImplicitReceiverValue? = null
|
||||
var explicitReceiverKind: ExplicitReceiverKind? = null
|
||||
|
||||
var system: NewConstraintSystemImpl? = null
|
||||
var callInfo: CallInfo? = null
|
||||
var substitutor: ConeSubstitutor? = null
|
||||
|
||||
var argumentMapping: Map<FirExpression, FirValueParameter>? = null
|
||||
val postponedAtoms = mutableListOf<PostponedResolvedAtomMarker>()
|
||||
|
||||
var baseSystem: ConstraintStorage? = null
|
||||
var inferenceComponents: InferenceComponents? = null
|
||||
|
||||
fun system(): NewConstraintSystemImpl {
|
||||
return system ?: inferenceComponents!!.createConstraintSystem()?.also {
|
||||
it.addOtherSystem(baseSystem!!)
|
||||
system = it
|
||||
}
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
symbol = null
|
||||
dispatchReceiverValue = null
|
||||
implicitExtensionReceiverValue = null
|
||||
explicitReceiverKind = null
|
||||
system = null
|
||||
callInfo = null
|
||||
substitutor = null
|
||||
baseSystem = null
|
||||
inferenceComponents = null
|
||||
argumentMapping = null
|
||||
postponedAtoms.clear()
|
||||
}
|
||||
}
|
||||
|
||||
inline class Candidate(val pooledCandidate: PooledCandidate) {
|
||||
val symbol: FirBasedSymbol<*> get() = pooledCandidate.symbol!!
|
||||
val dispatchReceiverValue: ClassDispatchReceiverValue? get() = pooledCandidate.dispatchReceiverValue
|
||||
val implicitExtensionReceiverValue: ImplicitReceiverValue? get() = pooledCandidate.implicitExtensionReceiverValue
|
||||
val explicitReceiverKind: ExplicitReceiverKind get() = pooledCandidate.explicitReceiverKind!!
|
||||
val callInfo: CallInfo get() = pooledCandidate.callInfo!!
|
||||
val system get() = pooledCandidate.system()
|
||||
|
||||
var substitutor: ConeSubstitutor?
|
||||
get() = pooledCandidate.substitutor
|
||||
set(value) {
|
||||
pooledCandidate.substitutor = value
|
||||
}
|
||||
var argumentMapping: Map<FirExpression, FirValueParameter>?
|
||||
get() = pooledCandidate.argumentMapping
|
||||
set(value) {
|
||||
pooledCandidate.argumentMapping = value
|
||||
}
|
||||
|
||||
val postponedAtoms get() = pooledCandidate.postponedAtoms
|
||||
}
|
||||
//
|
||||
//class Candidate(
|
||||
// val symbol: FirBasedSymbol<*>,
|
||||
// val dispatchReceiverValue: ClassDispatchReceiverValue?,
|
||||
// val implicitExtensionReceiverValue: ImplicitReceiverValue?,
|
||||
// val explicitReceiverKind: ExplicitReceiverKind,
|
||||
// private val inferenceComponents: InferenceComponents,
|
||||
// private val baseSystem: ConstraintStorage,
|
||||
// val callInfo: CallInfo
|
||||
//) {
|
||||
// val system by lazy {
|
||||
// val system = inferenceComponents.createConstraintSystem()
|
||||
// system.addOtherSystem(baseSystem)
|
||||
// system
|
||||
// }
|
||||
// lateinit var substitutor: ConeSubstitutor
|
||||
//
|
||||
// var argumentMapping: Map<FirExpression, FirValueParameter>? = null
|
||||
// val postponedAtoms = mutableListOf<PostponedResolvedAtomMarker>()
|
||||
//}
|
||||
|
||||
sealed class CallKind {
|
||||
abstract fun sequence(): List<ResolutionStage>
|
||||
|
||||
@@ -394,7 +480,8 @@ abstract class TowerDataConsumer {
|
||||
fun skipGroup(group: Int, resultCollector: CandidateCollector): Boolean {
|
||||
if (resultCollector.isSuccess() && stopGroup == Int.MAX_VALUE) {
|
||||
stopGroup = group
|
||||
} else if (group > stopGroup) return true
|
||||
}
|
||||
if (group >= stopGroup) return true
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -475,20 +562,18 @@ fun createFunctionConsumer(
|
||||
inferenceComponents,
|
||||
resultCollector
|
||||
),
|
||||
MultiplexerTowerDataConsumer(resultCollector).apply {
|
||||
addConsumer(
|
||||
createSimpleConsumer(
|
||||
session,
|
||||
name,
|
||||
TowerScopeLevel.Token.Properties,
|
||||
varCallInfo,
|
||||
inferenceComponents,
|
||||
InvokeCandidateCollector(
|
||||
callResolver,
|
||||
invokeCallInfo = callInfo,
|
||||
components = inferenceComponents,
|
||||
multiplexer = this
|
||||
)
|
||||
AccumulatingTowerDataConsumer(resultCollector).apply {
|
||||
initialConsumer = createSimpleConsumer(
|
||||
session,
|
||||
name,
|
||||
TowerScopeLevel.Token.Properties,
|
||||
varCallInfo,
|
||||
inferenceComponents,
|
||||
InvokeReceiverCandidateCollector(
|
||||
callResolver,
|
||||
invokeCallInfo = callInfo,
|
||||
components = inferenceComponents,
|
||||
invokeConsumer = this
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -552,16 +637,19 @@ class PrioritizedTowerDataConsumer(
|
||||
}
|
||||
}
|
||||
|
||||
class MultiplexerTowerDataConsumer(
|
||||
val resultCollector: CandidateCollector
|
||||
// Yet is used exclusively for invokes:
|
||||
// - initialConsumer consumes property which is invoke receiver
|
||||
// - additionalConsumers consume invoke calls themselves
|
||||
class AccumulatingTowerDataConsumer(
|
||||
private val resultCollector: CandidateCollector
|
||||
) : TowerDataConsumer() {
|
||||
|
||||
val consumers = mutableListOf<TowerDataConsumer>()
|
||||
val newConsumers = mutableListOf<TowerDataConsumer>()
|
||||
lateinit var initialConsumer: TowerDataConsumer
|
||||
private val additionalConsumers = mutableListOf<TowerDataConsumer>()
|
||||
|
||||
data class TowerData(val kind: TowerDataKind, val level: TowerScopeLevel, val group: Int)
|
||||
private data class TowerData(val kind: TowerDataKind, val level: TowerScopeLevel, val group: Int)
|
||||
|
||||
val datas = mutableListOf<TowerData>()
|
||||
private val accumulatedTowerData = mutableListOf<TowerData>()
|
||||
|
||||
override fun consume(
|
||||
kind: TowerDataKind,
|
||||
@@ -569,11 +657,12 @@ class MultiplexerTowerDataConsumer(
|
||||
group: Int
|
||||
): ProcessorAction {
|
||||
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
|
||||
consumers += newConsumers
|
||||
newConsumers.clear()
|
||||
datas += TowerData(kind, towerScopeLevel, group)
|
||||
accumulatedTowerData += TowerData(kind, towerScopeLevel, group)
|
||||
|
||||
for (consumer in consumers) {
|
||||
if (initialConsumer.consume(kind, towerScopeLevel, group).stop()) {
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
for (consumer in additionalConsumers) {
|
||||
val action = consumer.consume(kind, towerScopeLevel, group)
|
||||
if (action.stop()) {
|
||||
return ProcessorAction.STOP
|
||||
@@ -582,20 +671,17 @@ class MultiplexerTowerDataConsumer(
|
||||
return ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
fun addConsumer(consumer: TowerDataConsumer): ProcessorAction =
|
||||
run {
|
||||
for ((kind, level, group) in datas) {
|
||||
if (consumer.consume(kind, level, group).stop()) {
|
||||
return@run ProcessorAction.STOP
|
||||
}
|
||||
fun addConsumer(consumer: TowerDataConsumer): ProcessorAction {
|
||||
additionalConsumers += consumer
|
||||
for ((kind, level, group) in accumulatedTowerData) {
|
||||
if (consumer.consume(kind, level, group).stop()) {
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
return@run ProcessorAction.NEXT
|
||||
}.also {
|
||||
newConsumers += consumer
|
||||
}
|
||||
return ProcessorAction.NEXT
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ExplicitReceiverTowerDataConsumer<T : FirBasedSymbol<*>>(
|
||||
val session: FirSession,
|
||||
val name: Name,
|
||||
@@ -782,7 +868,11 @@ class CallResolver(val typeCalculator: ReturnTypeCalculator, val components: Inf
|
||||
return group
|
||||
}
|
||||
|
||||
val collector by lazy { CandidateCollector(components) }
|
||||
fun reset() {
|
||||
collector.newDataSet()
|
||||
}
|
||||
|
||||
val collector = CandidateCollector(components)
|
||||
lateinit var towerDataConsumer: TowerDataConsumer
|
||||
private lateinit var implicitReceiverValues: List<ImplicitReceiverValue>
|
||||
|
||||
@@ -831,7 +921,7 @@ enum class CandidateApplicability {
|
||||
open class CandidateCollector(val components: InferenceComponents) {
|
||||
|
||||
val groupNumbers = mutableListOf<Int>()
|
||||
val candidates = mutableListOf<Candidate>()
|
||||
val candidates = mutableListOf<PooledCandidate>()
|
||||
|
||||
|
||||
var currentApplicability = CandidateApplicability.HIDDEN
|
||||
@@ -881,13 +971,14 @@ open class CandidateCollector(val components: InferenceComponents) {
|
||||
|
||||
if (applicability > currentApplicability) {
|
||||
groupNumbers.clear()
|
||||
candidates.forEach { components.candidatePool.free(it) }
|
||||
candidates.clear()
|
||||
currentApplicability = applicability
|
||||
}
|
||||
|
||||
|
||||
if (applicability == currentApplicability) {
|
||||
candidates.add(candidate)
|
||||
candidates.add(candidate.pooledCandidate)
|
||||
groupNumbers.add(group)
|
||||
}
|
||||
|
||||
@@ -897,7 +988,7 @@ open class CandidateCollector(val components: InferenceComponents) {
|
||||
|
||||
fun bestCandidates(): List<Candidate> {
|
||||
if (groupNumbers.isEmpty()) return emptyList()
|
||||
if (groupNumbers.size == 1) return candidates
|
||||
//if (groupNumbers.size == 1) return listOf(Candidate(candidates.first()))
|
||||
val result = mutableListOf<Candidate>()
|
||||
var bestGroup = groupNumbers.first()
|
||||
for ((index, candidate) in candidates.withIndex()) {
|
||||
@@ -907,7 +998,7 @@ open class CandidateCollector(val components: InferenceComponents) {
|
||||
result.clear()
|
||||
}
|
||||
if (bestGroup == group) {
|
||||
result.add(candidate)
|
||||
result.add(Candidate(candidate))
|
||||
}
|
||||
}
|
||||
return result
|
||||
@@ -918,11 +1009,13 @@ open class CandidateCollector(val components: InferenceComponents) {
|
||||
}
|
||||
}
|
||||
|
||||
class InvokeCandidateCollector(
|
||||
// Collects properties that potentially could be invoke receivers, like 'propertyName()',
|
||||
// and initiates further invoke resolution by adding property-bound invoke consumers
|
||||
class InvokeReceiverCandidateCollector(
|
||||
val callResolver: CallResolver,
|
||||
val invokeCallInfo: CallInfo,
|
||||
components: InferenceComponents,
|
||||
val multiplexer: MultiplexerTowerDataConsumer
|
||||
val invokeConsumer: AccumulatingTowerDataConsumer
|
||||
) : CandidateCollector(components) {
|
||||
override fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability {
|
||||
val applicability = super.consumeCandidate(group, candidate)
|
||||
@@ -949,10 +1042,13 @@ class InvokeCandidateCollector(
|
||||
invokeCallInfo.container,
|
||||
invokeCallInfo.typeProvider
|
||||
)
|
||||
val invokeConsumer =
|
||||
createSimpleFunctionConsumer(session, Name.identifier("invoke"), boundInvokeCallInfo, components, callResolver.collector)
|
||||
|
||||
multiplexer.addConsumer(invokeConsumer)
|
||||
invokeConsumer.addConsumer(
|
||||
createSimpleFunctionConsumer(
|
||||
session, OperatorNameConventions.INVOKE,
|
||||
boundInvokeCallInfo, components, callResolver.collector
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return applicability
|
||||
|
||||
@@ -33,9 +33,17 @@ class CandidateFactory(
|
||||
implicitExtensionReceiverValue: ImplicitReceiverValue?,
|
||||
explicitReceiverKind: ExplicitReceiverKind
|
||||
): Candidate {
|
||||
|
||||
return Candidate(
|
||||
symbol, dispatchReceiverValue, implicitExtensionReceiverValue,
|
||||
explicitReceiverKind, inferenceComponents, baseSystem, callInfo
|
||||
inferenceComponents.candidatePool.new().also {
|
||||
it.symbol = symbol
|
||||
it.dispatchReceiverValue = dispatchReceiverValue
|
||||
it.implicitExtensionReceiverValue = implicitExtensionReceiverValue
|
||||
it.explicitReceiverKind = explicitReceiverKind
|
||||
it.inferenceComponents = inferenceComponents
|
||||
it.baseSystem = baseSystem
|
||||
it.callInfo = callInfo
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext,
|
||||
}
|
||||
|
||||
override fun newBaseTypeCheckerContext(errorTypesEqualToAnything: Boolean): AbstractTypeCheckerContext {
|
||||
return ConeTypeCheckerContext(errorTypesEqualToAnything, session)
|
||||
return ConeTypeCheckerContext(errorTypesEqualToAnything, session, correspondingSupertypesCache)
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.canHaveUndefinedNullability(): Boolean {
|
||||
@@ -248,6 +248,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext,
|
||||
}
|
||||
|
||||
override fun typeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, KotlinTypeMarker>): TypeSubstitutorMarker {
|
||||
if (map.isEmpty()) return ConeSubstitutor.Empty
|
||||
return object : AbstractConeSubstitutor(),
|
||||
TypeSubstitutorMarker {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.renderWithType
|
||||
import org.jetbrains.kotlin.fir.resolve.constructType
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.service
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.invoke
|
||||
@@ -92,7 +92,7 @@ fun createToFreshVariableSubstitutorAndAddInitialConstraints(
|
||||
|
||||
val freshTypeVariables = typeParameters.map { TypeParameterBasedTypeVariable(it.symbol) }
|
||||
|
||||
val toFreshVariables = ConeSubstitutorByMap(freshTypeVariables.associate { it.typeParameterSymbol to it.defaultType })
|
||||
val toFreshVariables = substitutorByMap(freshTypeVariables.associate { it.typeParameterSymbol to it.defaultType })
|
||||
|
||||
for (freshVariable in freshTypeVariables) {
|
||||
csBuilder.registerVariable(freshVariable)
|
||||
|
||||
@@ -7,8 +7,12 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class FirNamedReferenceWithCandidate(session: FirSession, psi: PsiElement?, name: Name, val candidate: Candidate) :
|
||||
FirResolvedCallableReferenceImpl(session, psi, name, candidate.symbol)
|
||||
FirSimpleNamedReference(session, psi, name) {
|
||||
override val candidateSymbol: ConeSymbol
|
||||
get() = candidate.symbol
|
||||
}
|
||||
@@ -57,7 +57,8 @@ class InferenceComponents(
|
||||
val ctx: TypeSystemInferenceExtensionContextDelegate,
|
||||
val session: FirSession,
|
||||
val returnTypeCalculator: ReturnTypeCalculator,
|
||||
val scopeSession: ScopeSession
|
||||
val scopeSession: ScopeSession,
|
||||
val candidatePool: CandidatePool
|
||||
) {
|
||||
private val approximator = object : AbstractTypeApproximator(ctx) {
|
||||
override fun createErrorType(message: String): SimpleTypeMarker {
|
||||
|
||||
@@ -7,9 +7,11 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.arrayElementType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
|
||||
import org.jetbrains.kotlin.resolve.OverloadabilitySpecificityCallbacks
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
||||
@@ -60,7 +62,7 @@ class ConeOverloadConflictResolver(
|
||||
return FlatSignature(
|
||||
call,
|
||||
constructor.typeParameters.map { it.symbol },
|
||||
call.argumentMapping!!.map { it.value.returnTypeRef.coneTypeUnsafe() },
|
||||
call.argumentMapping!!.map { it.value.argumentType() },
|
||||
//constructor.receiverTypeRef != null,
|
||||
false,
|
||||
constructor.valueParameters.any { it.isVararg },
|
||||
@@ -70,12 +72,18 @@ class ConeOverloadConflictResolver(
|
||||
)
|
||||
}
|
||||
|
||||
private fun FirValueParameter.argumentType(): ConeKotlinType {
|
||||
val type = returnTypeRef.coneTypeUnsafe<ConeKotlinType>()
|
||||
if (isVararg) return type.arrayElementType(inferenceComponents.session)!!
|
||||
return type
|
||||
}
|
||||
|
||||
private fun createFlatSignature(call: Candidate, function: FirNamedFunction): FlatSignature<Candidate> {
|
||||
return FlatSignature(
|
||||
call,
|
||||
function.typeParameters.map { it.symbol },
|
||||
listOfNotNull<ConeKotlinType>(function.receiverTypeRef?.coneTypeUnsafe()) +
|
||||
call.argumentMapping!!.map { it.value.returnTypeRef.coneTypeUnsafe() },
|
||||
call.argumentMapping!!.map { it.value.argumentType() },
|
||||
function.receiverTypeRef != null,
|
||||
function.valueParameters.any { it.isVararg },
|
||||
function.valueParameters.count { it.defaultValue != null },
|
||||
@@ -211,7 +219,7 @@ class ConeSimpleConstraintSystemImpl(val system: NewConstraintSystemImpl) : Simp
|
||||
|
||||
it to variable.defaultType
|
||||
}
|
||||
val substitutor = ConeSubstitutorByMap(substitutionMap.cast())
|
||||
val substitutor = substitutorByMap(substitutionMap.cast())
|
||||
for (typeParameter in typeParameters) {
|
||||
require(typeParameter is FirTypeParameterSymbol)
|
||||
for (upperBound in typeParameter.fir.bounds) {
|
||||
|
||||
@@ -103,7 +103,7 @@ internal sealed class CheckReceivers : ResolutionStage() {
|
||||
resolveArgumentExpression(
|
||||
candidate.csBuilder,
|
||||
argument = explicitReceiverExpression,
|
||||
expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverParameterValue.type),
|
||||
expectedType = candidate.substitutor!!.substituteOrSelf(expectedReceiverParameterValue.type),
|
||||
expectedTypeRef = explicitReceiverExpression.typeRef,
|
||||
sink = sink,
|
||||
isReceiver = true,
|
||||
@@ -118,7 +118,7 @@ internal sealed class CheckReceivers : ResolutionStage() {
|
||||
resolvePlainArgumentType(
|
||||
candidate.csBuilder,
|
||||
argumentType = argumentExtensionReceiverValue.type,
|
||||
expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverParameterValue.type),
|
||||
expectedType = candidate.substitutor!!.substituteOrSelf(expectedReceiverParameterValue.type),
|
||||
sink = sink,
|
||||
isReceiver = true,
|
||||
isSafeCall = callInfo.isSafeCall
|
||||
|
||||
@@ -29,23 +29,21 @@ class FirDependenciesSymbolProviderImpl(val session: FirSession) : AbstractFirSy
|
||||
}
|
||||
|
||||
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> {
|
||||
return topLevelCallableCache.lookupCacheOrCalculate(CallableId(packageFqName, null, name)) {
|
||||
dependencyProviders.flatMap { provider -> provider.getTopLevelCallableSymbols(packageFqName, name) }
|
||||
} ?: emptyList()
|
||||
return dependencyProviders.flatMap { provider -> provider.getTopLevelCallableSymbols(packageFqName, name) }
|
||||
}
|
||||
|
||||
override fun getClassDeclaredMemberScope(classId: ClassId) =
|
||||
dependencyProviders.firstNotNullResult { it.getClassDeclaredMemberScope(classId) }
|
||||
|
||||
override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>? {
|
||||
return classCache.lookupCacheOrCalculate(classId) {
|
||||
for (provider in dependencyProviders) {
|
||||
provider.getClassLikeSymbolByFqName(classId)?.let {
|
||||
return@lookupCacheOrCalculate it
|
||||
}
|
||||
|
||||
for (provider in dependencyProviders) {
|
||||
provider.getClassLikeSymbolByFqName(classId)?.let {
|
||||
return it
|
||||
}
|
||||
null
|
||||
}
|
||||
return null
|
||||
|
||||
}
|
||||
|
||||
override fun getClassUseSiteMemberScope(
|
||||
@@ -57,14 +55,12 @@ class FirDependenciesSymbolProviderImpl(val session: FirSession) : AbstractFirSy
|
||||
}
|
||||
|
||||
override fun getPackage(fqName: FqName): FqName? {
|
||||
return packageCache.lookupCacheOrCalculate(fqName) {
|
||||
for (provider in dependencyProviders) {
|
||||
provider.getPackage(fqName)?.let {
|
||||
return@lookupCacheOrCalculate it
|
||||
}
|
||||
for (provider in dependencyProviders) {
|
||||
provider.getPackage(fqName)?.let {
|
||||
return it
|
||||
}
|
||||
null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getAllCallableNamesInPackage(fqName: FqName): Set<Name> {
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.fir.deserialization.FirBuiltinAnnotationDeserializer
|
||||
import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext
|
||||
import org.jetbrains.kotlin.fir.deserialization.deserializeClassToSymbol
|
||||
import org.jetbrains.kotlin.fir.concurrent.TransactionalCache
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScope
|
||||
@@ -39,9 +40,10 @@ import org.jetbrains.kotlin.serialization.deserialization.ProtoBasedClassDataFin
|
||||
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
||||
import org.jetbrains.kotlin.serialization.deserialization.getName
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
import java.io.InputStream
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider() {
|
||||
private class BuiltInsPackageFragment(stream: InputStream, val fqName: FqName, val session: FirSession) {
|
||||
@@ -74,7 +76,7 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider(
|
||||
).memberDeserializer
|
||||
}
|
||||
|
||||
val lookup = mutableMapOf<ClassId, FirClassSymbol>()
|
||||
val classCache = TransactionalCache<ClassId, FirClassSymbol>()
|
||||
|
||||
fun getClassLikeSymbolByFqName(classId: ClassId): FirClassSymbol? =
|
||||
findAndDeserializeClass(classId)
|
||||
@@ -93,7 +95,7 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider(
|
||||
return null
|
||||
}
|
||||
}
|
||||
return lookup.getOrPut(classId, { FirClassSymbol(classId) }) { symbol ->
|
||||
return classCache.lookup(classId, { FirClassSymbol(classId) }) { symbol ->
|
||||
if (shouldBeEnumEntry) {
|
||||
FirEnumEntryImpl(session, null, symbol, classId.shortClassName)
|
||||
} else {
|
||||
@@ -152,7 +154,7 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider(
|
||||
|
||||
private val allPackageFragments = loadBuiltIns().groupBy { it.fqName }
|
||||
|
||||
private val fictitiousFunctionSymbols = mutableMapOf<Int, FirClassSymbol>()
|
||||
private val fictitiousFunctionSymbols = ConcurrentHashMap<Int, FirClassSymbol>()
|
||||
|
||||
override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassSymbol? {
|
||||
return allPackageFragments[classId.packageFqName]?.firstNotNullResult {
|
||||
@@ -162,7 +164,7 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider(
|
||||
val kind = FunctionClassDescriptor.Kind.byClassNamePrefix(packageFqName, className) ?: return@with null
|
||||
val prefix = kind.classNamePrefix
|
||||
val arity = className.substring(prefix.length).toIntOrNull() ?: return null
|
||||
fictitiousFunctionSymbols.getOrPut(arity) {
|
||||
fictitiousFunctionSymbols.computeIfAbsent(arity) {
|
||||
FirClassSymbol(this).apply {
|
||||
FirClassImpl(
|
||||
session,
|
||||
@@ -199,7 +201,7 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider(
|
||||
false
|
||||
)
|
||||
)
|
||||
val name = Name.identifier("invoke")
|
||||
val name = OperatorNameConventions.INVOKE
|
||||
addDeclaration(
|
||||
FirMemberFunctionImpl(
|
||||
session,
|
||||
|
||||
@@ -13,11 +13,11 @@ import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||
|
||||
|
||||
interface ConeSubstitutor : TypeSubstitutorMarker {
|
||||
fun substituteOrSelf(type: ConeKotlinType): ConeKotlinType
|
||||
fun substituteOrNull(type: ConeKotlinType): ConeKotlinType?
|
||||
abstract class ConeSubstitutor : TypeSubstitutorMarker {
|
||||
abstract fun substituteOrSelf(type: ConeKotlinType): ConeKotlinType
|
||||
abstract fun substituteOrNull(type: ConeKotlinType): ConeKotlinType?
|
||||
|
||||
object Empty : ConeSubstitutor {
|
||||
object Empty : ConeSubstitutor() {
|
||||
override fun substituteOrSelf(type: ConeKotlinType): ConeKotlinType {
|
||||
return type
|
||||
}
|
||||
@@ -33,7 +33,7 @@ fun ConeSubstitutor.substituteOrNull(type: ConeKotlinType?): ConeKotlinType? {
|
||||
return type?.let { substituteOrNull(it) }
|
||||
}
|
||||
|
||||
abstract class AbstractConeSubstitutor : ConeSubstitutor {
|
||||
abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
||||
private fun wrapProjection(old: ConeKotlinTypeProjection, newType: ConeKotlinType): ConeKotlinTypeProjection {
|
||||
return when (old) {
|
||||
is ConeStarProjection -> old
|
||||
@@ -130,6 +130,11 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor {
|
||||
}
|
||||
|
||||
|
||||
fun substitutorByMap(substitution: Map<ConeTypeParameterSymbol, ConeKotlinType>): ConeSubstitutor {
|
||||
if (substitution.isEmpty()) return ConeSubstitutor.Empty
|
||||
return ConeSubstitutorByMap(substitution)
|
||||
}
|
||||
|
||||
class ConeSubstitutorByMap(val substitution: Map<ConeTypeParameterSymbol, ConeKotlinType>) : AbstractConeSubstitutor() {
|
||||
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
|
||||
@@ -12,9 +12,10 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedQualifierImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.fir.references.FirBackingFieldReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||
@@ -25,8 +26,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirTopLevelDeclaredMemberScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
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.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.*
|
||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||
@@ -74,11 +74,6 @@ open class FirBodyResolveTransformer(
|
||||
private var primaryConstructorParametersScope: FirLocalScope? = null
|
||||
|
||||
override fun transformConstructor(constructor: FirConstructor, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
if (constructor.isPrimary) {
|
||||
primaryConstructorParametersScope = FirLocalScope().apply {
|
||||
constructor.valueParameters.forEach { this.storeDeclaration(it) }
|
||||
}
|
||||
}
|
||||
if (implicitTypeOnly) return constructor.compose()
|
||||
return super.transformConstructor(constructor, data)
|
||||
}
|
||||
@@ -131,6 +126,12 @@ open class FirBodyResolveTransformer(
|
||||
scopes.addIfNotNull(symbolProvider.getClassUseSiteMemberScope(companionObject.classId, session, scopeSession))
|
||||
}
|
||||
val result = withLabelAndReceiverType(regularClass.name, regularClass, type) {
|
||||
val constructor = regularClass.declarations.firstOrNull() as? FirConstructor
|
||||
if (constructor?.isPrimary == true) {
|
||||
primaryConstructorParametersScope = FirLocalScope().apply {
|
||||
constructor.valueParameters.forEach { this.storeDeclaration(it) }
|
||||
}
|
||||
}
|
||||
super.transformRegularClass(regularClass, data)
|
||||
}
|
||||
primaryConstructorParametersScope = oldConstructorScope
|
||||
@@ -200,39 +201,51 @@ open class FirBodyResolveTransformer(
|
||||
access.resultType = typeFromCallee(access)
|
||||
}
|
||||
|
||||
private fun typeFromSymbol(symbol: ConeSymbol, makeNullable: Boolean): FirResolvedTypeRef {
|
||||
return when (symbol) {
|
||||
is FirCallableSymbol<*> -> {
|
||||
val returnType = jump.tryCalculateReturnType(symbol.fir)
|
||||
if (makeNullable) {
|
||||
returnType.withReplacedConeType(
|
||||
session,
|
||||
returnType.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NULLABLE)
|
||||
)
|
||||
} else {
|
||||
returnType
|
||||
}
|
||||
}
|
||||
is ConeClassifierSymbol -> {
|
||||
val fir = (symbol as? FirBasedSymbol<*>)?.fir
|
||||
// TODO: unhack
|
||||
if (fir is FirEnumEntry) {
|
||||
(fir.superTypeRefs.firstOrNull() as? FirResolvedTypeRef) ?: FirErrorTypeRefImpl(
|
||||
session,
|
||||
null,
|
||||
"no enum item supertype"
|
||||
)
|
||||
} else
|
||||
FirResolvedTypeRefImpl(
|
||||
session, null, symbol.constructType(emptyArray(), isNullable = false),
|
||||
annotations = emptyList()
|
||||
)
|
||||
}
|
||||
else -> error("WTF ! $symbol")
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T> typeFromCallee(access: T): FirResolvedTypeRef where T : FirQualifiedAccess {
|
||||
val makeNullable: Boolean by lazy {
|
||||
access.safe && access.explicitReceiver!!.resultType.coneTypeUnsafe<ConeKotlinType>().isNullable
|
||||
}
|
||||
|
||||
return when (val newCallee = access.calleeReference) {
|
||||
is FirErrorNamedReference ->
|
||||
FirErrorTypeRefImpl(session, access.psi, newCallee.errorReason)
|
||||
is FirNamedReferenceWithCandidate -> {
|
||||
typeFromSymbol(newCallee.candidateSymbol, makeNullable)
|
||||
}
|
||||
is FirResolvedCallableReference -> {
|
||||
val symbol = newCallee.coneSymbol
|
||||
if (symbol is FirCallableSymbol<*>) {
|
||||
val returnType = jump.tryCalculateReturnType(symbol.fir)
|
||||
if (access.safe && access.explicitReceiver!!.resultType.coneTypeUnsafe<ConeKotlinType>().isNullable) {
|
||||
returnType.withReplacedConeType(
|
||||
session,
|
||||
returnType.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NULLABLE)
|
||||
)
|
||||
} else {
|
||||
returnType
|
||||
}
|
||||
} else if (symbol is ConeClassifierSymbol && symbol is FirBasedSymbol<*>) {
|
||||
val fir = symbol.fir
|
||||
// TODO: unhack
|
||||
if (fir is FirEnumEntry) {
|
||||
(fir.superTypeRefs.firstOrNull() as? FirResolvedTypeRef) ?: FirErrorTypeRefImpl(
|
||||
session,
|
||||
null,
|
||||
"no enum item supertype"
|
||||
)
|
||||
} else
|
||||
FirResolvedTypeRefImpl(
|
||||
session, null, symbol.constructType(emptyArray(), isNullable = false),
|
||||
annotations = emptyList()
|
||||
)
|
||||
} else {
|
||||
error("WTF ! $symbol")
|
||||
}
|
||||
typeFromSymbol(newCallee.coneSymbol, makeNullable)
|
||||
}
|
||||
is FirThisReference -> {
|
||||
val labelName = newCallee.labelName
|
||||
@@ -329,17 +342,17 @@ open class FirBodyResolveTransformer(
|
||||
file,
|
||||
container!!
|
||||
) { it.resultType }
|
||||
val resolver = CallResolver(jump, inferenceComponents)
|
||||
resolver.callInfo = info
|
||||
resolver.scopes = (scopes + localScopes).asReversed()
|
||||
callResolver.reset()
|
||||
callResolver.callInfo = info
|
||||
callResolver.scopes = (scopes + localScopes).asReversed()
|
||||
|
||||
val consumer = createVariableAndObjectConsumer(
|
||||
session,
|
||||
callee.name,
|
||||
info, inferenceComponents,
|
||||
resolver.collector
|
||||
callResolver.collector
|
||||
)
|
||||
val result = resolver.runTowerResolver(consumer, implicitReceiverStack.asReversed())
|
||||
val result = callResolver.runTowerResolver(consumer, implicitReceiverStack.asReversed())
|
||||
|
||||
val candidates = result.bestCandidates()
|
||||
val nameReference = createResolvedNamedReference(
|
||||
@@ -354,12 +367,14 @@ open class FirBodyResolveTransformer(
|
||||
tryResolveAsQualifier()?.let { return it }
|
||||
}
|
||||
|
||||
if (nameReference is FirResolvedCallableReference) {
|
||||
val symbol = nameReference.coneSymbol as? ConeClassLikeSymbol
|
||||
if (symbol != null) {
|
||||
return FirResolvedQualifierImpl(session, nameReference.psi, symbol.classId).apply {
|
||||
resultType = typeForQualifier(this)
|
||||
}
|
||||
val referencedSymbol = when (nameReference) {
|
||||
is FirResolvedCallableReference -> nameReference.coneSymbol
|
||||
is FirNamedReferenceWithCandidate -> nameReference.candidateSymbol
|
||||
else -> null
|
||||
}
|
||||
if (referencedSymbol is ConeClassLikeSymbol) {
|
||||
return FirResolvedQualifierImpl(session, nameReference.psi, referencedSymbol.classId).apply {
|
||||
resultType = typeForQualifier(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,6 +400,7 @@ open class FirBodyResolveTransformer(
|
||||
val types = if (labelName == null) labels.values() else labels[Name.identifier(labelName)]
|
||||
val type = types.lastOrNull() ?: ConeKotlinErrorType("Unresolved this@$labelName")
|
||||
qualifiedAccessExpression.resultType = FirResolvedTypeRefImpl(session, null, type, emptyList())
|
||||
return qualifiedAccessExpression.compose()
|
||||
}
|
||||
is FirSuperReference -> {
|
||||
if (callee.superTypeRef is FirResolvedTypeRef) {
|
||||
@@ -396,14 +412,23 @@ open class FirBodyResolveTransformer(
|
||||
qualifiedAccessExpression.resultType = superTypeRef
|
||||
callee.replaceSuperTypeRef(superTypeRef)
|
||||
}
|
||||
return qualifiedAccessExpression.compose()
|
||||
}
|
||||
is FirResolvedCallableReference -> {
|
||||
if (qualifiedAccessExpression.typeRef !is FirResolvedTypeRef) {
|
||||
storeTypeFromCallee(qualifiedAccessExpression)
|
||||
}
|
||||
return qualifiedAccessExpression.compose()
|
||||
}
|
||||
}
|
||||
return transformCallee(qualifiedAccessExpression).compose()
|
||||
val transformedCallee = transformCallee(qualifiedAccessExpression)
|
||||
// NB: here we can get raw expression because of dropped qualifiers (see transform callee),
|
||||
// so candidate existence must be checked before calling completion
|
||||
return if (transformedCallee is FirQualifiedAccessExpression && transformedCallee.candidate() != null) {
|
||||
completeTypeInference(transformedCallee, data as? FirTypeRef).compose()
|
||||
} else {
|
||||
transformedCallee.compose()
|
||||
}
|
||||
}
|
||||
|
||||
override fun transformVariableAssignment(
|
||||
@@ -522,7 +547,11 @@ open class FirBodyResolveTransformer(
|
||||
}
|
||||
|
||||
private val noExpectedType = FirImplicitTypeRefImpl(session, null)
|
||||
private val inferenceComponents = inferenceComponents(session, jump, scopeSession)
|
||||
private val pool = CandidatePool()
|
||||
private val inferenceComponents = inferenceComponents(session, jump, scopeSession, pool)
|
||||
private val callResolver = CallResolver(jump, inferenceComponents)
|
||||
private val conflictResolver = ConeOverloadConflictResolver(TypeSpecificityComparator.NONE, inferenceComponents)
|
||||
val completer = ConstraintSystemCompleter(inferenceComponents)
|
||||
|
||||
private fun resolveCallAndSelectCandidate(functionCall: FirFunctionCall, expectedTypeRef: FirTypeRef?): FirFunctionCall {
|
||||
|
||||
@@ -548,19 +577,19 @@ open class FirBodyResolveTransformer(
|
||||
file,
|
||||
container!!
|
||||
) { it.resultType }
|
||||
val resolver = CallResolver(jump, inferenceComponents)
|
||||
resolver.callInfo = info
|
||||
resolver.scopes = (scopes + localScopes).asReversed()
|
||||
callResolver.reset()
|
||||
callResolver.callInfo = info
|
||||
callResolver.scopes = (scopes + localScopes).asReversed()
|
||||
|
||||
val consumer = createFunctionConsumer(session, name, info, inferenceComponents, resolver.collector, resolver)
|
||||
val result = resolver.runTowerResolver(consumer, implicitReceiverStack.asReversed())
|
||||
val bestCandidates = result.bestCandidates()
|
||||
val consumer = createFunctionConsumer(session, name, info, inferenceComponents, callResolver.collector, callResolver)
|
||||
val result = callResolver.runTowerResolver(consumer, implicitReceiverStack.asReversed())
|
||||
val bestCandidates = result.bestCandidates().toSet()
|
||||
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
|
||||
bestCandidates.toSet()
|
||||
bestCandidates
|
||||
} else {
|
||||
ConeOverloadConflictResolver(TypeSpecificityComparator.NONE, inferenceComponents)
|
||||
.chooseMaximallySpecificCandidates(bestCandidates, discriminateGenerics = false)
|
||||
conflictResolver.chooseMaximallySpecificCandidates(bestCandidates, discriminateGenerics = false)
|
||||
}
|
||||
(bestCandidates - reducedCandidates).forEach { pool.free(it.pooledCandidate) }
|
||||
|
||||
|
||||
// fun isInvoke()
|
||||
@@ -628,7 +657,7 @@ open class FirBodyResolveTransformer(
|
||||
return qualifiedAccess
|
||||
}
|
||||
val candidate = qualifiedAccess.candidate() ?: return qualifiedAccess
|
||||
val initialSubstitutor = candidate.substitutor
|
||||
val initialSubstitutor = candidate.substitutor!!
|
||||
|
||||
val initialType = initialSubstitutor.substituteOrSelf(typeRef.type)
|
||||
|
||||
@@ -637,7 +666,7 @@ open class FirBodyResolveTransformer(
|
||||
}
|
||||
|
||||
val completionMode = candidate.computeCompletionMode(inferenceComponents, expectedTypeRef, initialType)
|
||||
val completer = ConstraintSystemCompleter(inferenceComponents)
|
||||
|
||||
val replacements = mutableMapOf<FirExpression, FirExpression>()
|
||||
|
||||
val analyzer = PostponedArgumentsAnalyzer(object : LambdaAnalyzer {
|
||||
@@ -695,14 +724,14 @@ open class FirBodyResolveTransformer(
|
||||
)
|
||||
}
|
||||
|
||||
qualifiedAccess.transformChildren(ReplaceInArguments, replacements.toMap())
|
||||
qualifiedAccess.transformChildren(MapArguments, replacements.toMap())
|
||||
|
||||
|
||||
if (completionMode == KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.FULL) {
|
||||
val finalSubstitutor =
|
||||
candidate.system.asReadOnlyStorage().buildAbstractResultingSubstitutor(inferenceComponents.ctx) as ConeSubstitutor
|
||||
return qualifiedAccess.transformSingle(
|
||||
FirCallCompleterTransformer(session, finalSubstitutor, jump),
|
||||
FirCallCompleterTransformer(session, finalSubstitutor, pool, jump),
|
||||
null
|
||||
)
|
||||
}
|
||||
@@ -733,7 +762,13 @@ open class FirBodyResolveTransformer(
|
||||
val expectedTypeRef = data as FirTypeRef?
|
||||
val completeInference =
|
||||
try {
|
||||
val initialExplicitReceiver = functionCall.explicitReceiver
|
||||
val resultExpression = resolveCallAndSelectCandidate(functionCall, expectedTypeRef)
|
||||
val resultExplicitReceiver = resultExpression.explicitReceiver
|
||||
if (initialExplicitReceiver !== resultExplicitReceiver && resultExplicitReceiver is FirQualifiedAccess) {
|
||||
// name.invoke() case
|
||||
completeTypeInference(resultExplicitReceiver, null)
|
||||
}
|
||||
completeTypeInference(resultExpression, expectedTypeRef)
|
||||
} catch (e: Throwable) {
|
||||
throw RuntimeException("While resolving call ${functionCall.render()}", e)
|
||||
@@ -773,10 +808,13 @@ open class FirBodyResolveTransformer(
|
||||
}
|
||||
candidates.size == 1 -> {
|
||||
val candidate = candidates.single()
|
||||
if (candidate.symbol is FirBackingFieldSymbol) {
|
||||
FirBackingFieldReferenceImpl(firSession, psi, candidate.symbol)
|
||||
} else {
|
||||
FirNamedReferenceWithCandidate(firSession, psi, name, candidate)
|
||||
val coneSymbol = candidate.symbol
|
||||
when {
|
||||
coneSymbol is FirBackingFieldSymbol -> FirBackingFieldReferenceImpl(firSession, psi, coneSymbol)
|
||||
coneSymbol is FirVariableSymbol &&
|
||||
(coneSymbol !is FirPropertySymbol || coneSymbol.firUnsafe<FirMemberDeclaration>().typeParameters.isEmpty()) ->
|
||||
FirResolvedCallableReferenceImpl(firSession, psi, name, coneSymbol)
|
||||
else -> FirNamedReferenceWithCandidate(firSession, psi, name, candidate)
|
||||
}
|
||||
}
|
||||
else -> FirErrorNamedReference(
|
||||
@@ -987,15 +1025,18 @@ open class FirBodyResolveTransformer(
|
||||
)
|
||||
}
|
||||
variable.delegate != null -> {
|
||||
// TODO: type from delegate
|
||||
variable.transformReturnTypeRef(
|
||||
this,
|
||||
FirErrorTypeRefImpl(
|
||||
session,
|
||||
null,
|
||||
"Not supported: type from delegate"
|
||||
val fakeInitializer = FirFunctionCallImpl(session, null).apply {
|
||||
explicitReceiver = variable.delegate
|
||||
calleeReference = FirSimpleNamedReference(this@FirBodyResolveTransformer.session, null, GET_VALUE)
|
||||
arguments += FirConstExpressionImpl(this@FirBodyResolveTransformer.session, null, IrConstKind.Null, null)
|
||||
arguments += FirThrowExpressionImpl(
|
||||
this@FirBodyResolveTransformer.session, null,
|
||||
FirConstExpressionImpl(this@FirBodyResolveTransformer.session, null, IrConstKind.Null, null)
|
||||
)
|
||||
)
|
||||
}
|
||||
val result = transformFunctionCall(fakeInitializer, variable.returnTypeRef).single as FirFunctionCall
|
||||
variable.replaceDelegate(result.explicitReceiver)
|
||||
variable.transformReturnTypeRef(this, result.typeRef)
|
||||
}
|
||||
variable is FirProperty && variable.getter !is FirDefaultPropertyAccessor -> {
|
||||
variable.transformReturnTypeRef(
|
||||
@@ -1034,11 +1075,14 @@ open class FirBodyResolveTransformer(
|
||||
override fun transformProperty(property: FirProperty, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
val returnTypeRef = property.returnTypeRef
|
||||
if (returnTypeRef !is FirImplicitTypeRef && implicitTypeOnly) return property.compose()
|
||||
if (returnTypeRef is FirImplicitTypeRef) {
|
||||
property.transformReturnTypeRef(StoreType, FirComputingImplicitTypeRef)
|
||||
}
|
||||
return withScopeCleanup(localScopes) {
|
||||
localScopes.addIfNotNull(primaryConstructorParametersScope)
|
||||
withContainer(property) {
|
||||
property.transformChildrenWithoutAccessors(this, returnTypeRef)
|
||||
if (property.returnTypeRef is FirImplicitTypeRef && property.initializer != null) {
|
||||
if (property.initializer != null || property.delegate != null) {
|
||||
storeVariableReturnType(property)
|
||||
}
|
||||
withScopeCleanup(localScopes) {
|
||||
@@ -1107,9 +1151,18 @@ open class FirBodyResolveTransformer(
|
||||
)
|
||||
return transformedGetClassCall.compose()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val GET_VALUE = Name.identifier("getValue")
|
||||
}
|
||||
}
|
||||
|
||||
private fun inferenceComponents(session: FirSession, jump: ReturnTypeCalculatorWithJump, scopeSession: ScopeSession) =
|
||||
private fun inferenceComponents(
|
||||
session: FirSession,
|
||||
jump: ReturnTypeCalculatorWithJump,
|
||||
scopeSession: ScopeSession,
|
||||
candidatePool: CandidatePool
|
||||
) =
|
||||
InferenceComponents(object : ConeInferenceContext, TypeSystemInferenceExtensionContextDelegate {
|
||||
override fun findCommonIntegerLiteralTypesSuperType(explicitSupertypes: List<SimpleTypeMarker>): SimpleTypeMarker? {
|
||||
//TODO wtf
|
||||
@@ -1120,34 +1173,22 @@ private fun inferenceComponents(session: FirSession, jump: ReturnTypeCalculatorW
|
||||
TODO("not implemented")
|
||||
}
|
||||
|
||||
override val correspondingSupertypesCache = FirCorrespondingSupertypesCache(session)
|
||||
|
||||
override val session: FirSession
|
||||
get() = session
|
||||
|
||||
override fun KotlinTypeMarker.removeExactAnnotation(): KotlinTypeMarker {
|
||||
return this
|
||||
}
|
||||
}, session, jump, scopeSession)
|
||||
}, session, jump, scopeSession, candidatePool)
|
||||
|
||||
|
||||
class ReturnTypeCalculatorWithJump(val session: FirSession, val scopeSession: ScopeSession) : ReturnTypeCalculator {
|
||||
|
||||
|
||||
val storeType = object : FirTransformer<FirTypeRef>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: FirTypeRef): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
override fun transformImplicitTypeRef(
|
||||
implicitTypeRef: FirImplicitTypeRef,
|
||||
data: FirTypeRef
|
||||
): CompositeTransformResult<FirTypeRef> {
|
||||
return data.compose()
|
||||
}
|
||||
}
|
||||
|
||||
private fun cycleErrorType(declaration: FirTypedDeclaration): FirResolvedTypeRef? {
|
||||
if (declaration.returnTypeRef is FirComputingImplicitTypeRef) {
|
||||
declaration.transformReturnTypeRef(storeType, FirErrorTypeRefImpl(session, null, "cycle"))
|
||||
declaration.transformReturnTypeRef(TransformImplicitType, FirErrorTypeRefImpl(session, null, "cycle"))
|
||||
return declaration.returnTypeRef as FirResolvedTypeRef
|
||||
}
|
||||
return null
|
||||
@@ -1157,7 +1198,7 @@ class ReturnTypeCalculatorWithJump(val session: FirSession, val scopeSession: Sc
|
||||
|
||||
if (declaration is FirValueParameter && declaration.returnTypeRef is FirImplicitTypeRef) {
|
||||
// TODO?
|
||||
declaration.transformReturnTypeRef(storeType, FirErrorTypeRefImpl(session, null, "Unsupported: implicit VP type"))
|
||||
declaration.transformReturnTypeRef(TransformImplicitType, FirErrorTypeRefImpl(session, null, "Unsupported: implicit VP type"))
|
||||
}
|
||||
val returnTypeRef = declaration.returnTypeRef
|
||||
if (returnTypeRef is FirResolvedTypeRef) return returnTypeRef
|
||||
@@ -1182,11 +1223,11 @@ class ReturnTypeCalculatorWithJump(val session: FirSession, val scopeSession: Sc
|
||||
"I don't know what todo"
|
||||
)
|
||||
|
||||
declaration.transformReturnTypeRef(storeType, FirComputingImplicitTypeRef)
|
||||
declaration.transformReturnTypeRef(TransformImplicitType, FirComputingImplicitTypeRef)
|
||||
|
||||
val transformer = FirDesignatedBodyResolveTransformer(
|
||||
(listOf(file) + outerClasses.filterNotNull().asReversed() + listOf(declaration)).iterator(),
|
||||
file.session,
|
||||
file.fileSession,
|
||||
scopeSession
|
||||
)
|
||||
|
||||
@@ -1195,7 +1236,9 @@ class ReturnTypeCalculatorWithJump(val session: FirSession, val scopeSession: Sc
|
||||
|
||||
val newReturnTypeRef = declaration.returnTypeRef
|
||||
cycleErrorType(declaration)?.let { return it }
|
||||
require(newReturnTypeRef is FirResolvedTypeRef) { declaration.render() }
|
||||
require(newReturnTypeRef is FirResolvedTypeRef) {
|
||||
declaration.render()
|
||||
}
|
||||
return newReturnTypeRef
|
||||
}
|
||||
}
|
||||
@@ -1215,26 +1258,28 @@ class FirDesignatedBodyResolveTransformer(val designation: Iterator<FirElement>,
|
||||
|
||||
|
||||
@Deprecated("It is temp", level = DeprecationLevel.WARNING, replaceWith = ReplaceWith("TODO(\"что-то нормальное\")"))
|
||||
class FirImplicitTypeBodyResolveTransformerAdapter : FirTransformer<Nothing?>() {
|
||||
class FirImplicitTypeBodyResolveTransformerAdapter(session: FirSession) : FirTransformer<Nothing?>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
val transformer = FirBodyResolveTransformer(session, implicitTypeOnly = true)
|
||||
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
|
||||
val transformer = FirBodyResolveTransformer(file.session, implicitTypeOnly = true)
|
||||
|
||||
return file.transform(transformer, null)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Deprecated("It is temp", level = DeprecationLevel.WARNING, replaceWith = ReplaceWith("TODO(\"что-то нормальное\")"))
|
||||
class FirBodyResolveTransformerAdapter : FirTransformer<Nothing?>() {
|
||||
class FirBodyResolveTransformerAdapter(session: FirSession) : FirTransformer<Nothing?>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
val transformer = FirBodyResolveTransformer(session, implicitTypeOnly = false)
|
||||
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
|
||||
val transformer = FirBodyResolveTransformer(file.session, implicitTypeOnly = false)
|
||||
|
||||
return file.transform(transformer, null)
|
||||
}
|
||||
}
|
||||
@@ -1261,57 +1306,4 @@ interface ReturnTypeCalculator {
|
||||
fun tryCalculateReturnType(declaration: FirTypedDeclaration): FirResolvedTypeRef
|
||||
}
|
||||
|
||||
private object StoreNameReference : FirTransformer<FirNamedReference>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: FirNamedReference): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
override fun transformNamedReference(
|
||||
namedReference: FirNamedReference,
|
||||
data: FirNamedReference
|
||||
): CompositeTransformResult<FirNamedReference> {
|
||||
return data.compose()
|
||||
}
|
||||
}
|
||||
|
||||
internal object StoreType : FirTransformer<FirTypeRef>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: FirTypeRef): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
override fun transformTypeRef(typeRef: FirTypeRef, data: FirTypeRef): CompositeTransformResult<FirTypeRef> {
|
||||
return data.compose()
|
||||
}
|
||||
}
|
||||
|
||||
internal object StoreExplicitReceiver : FirTransformer<FirExpression>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: FirExpression): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
override fun transformExpression(expression: FirExpression, data: FirExpression): CompositeTransformResult<FirStatement> {
|
||||
return data.compose()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private object ReplaceInArguments : FirTransformer<Map<FirElement, FirElement>>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: Map<FirElement, FirElement>): CompositeTransformResult<E> {
|
||||
return ((data[element] ?: element) as E).compose()
|
||||
}
|
||||
|
||||
override fun transformFunctionCall(
|
||||
functionCall: FirFunctionCall,
|
||||
data: Map<FirElement, FirElement>
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
return (functionCall.transformChildren(this, data) as FirStatement).compose()
|
||||
}
|
||||
|
||||
override fun transformWrappedArgumentExpression(
|
||||
wrappedArgumentExpression: FirWrappedArgumentExpression,
|
||||
data: Map<FirElement, FirElement>
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
return (wrappedArgumentExpression.transformChildren(this, data) as FirStatement).compose()
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,11 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.CandidatePool
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||
import org.jetbrains.kotlin.fir.resolve.constructFunctionalTypeRef
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
@@ -27,25 +29,43 @@ import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.compose
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
object StoreCalleeReference : FirTransformer<FirResolvedCallableReference>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: FirResolvedCallableReference): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
override fun transformResolvedCallableReference(
|
||||
resolvedCallableReference: FirResolvedCallableReference,
|
||||
data: FirResolvedCallableReference
|
||||
): CompositeTransformResult<FirNamedReference> {
|
||||
return data.compose()
|
||||
}
|
||||
}
|
||||
|
||||
class FirCallCompleterTransformer(
|
||||
val session: FirSession,
|
||||
private val finalSubstitutor: ConeSubstitutor,
|
||||
private val candidatePool: CandidatePool,
|
||||
private val typeCalculator: ReturnTypeCalculator
|
||||
) : FirAbstractTreeTransformer() {
|
||||
|
||||
override fun transformQualifiedAccessExpression(
|
||||
qualifiedAccessExpression: FirQualifiedAccessExpression,
|
||||
data: Nothing?
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
val calleeReference =
|
||||
qualifiedAccessExpression.calleeReference as? FirNamedReferenceWithCandidate ?: return qualifiedAccessExpression.compose()
|
||||
val candidate = calleeReference.candidate
|
||||
|
||||
|
||||
val typeRef = typeCalculator.tryCalculateReturnType(calleeReference.candidateSymbol.firUnsafe())
|
||||
|
||||
val initialType = candidate.substitutor!!.substituteOrNull(typeRef.type)
|
||||
val finalType = finalSubstitutor.substituteOrNull(initialType)
|
||||
|
||||
val resultType = typeRef.withReplacedConeType(session, finalType)
|
||||
qualifiedAccessExpression.replaceTypeRef(resultType)
|
||||
|
||||
return qualifiedAccessExpression.transformCalleeReference(
|
||||
StoreCalleeReference,
|
||||
FirResolvedCallableReferenceImpl(
|
||||
calleeReference.session,
|
||||
calleeReference.psi,
|
||||
calleeReference.name,
|
||||
calleeReference.candidateSymbol
|
||||
)
|
||||
).compose().also {
|
||||
candidatePool.free(calleeReference.candidate.pooledCandidate)
|
||||
}
|
||||
}
|
||||
|
||||
override fun transformVariableAssignment(
|
||||
variableAssignment: FirVariableAssignment,
|
||||
data: Nothing?
|
||||
@@ -58,9 +78,11 @@ class FirCallCompleterTransformer(
|
||||
calleeReference.session,
|
||||
calleeReference.psi,
|
||||
calleeReference.name,
|
||||
calleeReference.coneSymbol
|
||||
calleeReference.candidateSymbol
|
||||
)
|
||||
).compose()
|
||||
).compose().also {
|
||||
candidatePool.free(calleeReference.candidate.pooledCandidate)
|
||||
}
|
||||
}
|
||||
|
||||
override fun transformFunctionCall(functionCall: FirFunctionCall, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
@@ -70,7 +92,7 @@ class FirCallCompleterTransformer(
|
||||
val subCandidate = calleeReference.candidate
|
||||
val declaration = subCandidate.symbol.firUnsafe<FirCallableMemberDeclaration<*>>()
|
||||
val newTypeParameters = declaration.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }
|
||||
.map { subCandidate.substitutor.substituteOrSelf(it) }
|
||||
.map { subCandidate.substitutor!!.substituteOrSelf(it) }
|
||||
.map { finalSubstitutor.substituteOrSelf(it) }
|
||||
.mapIndexed { index, type ->
|
||||
when (val argument = functionCall.typeArguments.getOrNull(index)) {
|
||||
@@ -96,7 +118,7 @@ class FirCallCompleterTransformer(
|
||||
|
||||
val typeRef = typeCalculator.tryCalculateReturnType(declaration)
|
||||
|
||||
val initialType = subCandidate.substitutor.substituteOrNull(typeRef.type)
|
||||
val initialType = subCandidate.substitutor!!.substituteOrNull(typeRef.type)
|
||||
val finalType = finalSubstitutor.substituteOrNull(initialType)
|
||||
|
||||
val resultType = typeRef.withReplacedConeType(session, finalType)
|
||||
@@ -108,9 +130,11 @@ class FirCallCompleterTransformer(
|
||||
calleeReference.session,
|
||||
calleeReference.psi,
|
||||
calleeReference.name,
|
||||
calleeReference.coneSymbol
|
||||
calleeReference.candidateSymbol
|
||||
)
|
||||
).compose()
|
||||
).compose().also {
|
||||
candidatePool.free(calleeReference.candidate.pooledCandidate)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.resolve.transformers
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
|
||||
class FirStagesTransformerFactory(session: FirSession) {
|
||||
|
||||
|
||||
val resolveStages: List<FirResolveStage> = listOf(
|
||||
ImportResolveStage,
|
||||
SuperTypeResolveStage,
|
||||
TypeResolveStage,
|
||||
StatusResolveStage,
|
||||
ImplicitTypeBodyResolveStage(session),
|
||||
BodyResolveStage(session)
|
||||
)
|
||||
|
||||
val stageCount = resolveStages.size
|
||||
|
||||
fun createStageTransformer(stage: Int): FirTransformer<Nothing?> {
|
||||
return resolveStages[stage].createTransformer()
|
||||
}
|
||||
|
||||
fun processFiles(files: List<FirFile>) {
|
||||
for (resolveStage in resolveStages) {
|
||||
val transformer = resolveStage.createTransformer()
|
||||
for (firFile in files) {
|
||||
firFile.transform<FirFile, Nothing?>(transformer, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class FirResolveStage() {
|
||||
abstract val isParallel: Boolean
|
||||
abstract fun createTransformer(): FirTransformer<Nothing?>
|
||||
}
|
||||
|
||||
object ImportResolveStage : FirResolveStage() {
|
||||
override val isParallel: Boolean
|
||||
get() = true
|
||||
|
||||
override fun createTransformer(): FirTransformer<Nothing?> {
|
||||
return FirImportResolveTransformer()
|
||||
}
|
||||
}
|
||||
|
||||
object SuperTypeResolveStage : FirResolveStage() {
|
||||
override val isParallel: Boolean
|
||||
get() = false
|
||||
|
||||
override fun createTransformer(): FirTransformer<Nothing?> {
|
||||
return FirSupertypeResolverTransformer()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object TypeResolveStage : FirResolveStage() {
|
||||
override val isParallel: Boolean
|
||||
get() = true
|
||||
|
||||
override fun createTransformer(): FirTransformer<Nothing?> {
|
||||
return FirTypeResolveTransformer()
|
||||
}
|
||||
}
|
||||
|
||||
object StatusResolveStage : FirResolveStage() {
|
||||
override val isParallel: Boolean
|
||||
get() = true
|
||||
|
||||
override fun createTransformer(): FirTransformer<Nothing?> {
|
||||
return FirStatusResolveTransformer()
|
||||
}
|
||||
}
|
||||
|
||||
class ImplicitTypeBodyResolveStage(val session: FirSession) : FirResolveStage() {
|
||||
override val isParallel: Boolean
|
||||
get() = false
|
||||
|
||||
override fun createTransformer(): FirTransformer<Nothing?> {
|
||||
return FirImplicitTypeBodyResolveTransformerAdapter(session)
|
||||
}
|
||||
}
|
||||
|
||||
class BodyResolveStage(val session: FirSession) : FirResolveStage() {
|
||||
override val isParallel: Boolean
|
||||
get() = true
|
||||
|
||||
override fun createTransformer(): FirTransformer<Nothing?> {
|
||||
return FirBodyResolveTransformerAdapter(session)
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.resolve.transformers
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
|
||||
class FirTotalResolveTransformer {
|
||||
|
||||
val transformers: List<FirTransformer<Nothing?>> = listOf(
|
||||
FirImportResolveTransformer(),
|
||||
FirSupertypeResolverTransformer(),
|
||||
FirTypeResolveTransformer(),
|
||||
FirStatusResolveTransformer(),
|
||||
FirImplicitTypeBodyResolveTransformerAdapter(),
|
||||
FirBodyResolveTransformerAdapter()
|
||||
)
|
||||
|
||||
fun processFiles(files: List<FirFile>) {
|
||||
for (transformer in transformers) {
|
||||
for (firFile in files) {
|
||||
firFile.transform<FirFile, Nothing?>(transformer, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.resolve.transformers
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirNamedReference
|
||||
import org.jetbrains.kotlin.fir.FirResolvedCallableReference
|
||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.compose
|
||||
|
||||
internal object MapArguments : FirTransformer<Map<FirElement, FirElement>>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: Map<FirElement, FirElement>): CompositeTransformResult<E> {
|
||||
return ((data[element] ?: element) as E).compose()
|
||||
}
|
||||
|
||||
override fun transformFunctionCall(
|
||||
functionCall: FirFunctionCall,
|
||||
data: Map<FirElement, FirElement>
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
return (functionCall.transformChildren(this, data) as FirStatement).compose()
|
||||
}
|
||||
|
||||
override fun transformWrappedArgumentExpression(
|
||||
wrappedArgumentExpression: FirWrappedArgumentExpression,
|
||||
data: Map<FirElement, FirElement>
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
return (wrappedArgumentExpression.transformChildren(this, data) as FirStatement).compose()
|
||||
}
|
||||
}
|
||||
|
||||
internal object StoreType : FirTransformer<FirTypeRef>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: FirTypeRef): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
override fun transformTypeRef(typeRef: FirTypeRef, data: FirTypeRef): CompositeTransformResult<FirTypeRef> {
|
||||
return data.compose()
|
||||
}
|
||||
}
|
||||
|
||||
internal object TransformImplicitType : FirTransformer<FirTypeRef>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: FirTypeRef): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
override fun transformImplicitTypeRef(
|
||||
implicitTypeRef: FirImplicitTypeRef,
|
||||
data: FirTypeRef
|
||||
): CompositeTransformResult<FirTypeRef> {
|
||||
return data.compose()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal object StoreNameReference : FirTransformer<FirNamedReference>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: FirNamedReference): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
override fun transformNamedReference(
|
||||
namedReference: FirNamedReference,
|
||||
data: FirNamedReference
|
||||
): CompositeTransformResult<FirNamedReference> {
|
||||
return data.compose()
|
||||
}
|
||||
}
|
||||
|
||||
internal object StoreCalleeReference : FirTransformer<FirResolvedCallableReference>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: FirResolvedCallableReference): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
override fun transformNamedReference(
|
||||
namedReference: FirNamedReference,
|
||||
data: FirResolvedCallableReference
|
||||
): CompositeTransformResult<FirNamedReference> {
|
||||
return data.compose()
|
||||
}
|
||||
|
||||
override fun transformResolvedCallableReference(
|
||||
resolvedCallableReference: FirResolvedCallableReference,
|
||||
data: FirResolvedCallableReference
|
||||
): CompositeTransformResult<FirNamedReference> {
|
||||
return data.compose()
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||
@@ -38,7 +38,7 @@ abstract class AbstractFirOverrideScope(val session: FirSession) : FirScope() {
|
||||
val types = self.typeParameters.map {
|
||||
ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
|
||||
}
|
||||
val substitution = ConeSubstitutorByMap(member.typeParameters.map { it.symbol }.zip(types).toMap())
|
||||
val substitution = substitutorByMap(member.typeParameters.map { it.symbol }.zip(types).toMap())
|
||||
if (!member.typeParameters.zip(self.typeParameters).all { (a, b) ->
|
||||
a.bounds.size == b.bounds.size &&
|
||||
a.bounds.zip(b.bounds).all { (aBound, bBound) -> isEqualTypes(aBound, bBound, substitution) }
|
||||
|
||||
@@ -19,12 +19,13 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class FirClassDeclaredMemberScopeProvider {
|
||||
|
||||
val cache = mutableMapOf<FirRegularClass, FirClassDeclaredMemberScope>()
|
||||
val cache = ConcurrentHashMap<FirRegularClass, FirClassDeclaredMemberScope>()
|
||||
fun declaredMemberScope(klass: FirRegularClass): FirClassDeclaredMemberScope {
|
||||
return cache.getOrPut(klass) {
|
||||
return cache.computeIfAbsent(klass) {
|
||||
FirClassDeclaredMemberScope(klass)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirMemberFunctionImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorWithJump
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
@@ -33,7 +33,7 @@ class FirClassSubstitutionScope(
|
||||
|
||||
private val fakeOverrides = mutableMapOf<FirFunctionSymbol<*>, FirFunctionSymbol<*>>()
|
||||
|
||||
private val substitutor = ConeSubstitutorByMap(substitution)
|
||||
private val substitutor = substitutorByMap(substitution)
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> ProcessorAction): ProcessorAction {
|
||||
useSiteScope.processFunctionsByName(name) process@{ original ->
|
||||
|
||||
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ConeTypeVariableTypeConstructor
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.hasNullableSuperType
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
||||
import org.jetbrains.kotlin.fir.service
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
@@ -33,6 +33,7 @@ class ErrorTypeConstructor(reason: String) : TypeConstructorMarker
|
||||
|
||||
interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext {
|
||||
val session: FirSession
|
||||
val correspondingSupertypesCache: FirCorrespondingSupertypesCache?
|
||||
|
||||
override fun TypeConstructorMarker.isIntegerLiteralTypeConstructor(): Boolean {
|
||||
// TODO()
|
||||
@@ -45,7 +46,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext {
|
||||
|
||||
override fun SimpleTypeMarker.fastCorrespondingSupertypes(constructor: TypeConstructorMarker): List<SimpleTypeMarker>? {
|
||||
require(this is ConeKotlinType)
|
||||
return session.correspondingSupertypesCache.getCorrespondingSupertypes(this, constructor)
|
||||
return correspondingSupertypesCache?.getCorrespondingSupertypes(this, constructor)
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.isIntegerLiteralType(): Boolean {
|
||||
@@ -419,7 +420,10 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext {
|
||||
}
|
||||
}
|
||||
|
||||
class ConeTypeCheckerContext(override val isErrorTypeEqualsToAnything: Boolean, override val session: FirSession) :
|
||||
class ConeTypeCheckerContext(
|
||||
override val isErrorTypeEqualsToAnything: Boolean, override val session: FirSession,
|
||||
override val correspondingSupertypesCache: FirCorrespondingSupertypesCache?
|
||||
) :
|
||||
AbstractTypeCheckerContext(), ConeTypeContext {
|
||||
override fun substitutionSupertypePolicy(type: SimpleTypeMarker): SupertypesPolicy {
|
||||
if (type.argumentsCount() == 0) return SupertypesPolicy.LowerIfFlexible
|
||||
@@ -435,7 +439,7 @@ class ConeTypeCheckerContext(override val isErrorTypeEqualsToAnything: Boolean,
|
||||
parameter.symbol as ConeTypeParameterSymbol to ((argument as? ConeTypedProjection)?.type
|
||||
?: StandardClassIds.Any(session.firSymbolProvider).constructType(emptyArray(), isNullable = true))
|
||||
}
|
||||
ConeSubstitutorByMap(substitution)
|
||||
substitutorByMap(substitution)
|
||||
} else {
|
||||
ConeSubstitutor.Empty
|
||||
}
|
||||
|
||||
@@ -15,15 +15,20 @@ import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
||||
import org.jetbrains.kotlin.types.model.CaptureStatus
|
||||
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.concurrent.withLock
|
||||
|
||||
class FirCorrespondingSupertypesCache(private val session: FirSession) {
|
||||
private val context = ConeTypeCheckerContext(false, session)
|
||||
private val context = ConeTypeCheckerContext(false, session, null)
|
||||
private val cache = HashMap<ConeClassLikeSymbol, Map<ConeClassLikeSymbol, List<ConeClassLikeType>>?>(1000, 0.5f)
|
||||
|
||||
private val lock = ReentrantLock()
|
||||
|
||||
fun getCorrespondingSupertypes(
|
||||
type: ConeKotlinType,
|
||||
supertypeConstructor: TypeConstructorMarker
|
||||
): List<ConeClassLikeType>? {
|
||||
|
||||
if (type !is ConeClassLikeType || supertypeConstructor !is ConeClassLikeSymbol) return null
|
||||
|
||||
val symbol = type.lookupTag.toSymbol(session) as? ConeClassLikeSymbol ?: return null
|
||||
|
||||
3
compiler/fir/resolve/testData/resolve/expresssions/invoke/propertyFromParameter.kt
vendored
Normal file
3
compiler/fir/resolve/testData/resolve/expresssions/invoke/propertyFromParameter.kt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
class Bar(name: () -> String) {
|
||||
val name = name()
|
||||
}
|
||||
10
compiler/fir/resolve/testData/resolve/expresssions/invoke/propertyFromParameter.txt
vendored
Normal file
10
compiler/fir/resolve/testData/resolve/expresssions/invoke/propertyFromParameter.txt
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
FILE: propertyFromParameter.kt
|
||||
public final class Bar : R|kotlin/Any| {
|
||||
public constructor(name: R|kotlin/Function0<kotlin/String>|): R|Bar| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val name: R|kotlin/String| = R|<local>/name|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/String|>|()
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
}
|
||||
11
compiler/fir/resolve/testData/resolve/stdlib/recursiveBug.kt
vendored
Normal file
11
compiler/fir/resolve/testData/resolve/stdlib/recursiveBug.kt
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
class Foo(name: () -> String) {
|
||||
val result = run { name() }
|
||||
|
||||
val name = result.length
|
||||
}
|
||||
|
||||
fun bar(name: () -> String) {
|
||||
val result = run { name() }
|
||||
|
||||
val name = result.length
|
||||
}
|
||||
23
compiler/fir/resolve/testData/resolve/stdlib/recursiveBug.txt
vendored
Normal file
23
compiler/fir/resolve/testData/resolve/stdlib/recursiveBug.txt
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
FILE: recursiveBug.kt
|
||||
public final class Foo : R|kotlin/Any| {
|
||||
public constructor(name: R|kotlin/Function0<kotlin/String>|): R|Foo| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val result: R|kotlin/String| = R|kotlin/run|<R|kotlin/String|>(<L> = run@fun <anonymous>(): R|kotlin/String| {
|
||||
R|<local>/name|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/String|>|()
|
||||
}
|
||||
)
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
public final val name: R|kotlin/Int| = R|/Foo.result|.R|kotlin/String.length|
|
||||
public get(): R|kotlin/Int|
|
||||
|
||||
}
|
||||
public final fun bar(name: R|kotlin/Function0<kotlin/String>|): R|kotlin/Unit| {
|
||||
lval result: R|kotlin/String| = R|kotlin/run|<R|kotlin/String|>(<L> = run@fun <anonymous>(): R|kotlin/String| {
|
||||
R|<local>/name|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/String|>|()
|
||||
}
|
||||
)
|
||||
lval name: R|kotlin/Int| = R|<local>/result|.R|kotlin/String.length|
|
||||
}
|
||||
9
compiler/fir/resolve/testData/resolve/stdlib/simpleLazy.kt
vendored
Normal file
9
compiler/fir/resolve/testData/resolve/stdlib/simpleLazy.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
//val x = lazy { "Hello" }.getValue(null, throw null)
|
||||
val x by lazy { "Hello" }
|
||||
|
||||
fun foo() {
|
||||
x.length
|
||||
|
||||
val y by lazy { "Bye" }
|
||||
y.length
|
||||
}
|
||||
14
compiler/fir/resolve/testData/resolve/stdlib/simpleLazy.txt
vendored
Normal file
14
compiler/fir/resolve/testData/resolve/stdlib/simpleLazy.txt
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
FILE: simpleLazy.kt
|
||||
public final val x: R|kotlin/String|by R|kotlin/lazy|<R|kotlin/String|>(<L> = lazy@fun <anonymous>(): R|kotlin/String| {
|
||||
String(Hello)
|
||||
}
|
||||
)
|
||||
public get(): R|kotlin/String|
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
R|/x|.R|kotlin/String.length|
|
||||
lval y: R|kotlin/String|by R|kotlin/lazy|<R|kotlin/String|>(<L> = lazy@fun <anonymous>(): R|kotlin/String| {
|
||||
String(Bye)
|
||||
}
|
||||
)
|
||||
R|<local>/y|.R|kotlin/String.length|
|
||||
}
|
||||
@@ -13,7 +13,7 @@ FILE: topLevelResolve.kt
|
||||
lval setAndList: R|kotlin/collections/Set<kotlin/Int>| = R|kotlin/collections/setOf|<R|kotlin/Int|>(Int(0)).R|kotlin/collections/plus|<R|kotlin/Int|>(R|kotlin/collections/listOf|<R|kotlin/Int|>(Int(1), Int(2)))
|
||||
lval stringAndList: R|kotlin/String| = String().R|kotlin/String.plus|(R|kotlin/collections/emptyList|<R|kotlin/Boolean|>())
|
||||
lval map: R|kotlin/collections/Map<kotlin/String, kotlin/Int>| = R|kotlin/collections/mapOf|<R|kotlin/String|, R|kotlin/Int|>(String().R|kotlin/to|<R|kotlin/String|, R|kotlin/Int|>(Int(1)), String(.).R|kotlin/to|<R|kotlin/String|, R|kotlin/Int|>(Int(2))).R|kotlin/collections/plus|<R|kotlin/String|, R|kotlin/Int|>(String(..).R|kotlin/to|<R|kotlin/String|, R|kotlin/Int|>(Int(3)))
|
||||
lval mapAndMap: <ERROR TYPE REF: Ambiguity: plus, [kotlin/plus, kotlin/plus, kotlin/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/sequences/plus, kotlin/sequences/plus, kotlin/sequences/plus, kotlin/text/plus]> = <Ambiguity: mapOf, [kotlin/collections/mapOf, kotlin/collections/mapOf]>#(String(-).R|kotlin/to|(Int(4))).<Ambiguity: plus, [kotlin/plus, kotlin/plus, kotlin/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/sequences/plus, kotlin/sequences/plus, kotlin/sequences/plus, kotlin/text/plus]>#(<Ambiguity: mapOf, [kotlin/collections/mapOf, kotlin/collections/mapOf]>#(String(_).R|kotlin/to|(Int(5))))
|
||||
lval mapAndMap: R|kotlin/collections/Map<kotlin/String, kotlin/Int>| = R|kotlin/collections/mapOf|<R|kotlin/String|, R|kotlin/Int|>(String(-).R|kotlin/to|<R|kotlin/String|, R|kotlin/Int|>(Int(4))).R|kotlin/collections/plus|<R|kotlin/String|, R|kotlin/Int|>(R|kotlin/collections/mapOf|<R|kotlin/String|, R|kotlin/Int|>(String(_).R|kotlin/to|<R|kotlin/String|, R|kotlin/Int|>(Int(5))))
|
||||
}
|
||||
public final fun <T> id(arg: R|T|): R|T| {
|
||||
^id R|<local>/arg|
|
||||
|
||||
1
compiler/fir/resolve/testData/resolve/stdlib/typeFromDelegate.kt
vendored
Normal file
1
compiler/fir/resolve/testData/resolve/stdlib/typeFromDelegate.kt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
val x by lazy { 42 }
|
||||
6
compiler/fir/resolve/testData/resolve/stdlib/typeFromDelegate.txt
vendored
Normal file
6
compiler/fir/resolve/testData/resolve/stdlib/typeFromDelegate.txt
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
FILE: typeFromDelegate.kt
|
||||
public final val x: R|kotlin/Int|by R|kotlin/lazy|<R|kotlin/Int|>(<L> = lazy@fun <anonymous>(): R|kotlin/Int| {
|
||||
Int(42)
|
||||
}
|
||||
)
|
||||
public get(): R|kotlin/Int|
|
||||
@@ -20,13 +20,10 @@ import org.jetbrains.kotlin.fir.java.FirLibrarySession
|
||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirStagesTransformerFactory
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
||||
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.konan.KonanPlatforms
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||
import java.io.File
|
||||
@@ -72,7 +69,7 @@ abstract class AbstractFirDiagnosticsSmokeTest : BaseDiagnosticsTest() {
|
||||
FirJavaModuleBasedSession(info, sessionProvider, scope)
|
||||
}
|
||||
|
||||
val firFiles = mutableListOf<FirFile>()
|
||||
val firFilesPerSession = mutableMapOf<FirSession, MutableList<FirFile>>()
|
||||
|
||||
for ((testModule, testFilesInModule) in groupedByModule) {
|
||||
val ktFiles = getKtFiles(testFilesInModule, true)
|
||||
@@ -82,7 +79,8 @@ abstract class AbstractFirDiagnosticsSmokeTest : BaseDiagnosticsTest() {
|
||||
|
||||
val firBuilder = RawFirBuilder(session, false)
|
||||
|
||||
ktFiles.mapTo(firFiles) {
|
||||
val files = firFilesPerSession.getOrPut(session) { mutableListOf() }
|
||||
ktFiles.mapTo(files) {
|
||||
val firFile = firBuilder.buildFirFile(it)
|
||||
|
||||
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
|
||||
@@ -91,7 +89,9 @@ abstract class AbstractFirDiagnosticsSmokeTest : BaseDiagnosticsTest() {
|
||||
}
|
||||
}
|
||||
|
||||
doFirResolveTestBench(firFiles, FirTotalResolveTransformer().transformers, gc = false)
|
||||
for ((session, files) in firFilesPerSession) {
|
||||
doFirResolveTestBench(files, FirStagesTransformerFactory(session), gc = false)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirStagesTransformerFactory
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
@@ -31,7 +31,7 @@ abstract class AbstractFirResolveTestCase : AbstractFirResolveWithSessionTestCas
|
||||
|
||||
val builder = RawFirBuilder(session, stubMode = false)
|
||||
|
||||
val transformer = FirTotalResolveTransformer()
|
||||
val transformer = FirStagesTransformerFactory(session)
|
||||
return ktFiles.map {
|
||||
val firFile = builder.buildFirFile(it)
|
||||
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
|
||||
|
||||
@@ -372,6 +372,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/implicitTypeOrder.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyFromParameter.kt")
|
||||
public void testPropertyFromParameter() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/propertyFromParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/simple.kt");
|
||||
|
||||
@@ -84,11 +84,21 @@ public class FirResolveTestCaseWithStdlibGenerated extends AbstractFirResolveTes
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/mapList.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveBug.kt")
|
||||
public void testRecursiveBug() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/recursiveBug.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("reflectionClass.kt")
|
||||
public void testReflectionClass() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/reflectionClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleLazy.kt")
|
||||
public void testSimpleLazy() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/simpleLazy.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelResolve.kt")
|
||||
public void testTopLevelResolve() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/topLevelResolve.kt");
|
||||
@@ -99,6 +109,11 @@ public class FirResolveTestCaseWithStdlibGenerated extends AbstractFirResolveTes
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/typeAliasDeserialization.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeFromDelegate.kt")
|
||||
public void testTypeFromDelegate() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/typeFromDelegate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unaryOperators.kt")
|
||||
public void testUnaryOperators() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/unaryOperators.kt");
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirStagesTransformerFactory
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.TestJdkKind
|
||||
@@ -69,7 +69,7 @@ class FirResolveTestTotalKotlin : AbstractFirResolveWithSessionTestCase() {
|
||||
val session = createSession(environment, scope)
|
||||
val builder = RawFirBuilder(session, stubMode = false)
|
||||
|
||||
val totalTransformer = FirTotalResolveTransformer()
|
||||
val totalTransformer = FirStagesTransformerFactory(session)
|
||||
val firFiles = ktFiles.toList().progress("Loading FIR").map {
|
||||
val firFile = builder.buildFirFile(it)
|
||||
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
|
||||
@@ -79,6 +79,6 @@ class FirResolveTestTotalKotlin : AbstractFirResolveWithSessionTestCase() {
|
||||
|
||||
println("Raw FIR up, files: ${firFiles.size}")
|
||||
|
||||
doFirResolveTestBench(firFiles, totalTransformer.transformers, withProgress = true)
|
||||
doFirResolveTestBench(firFiles, totalTransformer, withProgress = true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir
|
||||
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -12,6 +13,8 @@ import org.jetbrains.kotlin.name.Name
|
||||
interface FirNamedReference : FirReference {
|
||||
val name: Name
|
||||
|
||||
val candidateSymbol: ConeSymbol? get() = null
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitNamedReference(this, data)
|
||||
}
|
||||
@@ -783,10 +783,18 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
}
|
||||
|
||||
override fun visitNamedReference(namedReference: FirNamedReference) {
|
||||
if (namedReference is FirErrorNamedReference) {
|
||||
print("<${namedReference.errorReason}>#")
|
||||
} else {
|
||||
print("${namedReference.name}#")
|
||||
val symbol = namedReference.candidateSymbol
|
||||
when {
|
||||
symbol != null -> {
|
||||
print("R?C|")
|
||||
if (symbol is ConeCallableSymbol)
|
||||
print(symbol.callableId)
|
||||
else if (symbol is ConeClassLikeSymbol)
|
||||
print(symbol.classId)
|
||||
print("|")
|
||||
}
|
||||
namedReference is FirErrorNamedReference -> print("<${namedReference.errorReason}>#")
|
||||
else -> print("${namedReference.name}#")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,12 @@ abstract class FirSession(val sessionProvider: FirSessionProvider?) {
|
||||
|
||||
var _correspondingSupertypesCache: Any? = null
|
||||
|
||||
fun <T : Any> getService(kclass: KClass<T>): T =
|
||||
components[kclass] as T
|
||||
fun <T : Any> getService(kclass: KClass<T>): T {
|
||||
val any = components[kclass] ?: error(
|
||||
"Couldn't find $kclass in session: '${this}', available: $components"
|
||||
)
|
||||
return any as T
|
||||
}
|
||||
|
||||
protected fun <T : Any> registerComponent(tClass: KClass<T>, t: T) {
|
||||
assert(tClass !in components) { "Already registered component" }
|
||||
|
||||
@@ -29,8 +29,6 @@ interface FirProperty :
|
||||
|
||||
val backingFieldSymbol: FirBackingFieldSymbol
|
||||
|
||||
fun <D> transformChildrenWithoutAccessors(transformer: FirTransformer<D>, data: D)
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitProperty(this, data)
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.VisitedSupertype
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirVariable
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
@BaseTransformedType
|
||||
@@ -24,6 +25,10 @@ interface FirValueParameter : @VisitedSupertype FirDeclaration, FirTypedDeclarat
|
||||
|
||||
override val symbol: FirVariableSymbol<FirValueParameter>
|
||||
|
||||
override fun <D> transformChildrenWithoutAccessors(transformer: FirTransformer<D>, data: D) {
|
||||
transformChildren(transformer, data)
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitValueParameter(this, data)
|
||||
|
||||
|
||||
@@ -52,9 +52,12 @@ class FirMemberPropertyImpl(
|
||||
status.isLateInit = isLateInit
|
||||
}
|
||||
|
||||
override fun replaceDelegate(newDelegate: FirExpression?) {
|
||||
delegate = newDelegate
|
||||
}
|
||||
|
||||
override fun <D> transformChildrenWithoutAccessors(transformer: FirTransformer<D>, data: D) {
|
||||
initializer = initializer?.transformSingle(transformer, data)
|
||||
delegate = delegate?.transformSingle(transformer, data)
|
||||
receiverTypeRef = receiverTypeRef?.transformSingle(transformer, data)
|
||||
returnTypeRef = returnTypeRef.transformSingle(transformer, data)
|
||||
typeParameters.transformInplace(transformer, data)
|
||||
@@ -65,6 +68,7 @@ class FirMemberPropertyImpl(
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
||||
getter = getter.transformSingle(transformer, data)
|
||||
setter = setter?.transformSingle(transformer, data)
|
||||
delegate = delegate?.transformSingle(transformer, data)
|
||||
transformChildrenWithoutAccessors(transformer, data)
|
||||
// Everything other (annotations, etc.) is done above
|
||||
return this
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirVariable
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.transformInplace
|
||||
import org.jetbrains.kotlin.fir.transformSingle
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
@@ -34,12 +35,21 @@ class FirVariableImpl(
|
||||
override val receiverTypeRef: FirTypeRef?
|
||||
get() = null
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
||||
override fun replaceDelegate(newDelegate: FirExpression?) {
|
||||
delegate = newDelegate
|
||||
}
|
||||
|
||||
override fun <D> transformChildrenWithoutAccessors(transformer: FirTransformer<D>, data: D) {
|
||||
returnTypeRef = returnTypeRef.transformSingle(transformer, data)
|
||||
initializer = initializer?.transformSingle(transformer, data)
|
||||
delegate = delegate?.transformSingle(transformer, data)
|
||||
annotations.transformInplace(transformer, data)
|
||||
}
|
||||
|
||||
return super<FirAbstractNamedAnnotatedDeclaration>.transformChildren(transformer, data)
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
||||
delegate = delegate?.transformSingle(transformer, data)
|
||||
transformChildrenWithoutAccessors(transformer, data)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
override fun <D> transformReturnTypeRef(transformer: FirTransformer<D>, data: D) {
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.expressions
|
||||
import org.jetbrains.kotlin.fir.VisitedSupertype
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
interface FirVariable<F : FirVariable<F>> :
|
||||
@@ -23,6 +24,10 @@ interface FirVariable<F : FirVariable<F>> :
|
||||
|
||||
override val symbol: FirVariableSymbol<F>
|
||||
|
||||
fun replaceDelegate(newDelegate: FirExpression?) {}
|
||||
|
||||
fun <D> transformChildrenWithoutAccessors(transformer: FirTransformer<D>, data: D)
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitVariable(this, data)
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
open class FirResolvedCallableReferenceImpl(
|
||||
class FirResolvedCallableReferenceImpl(
|
||||
session: FirSession,
|
||||
psi: PsiElement?,
|
||||
override val name: Name,
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.fir.FirNamedReference
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class FirSimpleNamedReference(
|
||||
open class FirSimpleNamedReference(
|
||||
session: FirSession,
|
||||
psi: PsiElement?,
|
||||
override val name: Name
|
||||
|
||||
@@ -151,7 +151,7 @@ class BinaryJavaAnnotation private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private val classifierResolutionResult by lazy(LazyThreadSafetyMode.NONE) {
|
||||
private val classifierResolutionResult by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
context.resolveByInternalName(Type.getType(desc).internalName)
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ import org.jetbrains.kotlin.utils.compact
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import java.text.CharacterIterator
|
||||
import java.text.StringCharacterIterator
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.concurrent.withLock
|
||||
|
||||
/**
|
||||
* Take a look at com.intellij.psi.impl.compiled.SignatureParsing
|
||||
@@ -38,6 +40,7 @@ import java.text.StringCharacterIterator
|
||||
class BinaryClassSignatureParser {
|
||||
|
||||
private val canonicalNameInterner = StringInterner()
|
||||
private val internerLock = ReentrantLock()
|
||||
|
||||
fun parseTypeParametersDeclaration(signature: CharacterIterator, context: ClassifierResolutionContext): List<JavaTypeParameter> {
|
||||
if (signature.current() != '<') {
|
||||
@@ -99,7 +102,7 @@ class BinaryClassSignatureParser {
|
||||
signature.next()
|
||||
}
|
||||
|
||||
val parameterName = canonicalNameInterner.intern(id.toString())
|
||||
val parameterName = internerLock.withLock { canonicalNameInterner.intern(id.toString()) }
|
||||
|
||||
return PlainJavaClassifierType({ context.resolveTypeParameter(parameterName) }, emptyList())
|
||||
}
|
||||
@@ -136,7 +139,9 @@ class BinaryClassSignatureParser {
|
||||
}
|
||||
signature.next()
|
||||
|
||||
val internalName = canonicalNameInterner.intern(canonicalName.toString().replace('.', '$'))
|
||||
val internalName = internerLock.withLock {
|
||||
canonicalNameInterner.intern(canonicalName.toString().replace('.', '$'))
|
||||
}
|
||||
return PlainJavaClassifierType(
|
||||
{ context.resolveByInternalName(internalName) },
|
||||
argumentGroups.reversed().flattenTo(arrayListOf()).compact()
|
||||
|
||||
@@ -33,7 +33,7 @@ internal class PlainJavaClassifierType(
|
||||
classifierComputation: () -> ClassifierResolutionContext.Result,
|
||||
override val typeArguments: List<JavaType>
|
||||
) : JavaClassifierType {
|
||||
private val classifierResolverResult by lazy(LazyThreadSafetyMode.NONE, classifierComputation)
|
||||
private val classifierResolverResult by lazy(LazyThreadSafetyMode.PUBLICATION, classifierComputation)
|
||||
|
||||
override val classifier get() = classifierResolverResult.classifier
|
||||
override val isRaw
|
||||
|
||||
@@ -18,10 +18,9 @@ FILE fqName:<root> fileName:/delegateFieldWithAnnotations.kt
|
||||
PROPERTY name:test1 visibility:public modality:FINAL [delegated,val]
|
||||
annotations:
|
||||
Ann
|
||||
FIELD PROPERTY_BACKING_FIELD name:test1 type:IrErrorType visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test1> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.Int visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test1> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test1 visibility:public modality:FINAL [delegated,val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test1> (): IrErrorType declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test1 type:IrErrorType visibility:public [final,static] ' type=IrErrorType origin=null
|
||||
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test1> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.Int visibility:public [final,static] ' type=kotlin.Int origin=null
|
||||
|
||||
@@ -84,27 +84,26 @@ FILE fqName:<root> fileName:/delegatedPropertyAccessorsWithAnnotations.kt
|
||||
PROPERTY name:test1 visibility:public modality:FINAL [delegated,val]
|
||||
annotations:
|
||||
A(x = 'test1.get')
|
||||
FIELD PROPERTY_BACKING_FIELD name:test1 type:IrErrorType visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test1> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.Int visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test1> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test1 visibility:public modality:FINAL [delegated,val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test1> (): IrErrorType declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test1 type:IrErrorType visibility:public [final,static] ' type=IrErrorType origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test1> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.Int visibility:public [final,static] ' type=kotlin.Int origin=null
|
||||
PROPERTY name:test2 visibility:public modality:FINAL [delegated,var]
|
||||
annotations:
|
||||
A(x = 'test2.get')
|
||||
A(x = 'test2.set')
|
||||
A(x = 'test2.set.param')
|
||||
FIELD PROPERTY_BACKING_FIELD name:test2 type:IrErrorType visibility:public [static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test2> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Int visibility:public [static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test2> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test2 visibility:public modality:FINAL [delegated,var]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test2> (): IrErrorType declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:IrErrorType visibility:public [static] ' type=IrErrorType origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<set-test2> visibility:public modality:FINAL <> (<set-?>:IrErrorType) returnType:kotlin.Unit
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test2> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Int visibility:public [static] ' type=kotlin.Int origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<set-test2> visibility:public modality:FINAL <> (<set-?>:kotlin.Int) returnType:kotlin.Unit
|
||||
correspondingProperty: PROPERTY name:test2 visibility:public modality:FINAL [delegated,var]
|
||||
VALUE_PARAMETER name:<set-?> index:0 type:IrErrorType
|
||||
VALUE_PARAMETER name:<set-?> index:0 type:kotlin.Int
|
||||
BLOCK_BODY
|
||||
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:IrErrorType visibility:public [static] ' type=kotlin.Unit origin=null
|
||||
value: GET_VAR '<set-?>: IrErrorType declared in <root>.<set-test2>' type=IrErrorType origin=null
|
||||
|
||||
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Int visibility:public [static] ' type=kotlin.Unit origin=null
|
||||
value: GET_VAR '<set-?>: kotlin.Int declared in <root>.<set-test2>' type=kotlin.Int origin=null
|
||||
|
||||
@@ -30,5 +30,4 @@ FILE fqName:<root> fileName:/localDelegatedPropertiesWithAnnotations.kt
|
||||
FUN name:foo visibility:public modality:FINAL <> (m:kotlin.collections.Map<kotlin.String, kotlin.Int>) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:m index:0 type:kotlin.collections.Map<kotlin.String, kotlin.Int>
|
||||
BLOCK_BODY
|
||||
VAR name:test type:IrErrorType [val]
|
||||
|
||||
VAR name:test type:kotlin.Int [val]
|
||||
|
||||
@@ -83,13 +83,13 @@ FILE fqName:<root> fileName:/classLevelProperties.kt
|
||||
correspondingProperty: PROPERTY name:test6 visibility:public modality:FINAL [val]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.C
|
||||
PROPERTY name:test7 visibility:public modality:FINAL [delegated,val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test7 type:IrErrorType visibility:public [final]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test7> visibility:public modality:FINAL <> ($this:<root>.C) returnType:IrErrorType
|
||||
FIELD PROPERTY_BACKING_FIELD name:test7 type:kotlin.Int visibility:public [final]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test7> visibility:public modality:FINAL <> ($this:<root>.C) returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test7 visibility:public modality:FINAL [delegated,val]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.C
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test7> (): IrErrorType declared in <root>.C'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test7 type:IrErrorType visibility:public [final] ' type=IrErrorType origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test7> (): kotlin.Int declared in <root>.C'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test7 type:kotlin.Int visibility:public [final] ' type=kotlin.Int origin=null
|
||||
receiver: GET_VAR '<this>: <root>.C declared in <root>.C.<get-test7>' type=<root>.C origin=null
|
||||
PROPERTY name:test8 visibility:public modality:FINAL [delegated,var]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test8 type:IrErrorType visibility:public
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
FILE fqName:<root> fileName:/delegatedProperties.kt
|
||||
PROPERTY name:test1 visibility:public modality:FINAL [delegated,val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test1 type:IrErrorType visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test1> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.Int visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test1> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test1 visibility:public modality:FINAL [delegated,val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test1> (): IrErrorType declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test1 type:IrErrorType visibility:public [final,static] ' type=IrErrorType origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test1> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.Int visibility:public [final,static] ' type=kotlin.Int origin=null
|
||||
CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.C
|
||||
CONSTRUCTOR visibility:public <> (map:kotlin.collections.MutableMap<kotlin.String, kotlin.Any>) returnType:<root>.C [primary]
|
||||
@@ -25,13 +25,13 @@ FILE fqName:<root> fileName:/delegatedProperties.kt
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:map type:kotlin.collections.MutableMap<kotlin.String, kotlin.Any> visibility:public [final] ' type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> origin=null
|
||||
receiver: GET_VAR '<this>: <root>.C declared in <root>.C.<get-map>' type=<root>.C origin=null
|
||||
PROPERTY name:test2 visibility:public modality:FINAL [delegated,val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test2 type:IrErrorType visibility:public [final]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test2> visibility:public modality:FINAL <> ($this:<root>.C) returnType:IrErrorType
|
||||
FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Int visibility:public [final]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test2> visibility:public modality:FINAL <> ($this:<root>.C) returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test2 visibility:public modality:FINAL [delegated,val]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.C
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test2> (): IrErrorType declared in <root>.C'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:IrErrorType visibility:public [final] ' type=IrErrorType origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test2> (): kotlin.Int declared in <root>.C'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Int visibility:public [final] ' type=kotlin.Int origin=null
|
||||
receiver: GET_VAR '<this>: <root>.C declared in <root>.C.<get-test2>' type=<root>.C origin=null
|
||||
PROPERTY name:test3 visibility:public modality:FINAL [delegated,var]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test3 type:IrErrorType visibility:public
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
FILE fqName:<root> fileName:/localDelegatedProperties.kt
|
||||
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
VAR name:x type:IrErrorType [val]
|
||||
ERROR_CALL 'Unresolved reference: <Ambiguity: println, [kotlin/io/println, kotlin/io/println, kotlin/io/println, kotlin/io/println, kotlin/io/println, kotlin/io/println, kotlin/io/println, kotlin/io/println, kotlin/io/println, kotlin/io/println]>#' type=IrErrorType
|
||||
GET_VAR 'val x: IrErrorType [val] declared in <root>.test1' type=IrErrorType origin=null
|
||||
VAR name:x type:kotlin.Int [val]
|
||||
CALL 'public final fun println (message: kotlin.Int): kotlin.Unit [inline] declared in kotlin.io' type=kotlin.Unit origin=null
|
||||
message: GET_VAR 'val x: kotlin.Int [val] declared in <root>.test1' type=kotlin.Int origin=null
|
||||
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
VAR name:x type:IrErrorType [var]
|
||||
|
||||
@@ -63,12 +63,12 @@ FILE fqName:<root> fileName:/packageLevelProperties.kt
|
||||
FUN name:<get-test6> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test6 visibility:public modality:FINAL [val]
|
||||
PROPERTY name:test7 visibility:public modality:FINAL [delegated,val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test7 type:IrErrorType visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test7> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
FIELD PROPERTY_BACKING_FIELD name:test7 type:kotlin.Int visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test7> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test7 visibility:public modality:FINAL [delegated,val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test7> (): IrErrorType declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test7 type:IrErrorType visibility:public [final,static] ' type=IrErrorType origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test7> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test7 type:kotlin.Int visibility:public [final,static] ' type=kotlin.Int origin=null
|
||||
PROPERTY name:test8 visibility:public modality:FINAL [delegated,var]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test8 type:IrErrorType visibility:public [static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test8> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
|
||||
@@ -51,17 +51,17 @@ FILE fqName:<root> fileName:/differentReceivers.kt
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-testO> (): IrErrorType declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:testO type:IrErrorType visibility:public [final,static] ' type=IrErrorType origin=null
|
||||
PROPERTY name:testK visibility:public modality:FINAL [delegated,val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:testK type:IrErrorType visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-testK> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
FIELD PROPERTY_BACKING_FIELD name:testK type:kotlin.String visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-testK> visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||
correspondingProperty: PROPERTY name:testK visibility:public modality:FINAL [delegated,val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-testK> (): IrErrorType declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:testK type:IrErrorType visibility:public [final,static] ' type=IrErrorType origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-testK> (): kotlin.String declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:testK type:kotlin.String visibility:public [final,static] ' type=kotlin.String origin=null
|
||||
PROPERTY name:testOK visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:testOK type:IrErrorType visibility:public [final,static]
|
||||
EXPRESSION_BODY
|
||||
ERROR_CALL 'Unresolved reference: <Ambiguity: plus, [kotlin/plus, kotlin/plus, kotlin/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/sequences/plus, kotlin/sequences/plus, kotlin/sequences/plus, kotlin/text/plus]>#' type=IrErrorType
|
||||
CALL 'public final fun <get-testK> (): IrErrorType declared in <root>' type=IrErrorType origin=null
|
||||
ERROR_CALL 'Unresolved reference: <Ambiguity: plus, [kotlin/plus, kotlin/plus, kotlin/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/sequences/plus, kotlin/text/plus]>#' type=IrErrorType
|
||||
CALL 'public final fun <get-testK> (): kotlin.String declared in <root>' type=kotlin.String origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-testOK> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
correspondingProperty: PROPERTY name:testOK visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
|
||||
@@ -46,10 +46,10 @@ FILE fqName:<root> fileName:/localDifferentReceivers.kt
|
||||
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||
BLOCK_BODY
|
||||
VAR name:testO type:IrErrorType [val]
|
||||
VAR name:testK type:IrErrorType [val]
|
||||
VAR name:testK type:kotlin.String [val]
|
||||
VAR name:testOK type:IrErrorType [val]
|
||||
ERROR_CALL 'Unresolved reference: <Ambiguity: plus, [kotlin/plus, kotlin/plus, kotlin/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/sequences/plus, kotlin/sequences/plus, kotlin/sequences/plus, kotlin/text/plus]>#' type=IrErrorType
|
||||
GET_VAR 'val testK: IrErrorType [val] declared in <root>.box' type=IrErrorType origin=null
|
||||
ERROR_CALL 'Unresolved reference: <Ambiguity: plus, [kotlin/plus, kotlin/plus, kotlin/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/collections/plus, kotlin/sequences/plus, kotlin/text/plus]>#' type=IrErrorType
|
||||
GET_VAR 'val testK: kotlin.String [val] declared in <root>.box' type=kotlin.String origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
|
||||
GET_VAR 'val testOK: IrErrorType [val] declared in <root>.box' type=IrErrorType origin=null
|
||||
|
||||
|
||||
@@ -24,6 +24,5 @@ FILE fqName:<root> fileName:/classReference.kt
|
||||
GET_OBJECT 'CLASS CLASS name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
|
||||
GET_CLASS type=kotlin.reflect.KClass<<root>.A>
|
||||
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.A' type=<root>.A origin=null
|
||||
ERROR_CALL 'No getter found for R|kotlin/jvm/java|' type=java.lang.Class<T of <uninitialized parent>>
|
||||
ERROR_CALL 'No getter found for R|kotlin/jvm/java|' type=java.lang.Class<T of <uninitialized parent>>
|
||||
|
||||
ERROR_CALL 'No getter found for R|kotlin/jvm/java|' type=java.lang.Class<<root>.A>
|
||||
ERROR_CALL 'No getter found for R|kotlin/jvm/java|' type=java.lang.Class<<root>.A>
|
||||
|
||||
@@ -8,7 +8,7 @@ FILE fqName:<root> fileName:/genericPropertyCall.kt
|
||||
PROPERTY name:test visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test type:IrErrorType visibility:public [final,static]
|
||||
EXPRESSION_BODY
|
||||
CALL 'public final fun <get-id> (): IrErrorType declared in <root>' type=IrErrorType origin=null
|
||||
ERROR_CALL 'Unresolved reference: R?C|/id|' type=IrErrorType
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
correspondingProperty: PROPERTY name:test visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
|
||||
@@ -65,19 +65,19 @@ FILE fqName:<root> fileName:/genericPropertyRef.kt
|
||||
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
PROPERTY name:additionalText visibility:public modality:FINAL [delegated,val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:additionalText type:IrErrorType visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-additionalText> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
FIELD PROPERTY_BACKING_FIELD name:additionalText type:kotlin.Int visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-additionalText> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:additionalText visibility:public modality:FINAL [delegated,val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-additionalText> (): IrErrorType declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:additionalText type:IrErrorType visibility:public [final,static] ' type=IrErrorType origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-additionalText> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:additionalText type:kotlin.Int visibility:public [final,static] ' type=kotlin.Int origin=null
|
||||
PROPERTY name:additionalValue visibility:public modality:FINAL [delegated,val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:additionalValue type:IrErrorType visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-additionalValue> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
FIELD PROPERTY_BACKING_FIELD name:additionalValue type:kotlin.Int visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-additionalValue> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:additionalValue visibility:public modality:FINAL [delegated,val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-additionalValue> (): IrErrorType declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:additionalValue type:IrErrorType visibility:public [final,static] ' type=IrErrorType origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-additionalValue> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:additionalValue type:kotlin.Int visibility:public [final,static] ' type=kotlin.Int origin=null
|
||||
CLASS CLASS name:DVal modality:FINAL visibility:public superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.DVal
|
||||
CONSTRUCTOR visibility:public <> (kmember:kotlin.Any) returnType:<root>.DVal [primary]
|
||||
@@ -161,12 +161,11 @@ FILE fqName:<root> fileName:/genericPropertyRef.kt
|
||||
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:value2 type:kotlin.Any? visibility:public [static] ' type=kotlin.Any? origin=null
|
||||
value: GET_VAR 'value: T of <uninitialized parent> declared in <root>.<set-bar>' type=T of <uninitialized parent> origin=null
|
||||
PROPERTY name:barRef visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:barRef type:T of <uninitialized parent> visibility:public [final,static]
|
||||
FIELD PROPERTY_BACKING_FIELD name:barRef type:kotlin.String.Companion visibility:public [final,static]
|
||||
EXPRESSION_BODY
|
||||
CALL 'public final fun <get-bar> (): T of <uninitialized parent> declared in <root>' type=T of <uninitialized parent> origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-barRef> visibility:public modality:FINAL <> () returnType:T of <uninitialized parent>
|
||||
CALL 'public final fun <get-bar> (): T of <uninitialized parent> declared in <root>' type=kotlin.String.Companion origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-barRef> visibility:public modality:FINAL <> () returnType:kotlin.String.Companion
|
||||
correspondingProperty: PROPERTY name:barRef visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-barRef> (): T of <uninitialized parent> declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:barRef type:T of <uninitialized parent> visibility:public [final,static] ' type=T of <uninitialized parent> origin=null
|
||||
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-barRef> (): kotlin.String.Companion declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:barRef type:kotlin.String.Companion visibility:public [final,static] ' type=kotlin.String.Companion origin=null
|
||||
|
||||
@@ -83,7 +83,7 @@ FILE fqName:<root> fileName:/multipleThisReferences.kt
|
||||
FIELD PROPERTY_BACKING_FIELD name:xx type:kotlin.String visibility:public [final]
|
||||
EXPRESSION_BODY
|
||||
CALL 'public final fun plus (other: kotlin.Any?): kotlin.String declared in kotlin' type=kotlin.String origin=null
|
||||
other: CALL 'public final fun <get-y> (): kotlin.Int declared in <root>.Host' type=kotlin.Int origin=null
|
||||
other: GET_VAR 'y: kotlin.Int declared in <root>.Host.<init>' type=kotlin.Int origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xx> visibility:public modality:FINAL <> ($this:<root>.Host.test.<no name provided>) returnType:kotlin.String
|
||||
correspondingProperty: PROPERTY name:xx visibility:public modality:FINAL [val]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Host.test.<no name provided>
|
||||
|
||||
@@ -22,5 +22,4 @@ FILE fqName:<root> fileName:/objectClassReference.kt
|
||||
BLOCK_BODY
|
||||
GET_CLASS type=kotlin.reflect.KClass<<root>.A>
|
||||
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
|
||||
ERROR_CALL 'No getter found for R|kotlin/jvm/java|' type=java.lang.Class<T of <uninitialized parent>>
|
||||
|
||||
ERROR_CALL 'No getter found for R|kotlin/jvm/java|' type=java.lang.Class<<root>.A>
|
||||
|
||||
@@ -181,43 +181,43 @@ FILE fqName:<root> fileName:/propertyReferences.kt
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test_varWithAccessors> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_varWithAccessors type:kotlin.Int visibility:public [final,static] ' type=kotlin.Int origin=null
|
||||
PROPERTY name:delegatedVal visibility:public modality:FINAL [delegated,val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:delegatedVal type:IrErrorType visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-delegatedVal> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
FIELD PROPERTY_BACKING_FIELD name:delegatedVal type:kotlin.Int visibility:public [final,static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-delegatedVal> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:delegatedVal visibility:public modality:FINAL [delegated,val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-delegatedVal> (): IrErrorType declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:delegatedVal type:IrErrorType visibility:public [final,static] ' type=IrErrorType origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-delegatedVal> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:delegatedVal type:kotlin.Int visibility:public [final,static] ' type=kotlin.Int origin=null
|
||||
PROPERTY name:test_delegatedVal visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test_delegatedVal type:IrErrorType visibility:public [final,static]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test_delegatedVal type:kotlin.Int visibility:public [final,static]
|
||||
EXPRESSION_BODY
|
||||
CALL 'public final fun <get-delegatedVal> (): IrErrorType declared in <root>' type=IrErrorType origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_delegatedVal> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
CALL 'public final fun <get-delegatedVal> (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_delegatedVal> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test_delegatedVal visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test_delegatedVal> (): IrErrorType declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_delegatedVal type:IrErrorType visibility:public [final,static] ' type=IrErrorType origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test_delegatedVal> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_delegatedVal type:kotlin.Int visibility:public [final,static] ' type=kotlin.Int origin=null
|
||||
PROPERTY name:delegatedVar visibility:public modality:FINAL [delegated,var]
|
||||
FIELD PROPERTY_BACKING_FIELD name:delegatedVar type:IrErrorType visibility:public [static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-delegatedVar> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
FIELD PROPERTY_BACKING_FIELD name:delegatedVar type:kotlin.Int visibility:public [static]
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-delegatedVar> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:delegatedVar visibility:public modality:FINAL [delegated,var]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-delegatedVar> (): IrErrorType declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:delegatedVar type:IrErrorType visibility:public [static] ' type=IrErrorType origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<set-delegatedVar> visibility:public modality:FINAL <> (<set-?>:IrErrorType) returnType:kotlin.Unit
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-delegatedVar> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:delegatedVar type:kotlin.Int visibility:public [static] ' type=kotlin.Int origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<set-delegatedVar> visibility:public modality:FINAL <> (<set-?>:kotlin.Int) returnType:kotlin.Unit
|
||||
correspondingProperty: PROPERTY name:delegatedVar visibility:public modality:FINAL [delegated,var]
|
||||
VALUE_PARAMETER name:<set-?> index:0 type:IrErrorType
|
||||
VALUE_PARAMETER name:<set-?> index:0 type:kotlin.Int
|
||||
BLOCK_BODY
|
||||
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:delegatedVar type:IrErrorType visibility:public [static] ' type=kotlin.Unit origin=null
|
||||
value: GET_VAR '<set-?>: IrErrorType declared in <root>.<set-delegatedVar>' type=IrErrorType origin=null
|
||||
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:delegatedVar type:kotlin.Int visibility:public [static] ' type=kotlin.Unit origin=null
|
||||
value: GET_VAR '<set-?>: kotlin.Int declared in <root>.<set-delegatedVar>' type=kotlin.Int origin=null
|
||||
PROPERTY name:test_delegatedVar visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test_delegatedVar type:IrErrorType visibility:public [final,static]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test_delegatedVar type:kotlin.Int visibility:public [final,static]
|
||||
EXPRESSION_BODY
|
||||
CALL 'public final fun <get-delegatedVar> (): IrErrorType declared in <root>' type=IrErrorType origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_delegatedVar> visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
CALL 'public final fun <get-delegatedVar> (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_delegatedVar> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:test_delegatedVar visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test_delegatedVar> (): IrErrorType declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_delegatedVar type:IrErrorType visibility:public [final,static] ' type=IrErrorType origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test_delegatedVar> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_delegatedVar type:kotlin.Int visibility:public [final,static] ' type=kotlin.Int origin=null
|
||||
PROPERTY name:constVal visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:constVal type:kotlin.Int visibility:public [final,static]
|
||||
EXPRESSION_BODY
|
||||
|
||||
@@ -208,7 +208,7 @@ FILE fqName:<root> fileName:/useImportedMember.kt
|
||||
BRANCH
|
||||
if: CALL 'public final fun not (): kotlin.Boolean declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
|
||||
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
|
||||
arg0: CALL 'public final fun <get-g2> (): T of <uninitialized parent> declared in <root>.C' type=T of <uninitialized parent> origin=null
|
||||
arg0: CALL 'public final fun <get-g2> (): T of <uninitialized parent> declared in <root>.C' type=kotlin.String origin=null
|
||||
$this: CONST String type=kotlin.String value="8"
|
||||
arg1: CONST String type=kotlin.String value="8"
|
||||
then: RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
|
||||
@@ -225,7 +225,7 @@ FILE fqName:<root> fileName:/useImportedMember.kt
|
||||
BRANCH
|
||||
if: CALL 'public final fun not (): kotlin.Boolean declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
|
||||
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
|
||||
arg0: CALL 'public final fun <get-fromClass> (): T of <uninitialized parent> declared in <root>.BaseClass' type=T of <uninitialized parent> origin=null
|
||||
arg0: CALL 'public final fun <get-fromClass> (): T of <uninitialized parent> declared in <root>.BaseClass' type=kotlin.String origin=null
|
||||
$this: CONST String type=kotlin.String value="10"
|
||||
arg1: CONST String type=kotlin.String value="10"
|
||||
then: RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
|
||||
|
||||
@@ -14,7 +14,7 @@ FILE fqName:<root> fileName:/variableAsFunctionCallWithGenerics.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun testGeneric1 (x: kotlin.String): T of <uninitialized parent> declared in <root>'
|
||||
CALL 'public abstract fun invoke (): T of <uninitialized parent> declared in kotlin.Function0' type=T of <uninitialized parent> origin=null
|
||||
$this: CALL 'public final fun <get-gk> (): kotlin.Function0<T of <uninitialized parent>> declared in <root>' type=kotlin.Function0<T of <uninitialized parent>> origin=null
|
||||
$this: ERROR_CALL 'Unresolved reference: R?C|/gk|' type=kotlin.Function0<T of <uninitialized parent>>
|
||||
PROPERTY name:kt26531Val visibility:public modality:FINAL [val]
|
||||
FUN name:<get-kt26531Val> visibility:public modality:FINAL <> () returnType:kotlin.Function0<T of <uninitialized parent>>
|
||||
correspondingProperty: PROPERTY name:kt26531Val visibility:public modality:FINAL [val]
|
||||
@@ -30,4 +30,4 @@ FILE fqName:<root> fileName:/variableAsFunctionCallWithGenerics.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun kt26531 (): T of <uninitialized parent> declared in <root>'
|
||||
CALL 'public abstract fun invoke (): T of <uninitialized parent> declared in kotlin.Function0' type=T of <uninitialized parent> origin=null
|
||||
$this: CALL 'public final fun <get-kt26531Val> (): kotlin.Function0<T of <uninitialized parent>> declared in <root>' type=kotlin.Function0<T of <uninitialized parent>> origin=null
|
||||
$this: ERROR_CALL 'Unresolved reference: R?C|/kt26531Val|' type=kotlin.Function0<T of <uninitialized parent>>
|
||||
|
||||
@@ -9,8 +9,8 @@ FILE fqName:<root> fileName:/builtinMap.kt
|
||||
BRANCH
|
||||
if: CALL 'public abstract fun isEmpty (): kotlin.Boolean declared in kotlin.collections.Map' type=kotlin.Boolean origin=null
|
||||
$this: ERROR_CALL 'Unresolved reference: this#' type=kotlin.collections.Map<out K1 of <root>.plus, V1 of <root>.plus>
|
||||
then: ERROR_CALL 'Unresolved reference: <Ambiguity: mapOf, [kotlin/collections/mapOf, kotlin/collections/mapOf]>#' type=IrErrorType
|
||||
GET_VAR 'pair: kotlin.Pair<K1 of <root>.plus, V1 of <root>.plus> declared in <root>.plus' type=kotlin.Pair<K1 of <root>.plus, V1 of <root>.plus> origin=null
|
||||
then: CALL 'public final fun mapOf (pair: kotlin.Pair<K of <uninitialized parent>, V of <uninitialized parent>>): kotlin.collections.Map<K of <uninitialized parent>, V of <uninitialized parent>> declared in kotlin.collections' type=kotlin.collections.Map<K1 of <root>.plus, V1 of <root>.plus> origin=null
|
||||
pair: GET_VAR 'pair: kotlin.Pair<K1 of <root>.plus, V1 of <root>.plus> declared in <root>.plus' type=kotlin.Pair<K1 of <root>.plus, V1 of <root>.plus> origin=null
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: CALL 'public final fun apply (block: kotlin.Function1<T of <uninitialized parent>, kotlin.Unit>): T of <uninitialized parent> [inline] declared in kotlin' type=java.util.LinkedHashMap<K1 of <root>.plus, V1 of <root>.plus> origin=null
|
||||
|
||||
@@ -8,14 +8,21 @@ import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.concurrent.tcReg
|
||||
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirResolveStage
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirStagesTransformerFactory
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import java.io.PrintStream
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.math.max
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.system.measureNanoTime
|
||||
@@ -28,18 +35,32 @@ fun checkFirProvidersConsistency(firFiles: List<FirFile>) {
|
||||
}
|
||||
}
|
||||
|
||||
private data class FailureInfo(val transformer: KClass<*>, val throwable: Throwable, val file: String)
|
||||
private data class FailureInfo(val stageClass: KClass<*>, val throwable: Throwable, val file: String)
|
||||
private data class ErrorTypeReport(val report: String, var count: Int = 0)
|
||||
|
||||
|
||||
private val threadLocalTransformer = ThreadLocal<FirTransformer<Nothing?>>()
|
||||
|
||||
|
||||
class FirResolveBench(val withProgress: Boolean) {
|
||||
|
||||
val timePerTransformer = mutableMapOf<KClass<*>, Long>()
|
||||
val counterPerTransformer = mutableMapOf<KClass<*>, Long>()
|
||||
val summaryTimePerStage = mutableMapOf<KClass<*>, Long>()
|
||||
val realTimePerStage = mutableMapOf<KClass<*>, Long>()
|
||||
var resolvedTypes = 0
|
||||
var errorTypes = 0
|
||||
var unresolvedTypes = 0
|
||||
var errorFunctionCallTypes = 0
|
||||
var errorQualifiedAccessTypes = 0
|
||||
var implicitTypes = 0
|
||||
var fileCount = 0
|
||||
var totalLines = 0
|
||||
|
||||
var parallelThreads = Runtime.getRuntime().availableProcessors()
|
||||
|
||||
var isParallel = true
|
||||
|
||||
val singleThreadPool = Executors.newSingleThreadExecutor()
|
||||
val pool by lazy { Executors.newFixedThreadPool(parallelThreads) }
|
||||
|
||||
|
||||
private val fails = mutableListOf<FailureInfo>()
|
||||
@@ -48,39 +69,132 @@ class FirResolveBench(val withProgress: Boolean) {
|
||||
private val errorTypesReports = mutableMapOf<String, ErrorTypeReport>()
|
||||
|
||||
fun countBuilder(builder: RawFirBuilder, time: Long) {
|
||||
timePerTransformer.merge(builder::class, time) { a, b -> a + b }
|
||||
counterPerTransformer.merge(builder::class, 1) { a, b -> a + b }
|
||||
summaryTimePerStage.merge(builder::class, time) { a, b -> a + b }
|
||||
realTimePerStage.merge(builder::class, time) { a, b -> a + b }
|
||||
}
|
||||
|
||||
private fun runBuilder(builder: RawFirBuilder, ktFiles: List<KtFile>): List<FirFile> {
|
||||
return ktFiles.map { file ->
|
||||
var firFile: FirFile? = null
|
||||
val time = measureNanoTime {
|
||||
firFile = builder.buildFirFile(file)
|
||||
(builder.session.service<FirProvider>() as FirProviderImpl).recordFile(firFile!!)
|
||||
}
|
||||
summaryTimePerStage.merge(builder::class, time) { a, b -> a + b }
|
||||
firFile!!
|
||||
}
|
||||
}
|
||||
|
||||
private fun runBuilderConcurrently(builder: RawFirBuilder, ktFiles: List<KtFile>): List<FirFile> {
|
||||
return ktFiles.map { file ->
|
||||
pool.submit(Callable {
|
||||
var firFile: FirFile? = null
|
||||
val time = measureNanoTime {
|
||||
firFile = builder.buildFirFile(file)
|
||||
(builder.session.service<FirProvider>() as FirProviderImpl).recordFile(firFile!!)
|
||||
}
|
||||
summaryTimePerStage.merge(builder::class, time) { a, b -> a + b }
|
||||
firFile!!
|
||||
})
|
||||
}.map { it.get() }
|
||||
}
|
||||
|
||||
fun buildFiles(
|
||||
builder: RawFirBuilder,
|
||||
ktFiles: List<KtFile>
|
||||
): List<FirFile> {
|
||||
val (result, time) = measureNanoTimeWithResult {
|
||||
if (isParallel)
|
||||
runBuilderConcurrently(builder, ktFiles)
|
||||
else
|
||||
runBuilder(builder, ktFiles)
|
||||
}
|
||||
realTimePerStage.merge(builder::class, time) { a, b -> a + b }
|
||||
ktFiles.forEach {
|
||||
totalLines += it.text.lines().count()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
private fun runStage(stage: FirResolveStage, firFiles: List<FirFile>) {
|
||||
val firFileSequence = if (withProgress) firFiles.progress(" ~ ") else firFiles.asSequence()
|
||||
val transformer = stage.createTransformer()
|
||||
for (firFile in firFileSequence) {
|
||||
var fail = false
|
||||
val time = measureNanoTime {
|
||||
try {
|
||||
transformer.transformFile(firFile, null)
|
||||
} catch (e: Throwable) {
|
||||
val ktFile = firFile.psi as KtFile
|
||||
println("Fail in file: ${ktFile.virtualFilePath}")
|
||||
fail = true
|
||||
fails += FailureInfo(stage::class, e, ktFile.virtualFilePath)
|
||||
//println(ktFile.text)
|
||||
//throw e
|
||||
}
|
||||
}
|
||||
if (!fail) {
|
||||
summaryTimePerStage.merge(stage::class, time) { a, b -> a + b }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun runStageConcurrently(stage: FirResolveStage, firFiles: List<FirFile>) {
|
||||
require(stage.isParallel)
|
||||
val transformerLocal = object : ThreadLocal<FirTransformer<Nothing?>>() {
|
||||
override fun initialValue(): FirTransformer<Nothing?> {
|
||||
return stage.createTransformer()
|
||||
}
|
||||
}
|
||||
val tasks = (firFiles).shuffled().map { firFile ->
|
||||
firFile to pool.submit {
|
||||
var fail = false
|
||||
val time = measureNanoTime {
|
||||
try {
|
||||
transformerLocal.get().transformFile(firFile, null)
|
||||
} catch (e: Throwable) {
|
||||
val ktFile = firFile.psi as KtFile
|
||||
println("Fail in file: ${ktFile.virtualFilePath}")
|
||||
fail = true
|
||||
fails += FailureInfo(stage::class, e, ktFile.virtualFilePath)
|
||||
//println(ktFile.text)
|
||||
//throw e
|
||||
}
|
||||
}
|
||||
if (!fail) {
|
||||
summaryTimePerStage.merge(stage::class, time) { a, b -> a + b }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
val tasksSequence = if (withProgress) tasks.progress(" ~ ") else tasks.asSequence()
|
||||
tasksSequence.forEach { (_, future) ->
|
||||
future.get()
|
||||
}
|
||||
}
|
||||
|
||||
fun processFiles(
|
||||
firFiles: List<FirFile>,
|
||||
transformers: List<FirTransformer<Nothing?>>
|
||||
factory: FirStagesTransformerFactory
|
||||
) {
|
||||
fileCount += firFiles.size
|
||||
try {
|
||||
for ((stage, transformer) in transformers.withIndex()) {
|
||||
println("Starting stage #$stage. $transformer")
|
||||
val firFileSequence = if (withProgress) firFiles.progress(" ~ ") else firFiles.asSequence()
|
||||
for (firFile in firFileSequence) {
|
||||
var fail = false
|
||||
val time = measureNanoTime {
|
||||
try {
|
||||
transformer.transformFile(firFile, null)
|
||||
} catch (e: Throwable) {
|
||||
val ktFile = firFile.psi as KtFile
|
||||
println("Fail in file: ${ktFile.virtualFilePath}")
|
||||
fail = true
|
||||
fails += FailureInfo(transformer::class, e, ktFile.virtualFilePath)
|
||||
//println(ktFile.text)
|
||||
//throw e
|
||||
}
|
||||
}
|
||||
if (!fail) {
|
||||
timePerTransformer.merge(transformer::class, time) { a, b -> a + b }
|
||||
counterPerTransformer.merge(transformer::class, 1) { a, b -> a + b }
|
||||
}
|
||||
//totalLength += StringBuilder().apply { FirRenderer(this).visitFile(firFile) }.length
|
||||
for ((stageNum, stage) in factory.resolveStages.withIndex()) {
|
||||
val usedThreads = if (stage.isParallel && isParallel) parallelThreads else 1
|
||||
println("Starting stage #$stageNum, $stage, isParallel = ${stage.isParallel}, using threads: $usedThreads")
|
||||
|
||||
val realTime = measureNanoTime {
|
||||
|
||||
if (stage.isParallel && isParallel)
|
||||
runStageConcurrently(stage, firFiles)
|
||||
else
|
||||
runStage(stage, firFiles)
|
||||
}
|
||||
|
||||
|
||||
realTimePerStage[stage::class] = realTime
|
||||
//totalLength += StringBuilder().apply { FirRenderer(this).visitFile(firFile) }.length
|
||||
checkFirProvidersConsistency(firFiles)
|
||||
}
|
||||
|
||||
@@ -113,6 +227,30 @@ class FirResolveBench(val withProgress: Boolean) {
|
||||
element.acceptChildren(this)
|
||||
}
|
||||
|
||||
override fun visitFunctionCall(functionCall: FirFunctionCall) {
|
||||
val typeRef = functionCall.typeRef
|
||||
if (typeRef is FirResolvedTypeRef) {
|
||||
val type = typeRef.type
|
||||
if (type is ConeKotlinErrorType) {
|
||||
errorFunctionCallTypes++
|
||||
}
|
||||
}
|
||||
|
||||
super.visitFunctionCall(functionCall)
|
||||
}
|
||||
|
||||
override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression) {
|
||||
val typeRef = qualifiedAccessExpression.typeRef
|
||||
if (typeRef is FirResolvedTypeRef) {
|
||||
val type = typeRef.type
|
||||
if (type is ConeKotlinErrorType) {
|
||||
errorQualifiedAccessTypes++
|
||||
}
|
||||
}
|
||||
|
||||
super.visitQualifiedAccessExpression(qualifiedAccessExpression)
|
||||
}
|
||||
|
||||
override fun visitTypeRef(typeRef: FirTypeRef) {
|
||||
unresolvedTypes++
|
||||
|
||||
@@ -177,30 +315,35 @@ class FirResolveBench(val withProgress: Boolean) {
|
||||
val goodTypes = resolvedTypes - errorTypes - implicitTypes
|
||||
stream.println("CORRECTLY RESOLVED TYPES: $goodTypes (${goodTypes percentOf resolvedTypes} of resolved)")
|
||||
stream.println("ERRONEOUSLY RESOLVED TYPES: $errorTypes (${errorTypes percentOf resolvedTypes} of resolved)")
|
||||
stream.println(" - unresolved calls: $errorFunctionCallTypes")
|
||||
stream.println(" - unresolved q.accesses: $errorQualifiedAccessTypes")
|
||||
stream.println("ERRONEOUSLY RESOLVED IMPLICIT TYPES: $implicitTypes (${implicitTypes percentOf resolvedTypes} of resolved)")
|
||||
stream.println("UNIQUE ERROR TYPES: ${errorTypesReports.size}")
|
||||
for (c in tcReg) {
|
||||
stream.println(c.stats())
|
||||
}
|
||||
|
||||
|
||||
var totalTime = 0L
|
||||
var totalFiles = 0L
|
||||
var totalSummaryTime = 0L
|
||||
|
||||
timePerTransformer.forEach { (transformer, time) ->
|
||||
val counter = counterPerTransformer[transformer]!!
|
||||
stream.println("${transformer.simpleName}, TIME: ${time * 1e-6} ms, TIME PER FILE: ${(time / counter) * 1e-6} ms, FILES: OK/E/T $counter/${fileCount - counter}/$fileCount")
|
||||
|
||||
realTimePerStage.forEach { (stageClass, time) ->
|
||||
val counter = fileCount - fails.count { it.stageClass == stageClass }
|
||||
val summaryTime = summaryTimePerStage[stageClass]!!
|
||||
stream.println("${stageClass.simpleName}, TIME: ${time * 1e-6} ms, TIME/FILE: ${(time / counter) * 1e-6} ms, S-TIME/TIME: ${summaryTime / (time * 1.0)}, S-TIME: ${summaryTime * 1e-6} ms, S-TIME/FILE: ${summaryTime / counter * 1e-6} ms, FILES: OK/E/T $counter/${fileCount - counter}/$fileCount")
|
||||
totalTime += time
|
||||
totalFiles += counter
|
||||
totalSummaryTime += summaryTime
|
||||
}
|
||||
|
||||
if (counterPerTransformer.keys.size > 0) {
|
||||
totalFiles /= counterPerTransformer.keys.size
|
||||
stream.println("Total, TIME: ${totalTime * 1e-6} ms, TIME PER FILE: ${(totalTime / totalFiles) * 1e-6} ms")
|
||||
}
|
||||
stream.println("Total, TIME: ${totalTime * 1e-6} ms, TIME PER FILE: ${(totalTime / fileCount) * 1e-6} ms, S-TIME/TIME: ${totalSummaryTime / (totalTime * 1.0)}, S-TIME: ${totalSummaryTime * 1e-6} ms, S-TIME/FILE: ${totalSummaryTime / fileCount * 1e-6} ms")
|
||||
stream.println(" ${totalLines / (totalTime * 1e-9)} Line/s")
|
||||
}
|
||||
}
|
||||
|
||||
fun doFirResolveTestBench(
|
||||
firFiles: List<FirFile>,
|
||||
transformers: List<FirTransformer<Nothing?>>,
|
||||
factory: FirStagesTransformerFactory,
|
||||
gc: Boolean = true,
|
||||
withProgress: Boolean = false
|
||||
) {
|
||||
@@ -210,7 +353,8 @@ fun doFirResolveTestBench(
|
||||
}
|
||||
|
||||
val bench = FirResolveBench(withProgress)
|
||||
bench.processFiles(firFiles, transformers)
|
||||
bench.parallelThreads = 1
|
||||
bench.processFiles(firFiles, factory)
|
||||
bench.report(System.out)
|
||||
bench.throwFailure()
|
||||
}
|
||||
@@ -243,4 +387,12 @@ fun <T> Collection<T>.progress(step: Double = 0.1, computeLabel: (T) -> String):
|
||||
}
|
||||
progress++
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <T> measureNanoTimeWithResult(crossinline block: () -> T): Pair<T, Long> {
|
||||
var result: Any? = null
|
||||
val time = measureNanoTime {
|
||||
result = block()
|
||||
}
|
||||
return result as T to time
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* 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.idea.perf
|
||||
|
||||
import com.intellij.ide.impl.ProjectUtil
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.ex.ApplicationEx
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager
|
||||
import com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl
|
||||
import com.intellij.openapi.projectRoots.ProjectJdkTable
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.search.FileTypeIndex
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.testFramework.LightPlatformTestCase
|
||||
import com.intellij.testFramework.ModuleTestCase
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.doFirResolveTestBench
|
||||
import org.jetbrains.kotlin.fir.java.FirJavaModuleBasedSession
|
||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||
import org.jetbrains.kotlin.fir.progress
|
||||
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.service
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.caches.project.*
|
||||
import org.jetbrains.kotlin.idea.fir.IdeFirDependenciesSymbolProvider
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.io.File
|
||||
import kotlin.test.Ignore
|
||||
|
||||
@Ignore(value = "[Simon Ogorodnik] turned off as it is suppose to be run manually")
|
||||
class FirTotalKotlinResolveInIdeTest : ModuleTestCase() {
|
||||
private val projectRootFile = File(".")
|
||||
|
||||
override fun setUpProject() {
|
||||
(ApplicationManager.getApplication() as ApplicationEx).doNotSave()
|
||||
myProject = ProjectUtil.openOrImport(projectRootFile.path, null, false)
|
||||
LightPlatformTestCase.clearUncommittedDocuments(this.project)
|
||||
this.runStartupActivities()
|
||||
(FileTypeManager.getInstance() as FileTypeManagerImpl).drainReDetectQueue()
|
||||
}
|
||||
|
||||
private lateinit var sessionProvider: FirProjectSessionProvider
|
||||
|
||||
private fun IdeaModuleInfo.createSession(): FirSession {
|
||||
val moduleInfo = this
|
||||
|
||||
return FirJavaModuleBasedSession(
|
||||
moduleInfo, sessionProvider, moduleInfo.contentScope(),
|
||||
IdeFirDependenciesSymbolProvider(moduleInfo as ModuleSourceInfo, project, sessionProvider)
|
||||
)
|
||||
}
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
sessionProvider = FirProjectSessionProvider(project)
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
val jdkTable = ProjectJdkTable.getInstance()
|
||||
runWriteAction {
|
||||
for (sdk in jdkTable.allJdks) {
|
||||
jdkTable.removeJdk(sdk)
|
||||
}
|
||||
}
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
fun testTotalKotlin() {
|
||||
val psiManager = PsiManager.getInstance(project)
|
||||
val files = FileTypeIndex.getFiles(KotlinFileType.INSTANCE, GlobalSearchScope.projectScope(project))
|
||||
val firFiles = mutableListOf<FirFile>()
|
||||
val sessionPerModule = mutableMapOf<ModuleInfo, FirSession>()
|
||||
|
||||
println("Got vfiles: ${files.size}")
|
||||
files.mapNotNull {
|
||||
val file = psiManager.findFile(it) as? KtFile ?: return@mapNotNull null
|
||||
val moduleInfo = file.getNullableModuleInfo() as? ModuleSourceInfo ?: return@mapNotNull null
|
||||
file to moduleInfo
|
||||
}.progress("Loading FIR").forEach { (file, moduleInfo) ->
|
||||
|
||||
val session = sessionPerModule.getOrPut(moduleInfo) {
|
||||
moduleInfo.createSession()
|
||||
}
|
||||
val builder = RawFirBuilder(session, stubMode = true)
|
||||
|
||||
try {
|
||||
val firFile = builder.buildFirFile(file)
|
||||
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
|
||||
firFiles += firFile
|
||||
} catch (e: Exception) {
|
||||
System.err.println("Error building fir for $file")
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
println("Raw fir up, files: ${firFiles.size}")
|
||||
doFirResolveTestBench(firFiles, FirTotalResolveTransformer().transformers, withProgress = true)
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirStagesTransformerFactory
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
|
||||
import org.jetbrains.kotlin.fir.service
|
||||
@@ -121,7 +121,7 @@ abstract class AbstractFirMultiModuleResolveTest : AbstractMultiModuleTest() {
|
||||
return result!!
|
||||
}
|
||||
|
||||
val transformer = FirTotalResolveTransformer()
|
||||
val transformer = FirStagesTransformerFactory(sessions)
|
||||
transformer.processFiles(firFiles)
|
||||
for (file in firFiles) {
|
||||
val firFileDump = StringBuilder().also { file.accept(FirRenderer(it), null) }.toString()
|
||||
|
||||
Reference in New Issue
Block a user