mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-17 00:21:29 +00:00
Compare commits
41 Commits
native-syn
...
FIR/invoke
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75ae076c61 | ||
|
|
420f5c0c12 | ||
|
|
735c2a1c92 | ||
|
|
7c617718a7 | ||
|
|
70a852f072 | ||
|
|
bce20ea3e1 | ||
|
|
d90749709e | ||
|
|
106ab769dd | ||
|
|
02c90d0690 | ||
|
|
0458f94cdc | ||
|
|
6888499081 | ||
|
|
ee6da3964a | ||
|
|
b312edad09 | ||
|
|
e73dd86472 | ||
|
|
d046c4f94d | ||
|
|
bff89230a5 | ||
|
|
b4d4f91255 | ||
|
|
81faf01672 | ||
|
|
3eebe73291 | ||
|
|
fa0dcddff8 | ||
|
|
58d3178bea | ||
|
|
997d73b1ce | ||
|
|
d72f04455b | ||
|
|
b63d9b03af | ||
|
|
4fdff4fbd3 | ||
|
|
f4d00b6574 | ||
|
|
df1460c93b | ||
|
|
309dd87567 | ||
|
|
79b713cc75 | ||
|
|
1cf60b8c37 | ||
|
|
d0358a57c0 | ||
|
|
332cdbf5a7 | ||
|
|
bdfa82b010 | ||
|
|
8b4c1f6b57 | ||
|
|
eed465ae03 | ||
|
|
809b8a95b7 | ||
|
|
70ef431227 | ||
|
|
c3eea13f78 | ||
|
|
bdf7f65f13 | ||
|
|
2e1a8741cd | ||
|
|
fee05d20fe |
@@ -107,7 +107,7 @@ abstract class ConeTypeParameterType : ConeLookupTagBasedType() {
|
||||
|
||||
|
||||
|
||||
class ConeFlexibleType(val lowerBound: ConeKotlinType, val upperBound: ConeKotlinType) : ConeKotlinType(),
|
||||
data class ConeFlexibleType(val lowerBound: ConeKotlinType, val upperBound: ConeKotlinType) : ConeKotlinType(),
|
||||
FlexibleTypeMarker {
|
||||
|
||||
init {
|
||||
|
||||
@@ -22,9 +22,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirUncheckedNotNullCastImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.directExpansionType
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.withNullability
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirTypePlaceholderProjection
|
||||
@@ -851,7 +849,7 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
|
||||
|
||||
withIdentLevel {
|
||||
generate(property.getter)
|
||||
generate(property.setter)
|
||||
property.setter?.let { generate(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1167,6 +1165,20 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
|
||||
keyword("class")
|
||||
}
|
||||
|
||||
private fun FlowContent.generate(resolvedQualifier: FirResolvedQualifier) {
|
||||
resolved {
|
||||
val symbolProvider = session.service<FirSymbolProvider>()
|
||||
val classId = resolvedQualifier.classId
|
||||
if (classId != null) {
|
||||
symbolRef(symbolProvider.getClassLikeSymbolByFqName(classId)) {
|
||||
fqn(classId.relativeClassName)
|
||||
}
|
||||
} else {
|
||||
fqn(resolvedQualifier.packageFqName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FlowContent.generate(expression: FirExpression) {
|
||||
exprType(expression.typeRef) {
|
||||
when (expression) {
|
||||
@@ -1195,6 +1207,7 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
|
||||
is FirFunctionCall -> {
|
||||
generate(expression)
|
||||
}
|
||||
is FirResolvedQualifier -> generate(expression)
|
||||
is FirQualifiedAccessExpression -> generate(expression)
|
||||
is FirNamedArgumentExpression -> {
|
||||
simpleName(expression.name)
|
||||
|
||||
@@ -494,7 +494,7 @@ internal class Fir2IrVisitor(
|
||||
}
|
||||
getter = property.getter.accept(this@Fir2IrVisitor, type) as IrSimpleFunction
|
||||
if (property.isVar) {
|
||||
setter = property.setter.accept(this@Fir2IrVisitor, type) as IrSimpleFunction
|
||||
setter = property.setter!!.accept(this@Fir2IrVisitor, type) as IrSimpleFunction
|
||||
}
|
||||
property.annotations.forEach {
|
||||
annotations += it.accept(this@Fir2IrVisitor, null) as IrConstructorCall
|
||||
|
||||
@@ -7,6 +7,9 @@ package org.jetbrains.kotlin.fir.java
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||
@@ -206,14 +209,14 @@ class JavaSymbolProvider(
|
||||
}
|
||||
declarations += firJavaMethod
|
||||
}
|
||||
for (javaConstructor in javaClass.constructors) {
|
||||
val constructorId = CallableId(classId.packageFqName, classId.relativeClassName, classId.shortClassName)
|
||||
val javaClassDeclaredConstructors = javaClass.constructors
|
||||
val constructorId = CallableId(classId.packageFqName, classId.relativeClassName, classId.shortClassName)
|
||||
|
||||
fun addJavaConstructor(visibility: Visibility = Visibilities.PUBLIC): FirJavaConstructor {
|
||||
val constructorSymbol = FirFunctionSymbol(constructorId)
|
||||
val classTypeParameters = javaClass.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
val constructorTypeParameters = javaConstructor.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
val typeParameters = classTypeParameters + constructorTypeParameters
|
||||
val firJavaConstructor = FirJavaConstructor(
|
||||
this@JavaSymbolProvider.session, constructorSymbol, javaConstructor.visibility,
|
||||
this@JavaSymbolProvider.session, constructorSymbol, visibility,
|
||||
FirResolvedTypeRefImpl(
|
||||
this@JavaSymbolProvider.session, null,
|
||||
firSymbol.constructType(
|
||||
@@ -221,7 +224,18 @@ class JavaSymbolProvider(
|
||||
)
|
||||
)
|
||||
).apply {
|
||||
this.typeParameters += typeParameters
|
||||
this.typeParameters += classTypeParameters
|
||||
}
|
||||
declarations += firJavaConstructor
|
||||
return firJavaConstructor
|
||||
}
|
||||
|
||||
if (javaClassDeclaredConstructors.isEmpty() && javaClass.classKind == ClassKind.CLASS) {
|
||||
addJavaConstructor()
|
||||
}
|
||||
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(
|
||||
@@ -229,7 +243,6 @@ class JavaSymbolProvider(
|
||||
)
|
||||
}
|
||||
}
|
||||
declarations += firJavaConstructor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaValueParameter
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.readOnlyToMutable
|
||||
import org.jetbrains.kotlin.fir.java.types.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
@@ -144,7 +145,8 @@ internal fun JavaClassifierType.toConeKotlinTypeWithNullability(
|
||||
return when (val classifier = classifier) {
|
||||
is JavaClass -> {
|
||||
//val classId = classifier.classId!!
|
||||
val classId = JavaToKotlinClassMap.mapJavaToKotlin(classifier.fqName!!) ?: classifier.classId!!
|
||||
var classId = JavaToKotlinClassMap.mapJavaToKotlin(classifier.fqName!!) ?: classifier.classId!!
|
||||
classId = classId.readOnlyToMutable() ?: classId
|
||||
|
||||
val lookupTag = ConeClassLikeLookupTagImpl(classId)
|
||||
lookupTag.constructClassType(
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.java.topLevelName
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firSafeNullable
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScope
|
||||
@@ -146,7 +147,7 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
): FirScope? {
|
||||
val symbol = this.getClassLikeSymbolByFqName(classId) ?: return null
|
||||
|
||||
return symbol.firUnsafe<FirRegularClass>().buildDefaultUseSiteScope(session, scopeSession)
|
||||
return symbol.firSafeNullable<FirRegularClass>()?.buildDefaultUseSiteScope(session, scopeSession)
|
||||
}
|
||||
|
||||
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol? {
|
||||
|
||||
@@ -114,7 +114,7 @@ private val KOTLIN_COLLECTIONS = FqName("kotlin.collections")
|
||||
|
||||
private val KOTLIN_COLLECTIONS_PREFIX_LENGTH = KOTLIN_COLLECTIONS.asString().length + 1
|
||||
|
||||
private fun ClassId.readOnlyToMutable(): ClassId? {
|
||||
internal fun ClassId.readOnlyToMutable(): ClassId? {
|
||||
val mutableFqName = JavaToKotlinClassMap.readOnlyToMutable(asSingleFqName().toUnsafe())
|
||||
return mutableFqName?.let {
|
||||
ClassId(KOTLIN_COLLECTIONS, FqName(it.asString().substring(KOTLIN_COLLECTIONS_PREFIX_LENGTH)), false)
|
||||
|
||||
@@ -315,7 +315,7 @@ class JavaClassEnhancementScope(
|
||||
return signatureParts.type
|
||||
}
|
||||
|
||||
private val overrideBindCache = mutableMapOf<Name, Map<ConeFunctionSymbol?, List<ConeCallableSymbol>>>()
|
||||
private val overrideBindCache = mutableMapOf<Name, Map<ConeCallableSymbol?, List<ConeCallableSymbol>>>()
|
||||
|
||||
private fun FirCallableMemberDeclaration.overriddenMembers(): List<FirCallableMemberDeclaration> {
|
||||
val backMap = overrideBindCache.getOrPut(this.name) {
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.*
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractProviderBasedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
|
||||
@@ -32,7 +33,7 @@ import org.jetbrains.kotlin.name.Name
|
||||
class JavaClassUseSiteScope(
|
||||
klass: FirRegularClass,
|
||||
session: FirSession,
|
||||
internal val superTypesScope: FirScope,
|
||||
private val superTypesScope: FirScope,
|
||||
private val declaredMemberScope: FirScope
|
||||
) : FirAbstractProviderBasedScope(session, lookupInFir = true) {
|
||||
internal val symbol = klass.symbol
|
||||
@@ -41,7 +42,7 @@ class JavaClassUseSiteScope(
|
||||
if (klass is FirJavaClass) klass.javaTypeParameterStack else JavaTypeParameterStack.EMPTY
|
||||
|
||||
//base symbol as key, overridden as value
|
||||
internal val overriddenByBase = mutableMapOf<ConeCallableSymbol, ConeFunctionSymbol?>()
|
||||
internal val overriddenByBase = mutableMapOf<ConeCallableSymbol, ConeCallableSymbol?>()
|
||||
|
||||
private val context: ConeTypeContext = session.typeContext
|
||||
|
||||
@@ -99,21 +100,31 @@ class JavaClassUseSiteScope(
|
||||
}
|
||||
}
|
||||
|
||||
private fun isOverriddenPropertyCheck(overriddenInKotlin: FirProperty, base: FirProperty): Boolean {
|
||||
val receiverTypeRef = base.receiverTypeRef
|
||||
val overriddenReceiverTypeRef = overriddenInKotlin.receiverTypeRef
|
||||
return when {
|
||||
receiverTypeRef == null -> overriddenReceiverTypeRef == null
|
||||
overriddenReceiverTypeRef == null -> false
|
||||
else -> isEqualTypes(receiverTypeRef, overriddenReceiverTypeRef, ConeSubstitutor.Empty)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun bindOverrides(name: Name) {
|
||||
val overrideCandidates = mutableSetOf<ConeFunctionSymbol>()
|
||||
declaredMemberScope.processFunctionsByName(name) {
|
||||
overrideCandidates += it
|
||||
ProcessorAction.NEXT
|
||||
NEXT
|
||||
}
|
||||
|
||||
|
||||
superTypesScope.processFunctionsByName(name) {
|
||||
it.getOverridden(overrideCandidates)
|
||||
ProcessorAction.NEXT
|
||||
NEXT
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeCallableSymbol.getOverridden(candidates: Set<ConeFunctionSymbol>): ConeCallableSymbol? {
|
||||
private fun ConeCallableSymbol.getOverridden(candidates: Set<ConeCallableSymbol>): ConeCallableSymbol? {
|
||||
if (overriddenByBase.containsKey(this)) return overriddenByBase[this]
|
||||
|
||||
val overriding = when (this) {
|
||||
@@ -121,23 +132,32 @@ class JavaClassUseSiteScope(
|
||||
val self = firUnsafe<FirFunction>()
|
||||
self as FirCallableMemberDeclaration
|
||||
candidates.firstOrNull {
|
||||
val member = (it as FirFunctionSymbol).fir as FirFunction
|
||||
self.modality != Modality.FINAL && isOverriddenFunCheck(member, self)
|
||||
val overridden = (it as? FirFunctionSymbol)?.fir as? FirFunction
|
||||
overridden != null && self.modality != Modality.FINAL && isOverriddenFunCheck(overridden, self)
|
||||
}
|
||||
}
|
||||
is FirPropertySymbol -> {
|
||||
val self = fir as? FirProperty ?: return null
|
||||
candidates.firstOrNull {
|
||||
val member = (it as FirFunctionSymbol).fir as FirNamedFunction
|
||||
self.modality != Modality.FINAL && isOverriddenPropertyCheck(member, self)
|
||||
when (it) {
|
||||
is FirFunctionSymbol -> {
|
||||
val overridden = it.fir as FirNamedFunction
|
||||
self.modality != Modality.FINAL && isOverriddenPropertyCheck(overridden, self)
|
||||
}
|
||||
is FirPropertySymbol -> {
|
||||
val overridden = it.fir
|
||||
overridden is FirProperty && self.modality != Modality.FINAL && isOverriddenPropertyCheck(overridden, self)
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
is FirAccessorSymbol -> {
|
||||
val self = fir as FirNamedFunction
|
||||
candidates.firstOrNull {
|
||||
val member = (it as FirFunctionSymbol).fir as FirNamedFunction
|
||||
self.modality != Modality.FINAL && isOverriddenFunCheck(member, self)
|
||||
val overridden = (it as? FirFunctionSymbol)?.fir as? FirNamedFunction
|
||||
overridden != null && self.modality != Modality.FINAL && isOverriddenFunCheck(overridden, self)
|
||||
}
|
||||
}
|
||||
else -> error("Unexpected callable symbol: $this")
|
||||
@@ -153,7 +173,7 @@ class JavaClassUseSiteScope(
|
||||
overrideCandidates += it
|
||||
processor(it)
|
||||
}
|
||||
) return ProcessorAction.STOP
|
||||
) return STOP
|
||||
|
||||
return superTypesScope.processFunctionsByName(name) {
|
||||
|
||||
@@ -161,53 +181,73 @@ class JavaClassUseSiteScope(
|
||||
if (overriddenBy == null) {
|
||||
processor(it)
|
||||
} else {
|
||||
ProcessorAction.NEXT
|
||||
NEXT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun processAccessorFunctionsByName(
|
||||
private fun processAccessorFunctionsAndPropertiesByName(
|
||||
propertyName: Name,
|
||||
accessorName: Name,
|
||||
processor: (ConePropertySymbol) -> ProcessorAction
|
||||
isGetter: Boolean,
|
||||
processor: (ConeVariableSymbol) -> ProcessorAction
|
||||
): ProcessorAction {
|
||||
val overrideCandidates = mutableSetOf<ConeFunctionSymbol>()
|
||||
if (!declaredMemberScope.processFunctionsByName(accessorName) { functionSymbol ->
|
||||
overrideCandidates += functionSymbol
|
||||
val accessorSymbol = FirAccessorSymbol(
|
||||
accessorId = functionSymbol.callableId,
|
||||
callableId = CallableId(functionSymbol.callableId.packageName, functionSymbol.callableId.className, propertyName)
|
||||
)
|
||||
if (functionSymbol is FirBasedSymbol<*>) {
|
||||
(functionSymbol.fir as? FirCallableMemberDeclaration)?.let { callableMember -> accessorSymbol.bind(callableMember) }
|
||||
}
|
||||
processor(accessorSymbol)
|
||||
val overrideCandidates = mutableSetOf<ConeCallableSymbol>()
|
||||
val klass = symbol.fir
|
||||
if (!declaredMemberScope.processPropertiesByName(propertyName) { variableSymbol ->
|
||||
overrideCandidates += variableSymbol
|
||||
processor(variableSymbol)
|
||||
}
|
||||
) return ProcessorAction.STOP
|
||||
) return STOP
|
||||
if (klass is FirJavaClass) {
|
||||
if (!declaredMemberScope.processFunctionsByName(accessorName) { functionSymbol ->
|
||||
if (functionSymbol is FirFunctionSymbol) {
|
||||
val fir = functionSymbol.fir
|
||||
if (fir is FirNamedFunction) {
|
||||
if (fir.isStatic) {
|
||||
return@processFunctionsByName NEXT
|
||||
}
|
||||
when (isGetter) {
|
||||
true -> if (fir.valueParameters.isNotEmpty()) {
|
||||
return@processFunctionsByName NEXT
|
||||
}
|
||||
false -> if (fir.valueParameters.size != 1) {
|
||||
return@processFunctionsByName NEXT
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
overrideCandidates += functionSymbol
|
||||
val accessorSymbol = FirAccessorSymbol(
|
||||
accessorId = functionSymbol.callableId,
|
||||
callableId = CallableId(functionSymbol.callableId.packageName, functionSymbol.callableId.className, propertyName)
|
||||
)
|
||||
if (functionSymbol is FirBasedSymbol<*>) {
|
||||
(functionSymbol.fir as? FirCallableMemberDeclaration)?.let { callableMember -> accessorSymbol.bind(callableMember) }
|
||||
}
|
||||
processor(accessorSymbol)
|
||||
}
|
||||
) return STOP
|
||||
}
|
||||
|
||||
return superTypesScope.processPropertiesByName(propertyName) {
|
||||
val firCallableMember = (it as FirBasedSymbol<*>).fir as? FirCallableMemberDeclaration
|
||||
if (firCallableMember?.isStatic == true) {
|
||||
ProcessorAction.NEXT
|
||||
NEXT
|
||||
} else {
|
||||
val overriddenBy = it.getOverridden(overrideCandidates)
|
||||
if (overriddenBy == null && it is ConePropertySymbol) {
|
||||
processor(it)
|
||||
} else {
|
||||
ProcessorAction.NEXT
|
||||
NEXT
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (ConeVariableSymbol) -> ProcessorAction): ProcessorAction {
|
||||
if (!declaredMemberScope.processPropertiesByName(name) {
|
||||
processor(it)
|
||||
}
|
||||
) return ProcessorAction.STOP
|
||||
|
||||
val getterName = Name.identifier(getterPrefix + name.asString().capitalize())
|
||||
return processAccessorFunctionsByName(name, getterName, processor)
|
||||
return processAccessorFunctionsAndPropertiesByName(name, getterName, isGetter = true, processor = processor)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -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
|
||||
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
|
||||
import org.w3c.dom.Node
|
||||
import org.w3c.dom.NodeList
|
||||
import java.io.File
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
|
||||
data class ModuleData(
|
||||
val name: String,
|
||||
val qualifiedName: String,
|
||||
val classpath: List<File>,
|
||||
val sources: List<File>,
|
||||
val javaSourceRoots: List<File>
|
||||
)
|
||||
|
||||
private fun NodeList.toList(): List<Node> {
|
||||
val list = mutableListOf<Node>()
|
||||
for (index in 0 until this.length) {
|
||||
list += item(index)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
|
||||
private val Node.childNodesList get() = childNodes.toList()
|
||||
|
||||
abstract class AbstractModularizedTest : KtUsefulTestCase() {
|
||||
private fun loadModule(file: File): ModuleData {
|
||||
|
||||
val factory = DocumentBuilderFactory.newInstance()
|
||||
factory.isIgnoringComments = true
|
||||
factory.isIgnoringElementContentWhitespace = true
|
||||
val builder = factory.newDocumentBuilder()
|
||||
val document = builder.parse(file)
|
||||
val moduleElement = document.childNodes.item(0).childNodesList.first { it.nodeType == Node.ELEMENT_NODE }
|
||||
val moduleName = moduleElement.attributes.getNamedItem("name").nodeValue
|
||||
val outputDir = moduleElement.attributes.getNamedItem("outputDir").nodeValue
|
||||
val qualifiedModuleName = outputDir.substringAfterLast("/")
|
||||
val javaSourceRoots = mutableListOf<File>()
|
||||
val classpath = mutableListOf<File>()
|
||||
val sources = mutableListOf<File>()
|
||||
|
||||
for (index in 0 until moduleElement.childNodes.length) {
|
||||
val item = moduleElement.childNodes.item(index)
|
||||
|
||||
if (item.nodeName == "classpath") {
|
||||
val path = item.attributes.getNamedItem("path").nodeValue
|
||||
if (path != outputDir) {
|
||||
classpath += File(path)
|
||||
}
|
||||
}
|
||||
if (item.nodeName == "javaSourceRoots") {
|
||||
javaSourceRoots += File(item.attributes.getNamedItem("path").nodeValue)
|
||||
}
|
||||
if (item.nodeName == "sources") {
|
||||
sources += File(item.attributes.getNamedItem("path").nodeValue)
|
||||
}
|
||||
}
|
||||
|
||||
return ModuleData(moduleName, qualifiedModuleName, classpath, sources, javaSourceRoots)
|
||||
}
|
||||
|
||||
|
||||
protected abstract fun beforePass()
|
||||
protected abstract fun afterPass()
|
||||
protected abstract fun processModule(moduleData: ModuleData): ProcessorAction
|
||||
|
||||
protected fun runTestOnce(pass: Int) {
|
||||
beforePass()
|
||||
val testDataPath = "/Users/jetbrains/jps"
|
||||
val root = File(testDataPath)
|
||||
|
||||
println("BASE PATH: ${root.absolutePath}")
|
||||
|
||||
val modules =
|
||||
root.listFiles().sortedBy { it.lastModified() }.map { loadModule(it) }
|
||||
.filter { it.qualifiedName == "kotlin.idea.main" }
|
||||
|
||||
|
||||
for (module in modules.progress(step = 0.0) { "Analyzing ${it.qualifiedName}" }) {
|
||||
if (processModule(module).stop()) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
afterPass()
|
||||
}
|
||||
}
|
||||
@@ -21,30 +21,17 @@ 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.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.TestJdkKind
|
||||
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
|
||||
import org.w3c.dom.Node
|
||||
import org.w3c.dom.NodeList
|
||||
import java.io.File
|
||||
import java.io.PrintStream
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
import kotlin.system.measureNanoTime
|
||||
|
||||
|
||||
private fun NodeList.toList(): List<Node> {
|
||||
val list = mutableListOf<Node>()
|
||||
for (index in 0 until this.length) {
|
||||
list += item(index)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
private val Node.childNodesList get() = childNodes.toList()
|
||||
|
||||
private const val FAIL_FAST = true
|
||||
private const val DUMP_FIR = true
|
||||
|
||||
@@ -52,18 +39,9 @@ private const val FIR_DUMP_PATH = "tmp/firDump"
|
||||
private const val FIR_HTML_DUMP_PATH = "tmp/firDump-html"
|
||||
private const val FIR_LOGS_PATH = "tmp/fir-logs"
|
||||
|
||||
private data class ModuleData(
|
||||
val name: String,
|
||||
val qualifiedName: String,
|
||||
val classpath: List<File>,
|
||||
val sources: List<File>,
|
||||
val javaSourceRoots: List<File>
|
||||
)
|
||||
|
||||
private const val PASSES = 1
|
||||
|
||||
class FirResolveModularizedTotalKotlinTest : KtUsefulTestCase() {
|
||||
|
||||
class FirResolveModularizedTotalKotlinTest : AbstractModularizedTest() {
|
||||
|
||||
private lateinit var bench: FirResolveBench
|
||||
private lateinit var dump: MultiModuleHtmlFirDump
|
||||
@@ -115,7 +93,7 @@ class FirResolveModularizedTotalKotlinTest : KtUsefulTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun processModule(moduleData: ModuleData) {
|
||||
override fun processModule(moduleData: ModuleData): ProcessorAction {
|
||||
val configurationKind = ConfigurationKind.ALL
|
||||
val testJdkKind = TestJdkKind.FULL_JDK
|
||||
|
||||
@@ -138,63 +116,15 @@ class FirResolveModularizedTotalKotlinTest : KtUsefulTestCase() {
|
||||
runAnalysis(moduleData, environment)
|
||||
|
||||
Disposer.dispose(disposable)
|
||||
if (bench.hasFiles && FAIL_FAST) return ProcessorAction.STOP
|
||||
return ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
private fun loadModule(file: File): ModuleData {
|
||||
|
||||
val factory = DocumentBuilderFactory.newInstance()
|
||||
factory.isIgnoringComments = true
|
||||
factory.isIgnoringElementContentWhitespace = true
|
||||
val builder = factory.newDocumentBuilder()
|
||||
val document = builder.parse(file)
|
||||
val moduleElement = document.childNodes.item(0).childNodesList.first { it.nodeType == Node.ELEMENT_NODE }
|
||||
val moduleName = moduleElement.attributes.getNamedItem("name").nodeValue
|
||||
val outputDir = moduleElement.attributes.getNamedItem("outputDir").nodeValue
|
||||
val qualifiedModuleName = outputDir.substringAfterLast("/")
|
||||
val javaSourceRoots = mutableListOf<File>()
|
||||
val classpath = mutableListOf<File>()
|
||||
val sources = mutableListOf<File>()
|
||||
|
||||
for (index in 0 until moduleElement.childNodes.length) {
|
||||
val item = moduleElement.childNodes.item(index)
|
||||
|
||||
if (item.nodeName == "classpath") {
|
||||
val path = item.attributes.getNamedItem("path").nodeValue
|
||||
if (path != outputDir) {
|
||||
classpath += File(path)
|
||||
}
|
||||
}
|
||||
if (item.nodeName == "javaSourceRoots") {
|
||||
javaSourceRoots += File(item.attributes.getNamedItem("path").nodeValue)
|
||||
}
|
||||
if (item.nodeName == "sources") {
|
||||
sources += File(item.attributes.getNamedItem("path").nodeValue)
|
||||
}
|
||||
}
|
||||
|
||||
return ModuleData(moduleName, qualifiedModuleName, classpath, sources, javaSourceRoots)
|
||||
}
|
||||
|
||||
|
||||
private fun runTestOnce(pass: Int) {
|
||||
override fun beforePass() {
|
||||
if (DUMP_FIR) dump = MultiModuleHtmlFirDump(File(FIR_HTML_DUMP_PATH))
|
||||
val testDataPath = "/Users/jetbrains/jps"
|
||||
val root = File(testDataPath)
|
||||
|
||||
println("BASE PATH: ${root.absolutePath}")
|
||||
|
||||
val modules =
|
||||
root.listFiles().sortedBy { it.lastModified() }.map { loadModule(it) }
|
||||
// .sortedByDescending { it.name == "idea" }
|
||||
|
||||
|
||||
for (module in modules.progress(step = 0.0) { "Analyzing ${it.qualifiedName}" }) {
|
||||
processModule(module)
|
||||
if (bench.hasFiles && FAIL_FAST) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun afterPass() {
|
||||
bench.report(System.out, errorTypeReports = false)
|
||||
|
||||
saveReport()
|
||||
|
||||
@@ -15,37 +15,21 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.TestJdkKind
|
||||
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
|
||||
import org.w3c.dom.Node
|
||||
import org.w3c.dom.NodeList
|
||||
import java.io.File
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
import kotlin.system.measureNanoTime
|
||||
|
||||
|
||||
private fun NodeList.toList(): List<Node> {
|
||||
val list = mutableListOf<Node>()
|
||||
for (index in 0 until this.length) {
|
||||
list += item(index)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
private val Node.childNodesList get() = childNodes.toList()
|
||||
|
||||
|
||||
private data class XModuleData(val name: String, val classpath: List<File>, val sources: List<File>, val javaSourceRoots: List<File>)
|
||||
|
||||
class NonFirResolveModularizedTotalKotlinTest : KtUsefulTestCase() {
|
||||
class NonFirResolveModularizedTotalKotlinTest : AbstractModularizedTest() {
|
||||
|
||||
|
||||
private var totalTime = 0L
|
||||
private var files = 0
|
||||
|
||||
private fun runAnalysis(moduleData: XModuleData, environment: KotlinCoreEnvironment) {
|
||||
private fun runAnalysis(moduleData: ModuleData, environment: KotlinCoreEnvironment) {
|
||||
val project = environment.project
|
||||
|
||||
val time = measureNanoTime {
|
||||
@@ -58,7 +42,7 @@ class NonFirResolveModularizedTotalKotlinTest : KtUsefulTestCase() {
|
||||
|
||||
}
|
||||
|
||||
private fun processModule(moduleData: XModuleData) {
|
||||
override fun processModule(moduleData: ModuleData): ProcessorAction {
|
||||
val configurationKind = ConfigurationKind.ALL
|
||||
val testJdkKind = TestJdkKind.FULL_JDK
|
||||
|
||||
@@ -92,73 +76,19 @@ class NonFirResolveModularizedTotalKotlinTest : KtUsefulTestCase() {
|
||||
})
|
||||
val environment = KotlinCoreEnvironment.createForTests(disposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
||||
|
||||
// Extensions.getArea(environment.project)
|
||||
// .getExtensionPoint(PsiElementFinder.EP_NAME)
|
||||
// .unregisterExtension(JavaElementFinder::class.java)
|
||||
|
||||
println("Processing module: ${moduleData.name}")
|
||||
runAnalysis(moduleData, environment)
|
||||
|
||||
Disposer.dispose(disposable)
|
||||
}
|
||||
|
||||
private fun loadModule(file: File): XModuleData {
|
||||
|
||||
val factory = DocumentBuilderFactory.newInstance()
|
||||
factory.isIgnoringComments = true
|
||||
factory.isIgnoringElementContentWhitespace = true
|
||||
val builder = factory.newDocumentBuilder()
|
||||
val document = builder.parse(file)
|
||||
val moduleElement = document.childNodes.item(0).childNodesList.first { it.nodeType == Node.ELEMENT_NODE }
|
||||
val moduleName = moduleElement.attributes.getNamedItem("name").nodeValue
|
||||
val javaSourceRoots = mutableListOf<File>()
|
||||
val classpath = mutableListOf<File>()
|
||||
val sources = mutableListOf<File>()
|
||||
|
||||
for (index in 0 until moduleElement.childNodes.length) {
|
||||
val item = moduleElement.childNodes.item(index)
|
||||
|
||||
if (item.nodeName == "classpath") {
|
||||
classpath += File(item.attributes.getNamedItem("path").nodeValue)
|
||||
}
|
||||
if (item.nodeName == "javaSourceRoots") {
|
||||
javaSourceRoots += File(item.attributes.getNamedItem("path").nodeValue)
|
||||
}
|
||||
if (item.nodeName == "sources") {
|
||||
sources += File(item.attributes.getNamedItem("path").nodeValue)
|
||||
}
|
||||
}
|
||||
|
||||
return XModuleData(moduleName, classpath, sources, javaSourceRoots)
|
||||
return ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
|
||||
private fun runTestLocal() {
|
||||
val testDataPath = "/Users/jetbrains/jps"
|
||||
val root = File(testDataPath)
|
||||
|
||||
println("BASE PATH: ${root.absolutePath}")
|
||||
|
||||
val modules =
|
||||
root.listFiles().sortedBy { it.lastModified() }.map { loadModule(it) }
|
||||
|
||||
// .sortedBy { !it.sources.any { it.nameWithoutExtension == "KotlinSearchEverywhereClassifier" } }
|
||||
|
||||
|
||||
for (module in modules.progress { "Analyzing ${it.name}" }) {
|
||||
processModule(module)
|
||||
}
|
||||
|
||||
println("Total time: ${totalTime * 1e-6} ms, ${(totalTime * 1e-6) / files} ms per file")
|
||||
totalTime = 0
|
||||
files = 0
|
||||
}
|
||||
override fun afterPass() {}
|
||||
override fun beforePass() {}
|
||||
|
||||
fun testTotalKotlin() {
|
||||
//Thread.sleep(5000)
|
||||
for (i in 0..2) {
|
||||
println("Pass $i")
|
||||
runTestLocal()
|
||||
runTestOnce(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,10 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirClassImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirMemberFunctionImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirFunctionCallImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirReturnExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
@@ -89,7 +86,7 @@ internal fun KtClassOrObject.generateCopyFunction(
|
||||
isInfix = false, isInline = false,
|
||||
isTailRec = false, isExternal = false,
|
||||
isSuspend = false, receiverTypeRef = null,
|
||||
returnTypeRef = FirImplicitTypeRefImpl(session, this)
|
||||
returnTypeRef = firPrimaryConstructor.returnTypeRef//FirImplicitTypeRefImpl(session, this)
|
||||
).apply {
|
||||
val copyFunction = this
|
||||
val zippedParameters =
|
||||
@@ -105,29 +102,31 @@ internal fun KtClassOrObject.generateCopyFunction(
|
||||
isCrossinline = false, isNoinline = false, isVararg = false
|
||||
)
|
||||
}
|
||||
body = FirSingleExpressionBlock(
|
||||
session,
|
||||
FirReturnExpressionImpl(
|
||||
session, this@generateCopyFunction,
|
||||
FirFunctionCallImpl(session, this@generateCopyFunction).apply {
|
||||
calleeReference = FirResolvedCallableReferenceImpl(
|
||||
session, this@generateCopyFunction, firClass.name,
|
||||
firPrimaryConstructor.symbol
|
||||
)
|
||||
}.apply {
|
||||
for ((ktParameter, firParameter) in primaryConstructorParameters.zip(valueParameters)) {
|
||||
this.arguments += FirQualifiedAccessExpressionImpl(session, ktParameter).apply {
|
||||
calleeReference = FirResolvedCallableReferenceImpl(
|
||||
session, ktParameter, firParameter.name, firParameter.symbol
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
).apply {
|
||||
target = FirFunctionTarget(null)
|
||||
target.bind(copyFunction)
|
||||
}
|
||||
)
|
||||
|
||||
body = FirEmptyExpressionBlock(session)
|
||||
// body = FirSingleExpressionBlock(
|
||||
// session,
|
||||
// FirReturnExpressionImpl(
|
||||
// session, this@generateCopyFunction,
|
||||
// FirFunctionCallImpl(session, this@generateCopyFunction).apply {
|
||||
// calleeReference = FirResolvedCallableReferenceImpl(
|
||||
// session, this@generateCopyFunction, firClass.name,
|
||||
// firPrimaryConstructor.symbol
|
||||
// )
|
||||
// }.apply {
|
||||
// for ((ktParameter, firParameter) in primaryConstructorParameters.zip(valueParameters)) {
|
||||
// this.arguments += FirQualifiedAccessExpressionImpl(session, ktParameter).apply {
|
||||
// calleeReference = FirResolvedCallableReferenceImpl(
|
||||
// session, ktParameter, firParameter.name, firParameter.symbol
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// ).apply {
|
||||
// target = FirFunctionTarget(null)
|
||||
// target.bind(copyFunction)
|
||||
// }
|
||||
// )
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -174,7 +174,7 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
|
||||
} else {
|
||||
FirSingleExpressionBlock(
|
||||
session,
|
||||
FirExpressionStub(session, this).toReturn()
|
||||
FirExpressionStub(session, null).toReturn()
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
@@ -281,7 +281,7 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
|
||||
)
|
||||
},
|
||||
getter = FirDefaultPropertyGetter(session, this, type, visibility),
|
||||
setter = FirDefaultPropertySetter(session, this, type, visibility),
|
||||
setter = if (isMutable) FirDefaultPropertySetter(session, this, type, visibility) else null,
|
||||
delegate = null
|
||||
)
|
||||
extractAnnotationsTo(firProperty)
|
||||
@@ -796,7 +796,7 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
|
||||
isVar,
|
||||
initializer,
|
||||
property.getter.toFirPropertyAccessor(property, propertyType, isGetter = true),
|
||||
property.setter.toFirPropertyAccessor(property, propertyType, isGetter = false),
|
||||
if (isVar) property.setter.toFirPropertyAccessor(property, propertyType, isGetter = false) else null,
|
||||
if (property.hasDelegate()) {
|
||||
{ property.delegate?.expression }.toFirExpression("Should have delegate")
|
||||
} else null
|
||||
|
||||
@@ -159,6 +159,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
||||
|
||||
val getterFlags = if (proto.hasGetterFlags()) proto.getterFlags else flags
|
||||
val setterFlags = if (proto.hasSetterFlags()) proto.setterFlags else flags
|
||||
val isVar = Flags.IS_VAR.get(flags)
|
||||
|
||||
return FirMemberPropertyImpl(
|
||||
c.session,
|
||||
@@ -174,10 +175,12 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
||||
isLateInit = Flags.IS_LATEINIT.get(flags),
|
||||
receiverTypeRef = proto.receiverType(c.typeTable)?.toTypeRef(local),
|
||||
returnTypeRef = returnTypeRef,
|
||||
isVar = Flags.IS_VAR.get(flags),
|
||||
isVar = isVar,
|
||||
initializer = null,
|
||||
getter = FirDefaultPropertyGetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(getterFlags))),
|
||||
setter = FirDefaultPropertySetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(setterFlags))),
|
||||
setter = if (isVar) {
|
||||
FirDefaultPropertySetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(setterFlags)))
|
||||
} else null,
|
||||
delegate = null
|
||||
).apply {
|
||||
typeParameters += local.typeDeserializer.ownTypeParameters.map { it.firUnsafe() }
|
||||
|
||||
@@ -6,14 +6,16 @@
|
||||
package org.jetbrains.kotlin.fir.resolve
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.service
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeAbbreviatedTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -115,6 +117,7 @@ fun <T : ConeKotlinType> T.withNullability(nullability: ConeNullability): T {
|
||||
is ConeTypeParameterTypeImpl -> ConeTypeParameterTypeImpl(lookupTag, nullability.isNullable) as T
|
||||
is ConeFlexibleType -> ConeFlexibleType(lowerBound.withNullability(nullability), upperBound.withNullability(nullability)) as T
|
||||
is ConeTypeVariableType -> ConeTypeVariableType(nullability, lookupTag) as T
|
||||
is ConeCapturedType -> ConeCapturedType(captureStatus, lowerType, nullability, constructor) as T
|
||||
else -> error("sealed: ${this::class}")
|
||||
}
|
||||
}
|
||||
@@ -136,3 +139,22 @@ fun <T : ConeKotlinType> T.withArguments(arguments: Array<ConeKotlinTypeProjecti
|
||||
else -> error("Not supported: $this: ${this.render()}")
|
||||
}
|
||||
}
|
||||
|
||||
fun FirFunction.constructFunctionalTypeRef(session: FirSession): FirResolvedTypeRef {
|
||||
val receiverTypeRef = when (this) {
|
||||
is FirNamedFunction -> receiverTypeRef
|
||||
is FirAnonymousFunction -> receiverTypeRef
|
||||
else -> null
|
||||
}
|
||||
val receiverType = receiverTypeRef?.coneTypeUnsafe<ConeKotlinType>()
|
||||
val parameters = valueParameters.map {
|
||||
it.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: ConeKotlinErrorType("No type for parameter")
|
||||
}
|
||||
val rawReturnType = (this as FirTypedDeclaration).returnTypeRef.coneTypeUnsafe<ConeKotlinType>()
|
||||
val receiverAndParameterTypes = listOfNotNull(receiverType) + parameters + listOf(rawReturnType)
|
||||
|
||||
val functionalTypeId = StandardClassIds.byName("Function${receiverAndParameterTypes.size - 1}")
|
||||
val functionalType = functionalTypeId(session.service()).constructType(receiverAndParameterTypes.toTypedArray(), isNullable = false)
|
||||
|
||||
return FirResolvedTypeRefImpl(session, psi, functionalType)
|
||||
}
|
||||
|
||||
@@ -29,10 +29,7 @@ fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession)
|
||||
// For ConeClassLikeType they might be a type alias instead of a regular class
|
||||
// TODO: support that case and switch back to `firUnsafe` instead of `firSafeNullable`
|
||||
val fir = this.lookupTag.toSymbol(useSiteSession)?.firSafeNullable<FirRegularClass>() ?: return null
|
||||
val companionScope = fir.companionObject?.buildUseSiteScope(useSiteSession, scopeSession)
|
||||
val ownScope = wrapSubstitutionScopeIfNeed(useSiteSession, fir.buildUseSiteScope(useSiteSession, scopeSession)!!, scopeSession)
|
||||
if (companionScope != null) FirCompositeScope(mutableListOf(ownScope, companionScope)) else ownScope
|
||||
|
||||
wrapSubstitutionScopeIfNeed(useSiteSession, fir.buildUseSiteScope(useSiteSession, scopeSession)!!, scopeSession)
|
||||
}
|
||||
is ConeTypeParameterType -> {
|
||||
// TODO: support LibraryTypeParameterSymbol or get rid of it
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
||||
import org.jetbrains.kotlin.fir.resolve.withNullability
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||
@@ -37,7 +38,8 @@ fun resolveArgumentExpression(
|
||||
typeProvider: (FirExpression) -> FirTypeRef?
|
||||
) {
|
||||
return when (argument) {
|
||||
is FirQualifiedAccessExpression, is FirFunctionCall -> resolvePlainExpressionArgument(
|
||||
is FirFunctionCall -> resolveSubCallArgument(csBuilder, argument, expectedType, sink, isReceiver, isSafeCall, typeProvider)
|
||||
is FirQualifiedAccessExpression -> resolvePlainExpressionArgument(
|
||||
csBuilder,
|
||||
argument,
|
||||
expectedType,
|
||||
@@ -78,6 +80,21 @@ fun resolveArgumentExpression(
|
||||
}
|
||||
}
|
||||
|
||||
fun resolveSubCallArgument(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: FirFunctionCall,
|
||||
expectedType: ConeKotlinType,
|
||||
sink: CheckerSink,
|
||||
isReceiver: Boolean,
|
||||
isSafeCall: Boolean,
|
||||
typeProvider: (FirExpression) -> FirTypeRef?
|
||||
) {
|
||||
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)
|
||||
resolvePlainArgumentType(csBuilder, argumentType, expectedType, sink, isReceiver, isSafeCall)
|
||||
}
|
||||
|
||||
fun resolvePlainExpressionArgument(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: FirExpression,
|
||||
|
||||
@@ -8,16 +8,23 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirImportImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.scope
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorWithJump
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
||||
import org.jetbrains.kotlin.fir.scopes.FirPosition
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope
|
||||
import org.jetbrains.kotlin.fir.scopes.processClassifiersByNameWithAction
|
||||
import org.jetbrains.kotlin.fir.service
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
@@ -25,11 +32,14 @@ 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.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.model.PostponedResolvedAtomMarker
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.createCoroutineUnintercepted
|
||||
|
||||
class CallInfo(
|
||||
val callKind: CallKind,
|
||||
@@ -49,24 +59,45 @@ class CallInfo(
|
||||
|
||||
interface CheckerSink {
|
||||
fun reportApplicability(new: CandidateApplicability)
|
||||
suspend fun yield()
|
||||
suspend fun yieldApplicability(new: CandidateApplicability) {
|
||||
reportApplicability(new)
|
||||
yield()
|
||||
}
|
||||
|
||||
val components: InferenceComponents
|
||||
|
||||
suspend fun yieldIfNeed()
|
||||
}
|
||||
|
||||
|
||||
class CheckerSinkImpl(override val components: InferenceComponents) : CheckerSink {
|
||||
class CheckerSinkImpl(override val components: InferenceComponents, var continuation: Continuation<Unit>? = null) : CheckerSink {
|
||||
var current = CandidateApplicability.RESOLVED
|
||||
override fun reportApplicability(new: CandidateApplicability) {
|
||||
if (new < current) current = new
|
||||
}
|
||||
|
||||
override suspend fun yield() = kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn<Unit> {
|
||||
continuation = it
|
||||
kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
override suspend fun yieldIfNeed() {
|
||||
if (current < CandidateApplicability.SYNTHETIC_RESOLVED) {
|
||||
yield()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Candidate(
|
||||
val symbol: ConeSymbol,
|
||||
val dispatchReceiverValue: ClassDispatchReceiverValue?,
|
||||
val implicitExtensionReceiverValue: ImplicitReceiverValue?,
|
||||
val explicitReceiverKind: ExplicitReceiverKind,
|
||||
private val inferenceComponents: InferenceComponents,
|
||||
private val baseSystem: ConstraintStorage
|
||||
private val baseSystem: ConstraintStorage,
|
||||
val callInfo: CallInfo
|
||||
) {
|
||||
val system by lazy {
|
||||
val system = inferenceComponents.createConstraintSystem()
|
||||
@@ -118,7 +149,11 @@ interface TowerScopeLevel {
|
||||
): ProcessorAction
|
||||
|
||||
interface TowerScopeLevelProcessor<T : ConeSymbol> {
|
||||
fun consumeCandidate(symbol: T, dispatchReceiverValue: ClassDispatchReceiverValue?): ProcessorAction
|
||||
fun consumeCandidate(
|
||||
symbol: T,
|
||||
dispatchReceiverValue: ClassDispatchReceiverValue?,
|
||||
implicitExtensionReceiverValue: ImplicitReceiverValue?
|
||||
): ProcessorAction
|
||||
}
|
||||
|
||||
object Empty : TowerScopeLevel {
|
||||
@@ -155,7 +190,7 @@ abstract class SessionBasedTowerLevel(val session: FirSession) : TowerScopeLevel
|
||||
class MemberScopeTowerLevel(
|
||||
session: FirSession,
|
||||
val dispatchReceiver: ReceiverValue,
|
||||
val implicitExtensionReceiver: ReceiverValue? = null
|
||||
val implicitExtensionReceiver: ImplicitReceiverValue? = null
|
||||
) : SessionBasedTowerLevel(session) {
|
||||
|
||||
private fun <T : ConeSymbol> processMembers(
|
||||
@@ -170,9 +205,9 @@ class MemberScopeTowerLevel(
|
||||
if (candidate is ConeCallableSymbol && candidate.hasConsistentExtensionReceiver(extensionReceiver)) {
|
||||
// NB: we do not check dispatchReceiverValue != null here,
|
||||
// because of objects & constructors (see comments in dispatchReceiverValue() implementation)
|
||||
output.consumeCandidate(candidate, candidate.dispatchReceiverValue())
|
||||
output.consumeCandidate(candidate, candidate.dispatchReceiverValue(), implicitExtensionReceiver)
|
||||
} else if (candidate is ConeClassLikeSymbol) {
|
||||
output.consumeCandidate(candidate, null)
|
||||
output.consumeCandidate(candidate, null, implicitExtensionReceiver)
|
||||
} else {
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
@@ -180,7 +215,7 @@ class MemberScopeTowerLevel(
|
||||
) return ProcessorAction.STOP
|
||||
val withSynthetic = FirSyntheticPropertiesScope(session, scope, ReturnTypeCalculatorWithJump(session))
|
||||
return withSynthetic.processScopeMembers { symbol ->
|
||||
output.consumeCandidate(symbol, symbol.dispatchReceiverValue())
|
||||
output.consumeCandidate(symbol, symbol.dispatchReceiverValue(), implicitExtensionReceiver)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +252,8 @@ private fun ConeCallableSymbol.hasExtensionReceiver(): Boolean = (this as? FirCa
|
||||
// (if explicit receiver exists, it always *should* be an extension receiver)
|
||||
class ScopeTowerLevel(
|
||||
session: FirSession,
|
||||
val scope: FirScope
|
||||
val scope: FirScope,
|
||||
val implicitExtensionReceiver: ImplicitReceiverValue? = null
|
||||
) : SessionBasedTowerLevel(session) {
|
||||
override fun <T : ConeSymbol> processElementsByName(
|
||||
token: TowerScopeLevel.Token<T>,
|
||||
@@ -225,27 +261,36 @@ class ScopeTowerLevel(
|
||||
explicitReceiver: ExpressionReceiverValue?,
|
||||
processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
|
||||
): ProcessorAction {
|
||||
if (explicitReceiver != null && implicitExtensionReceiver != null) {
|
||||
return ProcessorAction.NEXT
|
||||
}
|
||||
val extensionReceiver = explicitReceiver ?: implicitExtensionReceiver
|
||||
return when (token) {
|
||||
|
||||
TowerScopeLevel.Token.Properties -> scope.processPropertiesByName(name) { candidate ->
|
||||
if (candidate.hasConsistentExtensionReceiver(explicitReceiver) && candidate.dispatchReceiverValue() == null) {
|
||||
processor.consumeCandidate(candidate as T, dispatchReceiverValue = null)
|
||||
if (candidate.hasConsistentExtensionReceiver(extensionReceiver) && candidate.dispatchReceiverValue() == null) {
|
||||
processor.consumeCandidate(
|
||||
candidate as T, dispatchReceiverValue = null,
|
||||
implicitExtensionReceiverValue = implicitExtensionReceiver
|
||||
)
|
||||
} else {
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
}
|
||||
TowerScopeLevel.Token.Functions -> scope.processFunctionsByName(name) { candidate ->
|
||||
// TODO: fix implicit receiver
|
||||
if (candidate.hasConsistentExtensionReceiver(explicitReceiver) && candidate.dispatchReceiverValue() == null) {
|
||||
processor.consumeCandidate(candidate as T, dispatchReceiverValue = null)
|
||||
if (candidate.hasConsistentExtensionReceiver(extensionReceiver) && candidate.dispatchReceiverValue() == null) {
|
||||
processor.consumeCandidate(
|
||||
candidate as T, dispatchReceiverValue = null,
|
||||
implicitExtensionReceiverValue = implicitExtensionReceiver
|
||||
)
|
||||
} else {
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
}
|
||||
TowerScopeLevel.Token.Objects -> scope.processClassifiersByNameWithAction(name, FirPosition.OTHER) {
|
||||
processor.consumeCandidate(
|
||||
it as T,
|
||||
dispatchReceiverValue = null
|
||||
it as T, dispatchReceiverValue = null,
|
||||
implicitExtensionReceiverValue = null
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -253,21 +298,112 @@ class ScopeTowerLevel(
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles only statics and top-levels, DOES NOT handle objects/companions members
|
||||
*/
|
||||
class QualifiedReceiverTowerLevel(session: FirSession) : SessionBasedTowerLevel(session) {
|
||||
override fun <T : ConeSymbol> processElementsByName(
|
||||
token: TowerScopeLevel.Token<T>,
|
||||
name: Name,
|
||||
explicitReceiver: ExpressionReceiverValue?,
|
||||
processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
|
||||
): ProcessorAction {
|
||||
val qualifiedReceiver = explicitReceiver?.explicitReceiverExpression as FirResolvedQualifier
|
||||
val scope = FirExplicitSimpleImportingScope(
|
||||
listOf(
|
||||
FirResolvedImportImpl(
|
||||
session,
|
||||
FirImportImpl(session, null, FqName.topLevel(name), false, null),
|
||||
qualifiedReceiver.packageFqName,
|
||||
qualifiedReceiver.relativeClassFqName
|
||||
)
|
||||
), session
|
||||
)
|
||||
|
||||
return if (token == TowerScopeLevel.Token.Objects) {
|
||||
scope.processClassifiersByNameWithAction(name, FirPosition.OTHER) {
|
||||
processor.consumeCandidate(it as T, null, null)
|
||||
}
|
||||
} else {
|
||||
scope.processCallables(name, token.cast()) {
|
||||
val fir = it.firUnsafe<FirCallableMemberDeclaration>()
|
||||
if (fir.isStatic || it.callableId.classId == null) {
|
||||
processor.consumeCandidate(it as T, null, null)
|
||||
} else {
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class QualifiedReceiverTowerDataConsumer<T : ConeSymbol>(
|
||||
val session: FirSession,
|
||||
val name: Name,
|
||||
val token: TowerScopeLevel.Token<T>,
|
||||
val explicitReceiver: ExpressionReceiverValue,
|
||||
val candidateFactory: CandidateFactory,
|
||||
val resultCollector: CandidateCollector
|
||||
) : TowerDataConsumer() {
|
||||
override fun consume(
|
||||
kind: TowerDataKind,
|
||||
towerScopeLevel: TowerScopeLevel,
|
||||
group: Int
|
||||
): ProcessorAction {
|
||||
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
|
||||
if (kind != TowerDataKind.EMPTY) return ProcessorAction.NEXT
|
||||
|
||||
return QualifiedReceiverTowerLevel(session).processElementsByName(
|
||||
token,
|
||||
name,
|
||||
explicitReceiver,
|
||||
processor = object : TowerScopeLevel.TowerScopeLevelProcessor<T> {
|
||||
override fun consumeCandidate(
|
||||
symbol: T,
|
||||
dispatchReceiverValue: ClassDispatchReceiverValue?,
|
||||
implicitExtensionReceiverValue: ImplicitReceiverValue?
|
||||
): ProcessorAction {
|
||||
assert(dispatchReceiverValue == null)
|
||||
resultCollector.consumeCandidate(
|
||||
group,
|
||||
candidateFactory.createCandidate(
|
||||
symbol,
|
||||
dispatchReceiverValue = null,
|
||||
implicitExtensionReceiverValue = null,
|
||||
explicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
||||
)
|
||||
)
|
||||
return ProcessorAction.NEXT
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract class TowerDataConsumer {
|
||||
abstract fun consume(
|
||||
kind: TowerDataKind,
|
||||
towerScopeLevel: TowerScopeLevel,
|
||||
resultCollector: CandidateCollector,
|
||||
// resultCollector: CandidateCollector,
|
||||
group: Int
|
||||
): ProcessorAction
|
||||
|
||||
private var processed = -1
|
||||
private var stopGroup = Int.MAX_VALUE
|
||||
fun checkSkip(group: Int, resultCollector: CandidateCollector): Boolean {
|
||||
fun skipGroup(group: Int, resultCollector: CandidateCollector): Boolean {
|
||||
if (resultCollector.isSuccess() && stopGroup == Int.MAX_VALUE) {
|
||||
stopGroup = group
|
||||
}
|
||||
return group > stopGroup
|
||||
if (group > processed) {
|
||||
processed = group
|
||||
}
|
||||
if (group < processed) {
|
||||
return true
|
||||
}
|
||||
if (group > stopGroup) return true
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,39 +412,94 @@ fun createVariableAndObjectConsumer(
|
||||
session: FirSession,
|
||||
name: Name,
|
||||
callInfo: CallInfo,
|
||||
inferenceComponents: InferenceComponents
|
||||
inferenceComponents: InferenceComponents,
|
||||
resultCollector: CandidateCollector
|
||||
): TowerDataConsumer {
|
||||
return PrioritizedTowerDataConsumer(
|
||||
resultCollector,
|
||||
createSimpleConsumer(
|
||||
session,
|
||||
name,
|
||||
TowerScopeLevel.Token.Properties,
|
||||
callInfo,
|
||||
inferenceComponents
|
||||
inferenceComponents,
|
||||
resultCollector
|
||||
),
|
||||
createSimpleConsumer(
|
||||
session,
|
||||
name,
|
||||
TowerScopeLevel.Token.Objects,
|
||||
callInfo,
|
||||
inferenceComponents
|
||||
inferenceComponents,
|
||||
resultCollector
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
fun createFunctionConsumer(
|
||||
fun createSimpleFunctionConsumer(
|
||||
session: FirSession,
|
||||
name: Name,
|
||||
callInfo: CallInfo,
|
||||
inferenceComponents: InferenceComponents
|
||||
inferenceComponents: InferenceComponents,
|
||||
resultCollector: CandidateCollector
|
||||
): TowerDataConsumer {
|
||||
return createSimpleConsumer(
|
||||
session,
|
||||
name,
|
||||
TowerScopeLevel.Token.Functions,
|
||||
callInfo,
|
||||
inferenceComponents
|
||||
inferenceComponents,
|
||||
resultCollector
|
||||
)
|
||||
}
|
||||
|
||||
fun createFunctionConsumer(
|
||||
session: FirSession,
|
||||
name: Name,
|
||||
callInfo: CallInfo,
|
||||
inferenceComponents: InferenceComponents,
|
||||
resultCollector: CandidateCollector,
|
||||
callResolver: CallResolver
|
||||
): TowerDataConsumer {
|
||||
val varCallInfo = CallInfo(
|
||||
CallKind.VariableAccess,
|
||||
callInfo.explicitReceiver,
|
||||
emptyList(),
|
||||
callInfo.isSafeCall,
|
||||
callInfo.typeArguments,
|
||||
inferenceComponents.session,
|
||||
callInfo.containingFile,
|
||||
callInfo.container,
|
||||
callInfo.typeProvider
|
||||
)
|
||||
return PrioritizedTowerDataConsumer(
|
||||
resultCollector,
|
||||
createSimpleConsumer(
|
||||
session,
|
||||
name,
|
||||
TowerScopeLevel.Token.Functions,
|
||||
callInfo,
|
||||
inferenceComponents,
|
||||
resultCollector
|
||||
),
|
||||
MultiplexerTowerDataConsumer(resultCollector).apply {
|
||||
addConsumer(
|
||||
createSimpleConsumer(
|
||||
session,
|
||||
name,
|
||||
TowerScopeLevel.Token.Properties,
|
||||
varCallInfo,
|
||||
inferenceComponents,
|
||||
InvokeCandidateCollector(
|
||||
callResolver,
|
||||
invokeCallInfo = callInfo,
|
||||
components = inferenceComponents,
|
||||
multiplexer = this
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -318,36 +509,49 @@ fun createSimpleConsumer(
|
||||
name: Name,
|
||||
token: TowerScopeLevel.Token<*>,
|
||||
callInfo: CallInfo,
|
||||
inferenceComponents: InferenceComponents
|
||||
inferenceComponents: InferenceComponents,
|
||||
resultCollector: CandidateCollector
|
||||
): TowerDataConsumer {
|
||||
val factory = CandidateFactory(inferenceComponents, callInfo)
|
||||
return if (callInfo.explicitReceiver != null) {
|
||||
ExplicitReceiverTowerDataConsumer(
|
||||
session,
|
||||
name,
|
||||
token,
|
||||
ExpressionReceiverValue(callInfo.explicitReceiver, callInfo.typeProvider),
|
||||
factory
|
||||
)
|
||||
val explicitReceiver = callInfo.explicitReceiver
|
||||
return if (explicitReceiver != null) {
|
||||
val receiverValue = ExpressionReceiverValue(explicitReceiver, callInfo.typeProvider)
|
||||
if (explicitReceiver is FirResolvedQualifier) {
|
||||
val qualified =
|
||||
QualifiedReceiverTowerDataConsumer(session, name, token, receiverValue, factory, resultCollector)
|
||||
|
||||
if (explicitReceiver.classId != null) {
|
||||
PrioritizedTowerDataConsumer(
|
||||
resultCollector,
|
||||
qualified,
|
||||
ExplicitReceiverTowerDataConsumer(session, name, token, receiverValue, factory, resultCollector)
|
||||
)
|
||||
} else {
|
||||
qualified
|
||||
}
|
||||
|
||||
} else {
|
||||
ExplicitReceiverTowerDataConsumer(session, name, token, receiverValue, factory, resultCollector)
|
||||
}
|
||||
} else {
|
||||
NoExplicitReceiverTowerDataConsumer(session, name, token, factory)
|
||||
NoExplicitReceiverTowerDataConsumer(session, name, token, factory, resultCollector)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PrioritizedTowerDataConsumer(
|
||||
val resultCollector: CandidateCollector,
|
||||
vararg val consumers: TowerDataConsumer
|
||||
) : TowerDataConsumer() {
|
||||
|
||||
override fun consume(
|
||||
kind: TowerDataKind,
|
||||
towerScopeLevel: TowerScopeLevel,
|
||||
resultCollector: CandidateCollector,
|
||||
group: Int
|
||||
): ProcessorAction {
|
||||
if (checkSkip(group, resultCollector)) return ProcessorAction.NEXT
|
||||
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
|
||||
for ((index, consumer) in consumers.withIndex()) {
|
||||
val action = consumer.consume(kind, towerScopeLevel, resultCollector, group * consumers.size + index)
|
||||
val action = consumer.consume(kind, towerScopeLevel, group * consumers.size + index)
|
||||
if (action.stop()) {
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
@@ -356,22 +560,68 @@ class PrioritizedTowerDataConsumer(
|
||||
}
|
||||
}
|
||||
|
||||
class MultiplexerTowerDataConsumer(
|
||||
val resultCollector: CandidateCollector
|
||||
) : TowerDataConsumer() {
|
||||
|
||||
val consumers = mutableListOf<TowerDataConsumer>()
|
||||
val newConsumers = mutableListOf<TowerDataConsumer>()
|
||||
|
||||
val kinds = mutableListOf<TowerDataKind>()
|
||||
val groups = mutableListOf<Int>()
|
||||
val levels = mutableListOf<TowerScopeLevel>()
|
||||
|
||||
override fun consume(
|
||||
kind: TowerDataKind,
|
||||
towerScopeLevel: TowerScopeLevel,
|
||||
group: Int
|
||||
): ProcessorAction {
|
||||
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
|
||||
consumers += newConsumers
|
||||
newConsumers.clear()
|
||||
kinds += kind
|
||||
groups += group
|
||||
levels += towerScopeLevel
|
||||
|
||||
for (consumer in consumers) {
|
||||
val action = consumer.consume(kind, towerScopeLevel, group)
|
||||
if (action.stop()) {
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
}
|
||||
return ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
fun addConsumer(consumer: TowerDataConsumer): ProcessorAction =
|
||||
run {
|
||||
for (index in kinds.indices) {
|
||||
if (consumer.consume(kinds[index], levels[index], groups[index]).stop()) {
|
||||
return@run ProcessorAction.STOP
|
||||
}
|
||||
}
|
||||
return@run ProcessorAction.NEXT
|
||||
}.also {
|
||||
newConsumers += consumer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ExplicitReceiverTowerDataConsumer<T : ConeSymbol>(
|
||||
val session: FirSession,
|
||||
val name: Name,
|
||||
val token: TowerScopeLevel.Token<T>,
|
||||
val explicitReceiver: ExpressionReceiverValue,
|
||||
val candidateFactory: CandidateFactory
|
||||
val candidateFactory: CandidateFactory,
|
||||
val resultCollector: CandidateCollector
|
||||
) : TowerDataConsumer() {
|
||||
|
||||
|
||||
override fun consume(
|
||||
kind: TowerDataKind,
|
||||
towerScopeLevel: TowerScopeLevel,
|
||||
resultCollector: CandidateCollector,
|
||||
group: Int
|
||||
): ProcessorAction {
|
||||
if (checkSkip(group, resultCollector)) return ProcessorAction.NEXT
|
||||
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
|
||||
return when (kind) {
|
||||
TowerDataKind.EMPTY ->
|
||||
MemberScopeTowerLevel(session, explicitReceiver).processElementsByName(
|
||||
@@ -379,12 +629,17 @@ class ExplicitReceiverTowerDataConsumer<T : ConeSymbol>(
|
||||
name,
|
||||
explicitReceiver = null,
|
||||
processor = object : TowerScopeLevel.TowerScopeLevelProcessor<T> {
|
||||
override fun consumeCandidate(symbol: T, dispatchReceiverValue: ClassDispatchReceiverValue?): ProcessorAction {
|
||||
override fun consumeCandidate(
|
||||
symbol: T,
|
||||
dispatchReceiverValue: ClassDispatchReceiverValue?,
|
||||
implicitExtensionReceiverValue: ImplicitReceiverValue?
|
||||
): ProcessorAction {
|
||||
resultCollector.consumeCandidate(
|
||||
group,
|
||||
candidateFactory.createCandidate(
|
||||
symbol,
|
||||
dispatchReceiverValue,
|
||||
implicitExtensionReceiverValue,
|
||||
ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||
)
|
||||
)
|
||||
@@ -399,12 +654,17 @@ class ExplicitReceiverTowerDataConsumer<T : ConeSymbol>(
|
||||
name,
|
||||
explicitReceiver = explicitReceiver,
|
||||
processor = object : TowerScopeLevel.TowerScopeLevelProcessor<T> {
|
||||
override fun consumeCandidate(symbol: T, dispatchReceiverValue: ClassDispatchReceiverValue?): ProcessorAction {
|
||||
override fun consumeCandidate(
|
||||
symbol: T,
|
||||
dispatchReceiverValue: ClassDispatchReceiverValue?,
|
||||
implicitExtensionReceiverValue: ImplicitReceiverValue?
|
||||
): ProcessorAction {
|
||||
resultCollector.consumeCandidate(
|
||||
group,
|
||||
candidateFactory.createCandidate(
|
||||
symbol,
|
||||
dispatchReceiverValue,
|
||||
implicitExtensionReceiverValue,
|
||||
ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||
)
|
||||
)
|
||||
@@ -422,17 +682,17 @@ class NoExplicitReceiverTowerDataConsumer<T : ConeSymbol>(
|
||||
val session: FirSession,
|
||||
val name: Name,
|
||||
val token: TowerScopeLevel.Token<T>,
|
||||
val candidateFactory: CandidateFactory
|
||||
val candidateFactory: CandidateFactory,
|
||||
val resultCollector: CandidateCollector
|
||||
) : TowerDataConsumer() {
|
||||
|
||||
|
||||
override fun consume(
|
||||
kind: TowerDataKind,
|
||||
towerScopeLevel: TowerScopeLevel,
|
||||
resultCollector: CandidateCollector,
|
||||
group: Int
|
||||
): ProcessorAction {
|
||||
if (checkSkip(group, resultCollector)) return ProcessorAction.NEXT
|
||||
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
|
||||
return when (kind) {
|
||||
|
||||
TowerDataKind.TOWER_LEVEL -> {
|
||||
@@ -441,12 +701,17 @@ class NoExplicitReceiverTowerDataConsumer<T : ConeSymbol>(
|
||||
name,
|
||||
explicitReceiver = null,
|
||||
processor = object : TowerScopeLevel.TowerScopeLevelProcessor<T> {
|
||||
override fun consumeCandidate(symbol: T, dispatchReceiverValue: ClassDispatchReceiverValue?): ProcessorAction {
|
||||
override fun consumeCandidate(
|
||||
symbol: T,
|
||||
dispatchReceiverValue: ClassDispatchReceiverValue?,
|
||||
implicitExtensionReceiverValue: ImplicitReceiverValue?
|
||||
): ProcessorAction {
|
||||
resultCollector.consumeCandidate(
|
||||
group,
|
||||
candidateFactory.createCandidate(
|
||||
symbol,
|
||||
dispatchReceiverValue,
|
||||
implicitExtensionReceiverValue,
|
||||
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
||||
)
|
||||
)
|
||||
@@ -458,7 +723,6 @@ class NoExplicitReceiverTowerDataConsumer<T : ConeSymbol>(
|
||||
else -> ProcessorAction.NEXT
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CallResolver(val typeCalculator: ReturnTypeCalculator, val components: InferenceComponents) {
|
||||
@@ -479,28 +743,41 @@ class CallResolver(val typeCalculator: ReturnTypeCalculator, val components: Inf
|
||||
towerDataConsumer.consume(
|
||||
TowerDataKind.TOWER_LEVEL,
|
||||
MemberScopeTowerLevel(session, implicitReceiverValue),
|
||||
collector, group++
|
||||
group++
|
||||
)
|
||||
|
||||
// This is an equivalent to the old "BothTowerLevelAndImplicitReceiver"
|
||||
towerDataConsumer.consume(
|
||||
TowerDataKind.TOWER_LEVEL,
|
||||
MemberScopeTowerLevel(session, implicitReceiverValue, implicitReceiverValue),
|
||||
collector, group++
|
||||
group++
|
||||
)
|
||||
|
||||
for (scope in scopes!!) {
|
||||
towerDataConsumer.consume(
|
||||
TowerDataKind.TOWER_LEVEL,
|
||||
ScopeTowerLevel(session, scope, implicitReceiverValue),
|
||||
group++
|
||||
)
|
||||
}
|
||||
|
||||
return group
|
||||
}
|
||||
|
||||
fun runTowerResolver(towerDataConsumer: TowerDataConsumer, implicitReceiverValues: List<ImplicitReceiverValue>): CandidateCollector {
|
||||
val collector = CandidateCollector(callInfo!!, components)
|
||||
val collector by lazy { CandidateCollector(components) }
|
||||
lateinit var towerDataConsumer: TowerDataConsumer
|
||||
private lateinit var implicitReceiverValues: List<ImplicitReceiverValue>
|
||||
|
||||
fun runTowerResolver(consumer: TowerDataConsumer, implicitReceiverValues: List<ImplicitReceiverValue>): CandidateCollector {
|
||||
this.implicitReceiverValues = implicitReceiverValues
|
||||
towerDataConsumer = consumer
|
||||
|
||||
var group = 0
|
||||
|
||||
towerDataConsumer.consume(TowerDataKind.EMPTY, TowerScopeLevel.Empty, collector, group++)
|
||||
towerDataConsumer.consume(TowerDataKind.EMPTY, TowerScopeLevel.Empty, group++)
|
||||
|
||||
for (scope in scopes!!) {
|
||||
towerDataConsumer.consume(TowerDataKind.TOWER_LEVEL, ScopeTowerLevel(session, scope), collector, group++)
|
||||
towerDataConsumer.consume(TowerDataKind.TOWER_LEVEL, ScopeTowerLevel(session, scope), group++)
|
||||
}
|
||||
|
||||
var blockDispatchReceivers = false
|
||||
@@ -516,10 +793,11 @@ class CallResolver(val typeCalculator: ReturnTypeCalculator, val components: Inf
|
||||
processImplicitReceiver(towerDataConsumer, implicitReceiverValue, collector, group)
|
||||
}
|
||||
|
||||
|
||||
|
||||
return collector
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -532,7 +810,8 @@ enum class CandidateApplicability {
|
||||
RESOLVED
|
||||
}
|
||||
|
||||
class CandidateCollector(val callInfo: CallInfo, val components: InferenceComponents) {
|
||||
|
||||
open class CandidateCollector(val components: InferenceComponents) {
|
||||
|
||||
val groupNumbers = mutableListOf<Int>()
|
||||
val candidates = mutableListOf<Candidate>()
|
||||
@@ -553,16 +832,34 @@ class CandidateCollector(val callInfo: CallInfo, val components: InferenceCompon
|
||||
): CandidateApplicability {
|
||||
|
||||
val sink = CheckerSinkImpl(components)
|
||||
var finished = false
|
||||
sink.continuation = suspend {
|
||||
for (stage in candidate.callInfo.callKind.sequence()) {
|
||||
stage.check(candidate, sink, candidate.callInfo)
|
||||
}
|
||||
}.createCoroutineUnintercepted(completion = object : Continuation<Unit> {
|
||||
override val context: CoroutineContext
|
||||
get() = EmptyCoroutineContext
|
||||
|
||||
override fun resumeWith(result: Result<Unit>) {
|
||||
result.exceptionOrNull()?.let { throw it }
|
||||
finished = true
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
callInfo.callKind.sequence().forEach {
|
||||
it.check(candidate, sink, callInfo)
|
||||
|
||||
|
||||
while (!finished) {
|
||||
sink.continuation!!.resume(Unit)
|
||||
if (sink.current < CandidateApplicability.SYNTHETIC_RESOLVED) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return sink.current
|
||||
}
|
||||
|
||||
fun consumeCandidate(group: Int, candidate: Candidate) {
|
||||
open fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability {
|
||||
val applicability = getApplicability(group, candidate)
|
||||
|
||||
if (applicability > currentApplicability) {
|
||||
@@ -576,6 +873,8 @@ class CandidateCollector(val callInfo: CallInfo, val components: InferenceCompon
|
||||
candidates.add(candidate)
|
||||
groupNumbers.add(group)
|
||||
}
|
||||
|
||||
return applicability
|
||||
}
|
||||
|
||||
|
||||
@@ -601,6 +900,47 @@ class CandidateCollector(val callInfo: CallInfo, val components: InferenceCompon
|
||||
}
|
||||
}
|
||||
|
||||
class InvokeCandidateCollector(
|
||||
val callResolver: CallResolver,
|
||||
val invokeCallInfo: CallInfo,
|
||||
components: InferenceComponents,
|
||||
val multiplexer: MultiplexerTowerDataConsumer
|
||||
) : CandidateCollector(components) {
|
||||
override fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability {
|
||||
val applicability = super.consumeCandidate(group, candidate)
|
||||
|
||||
if (applicability >= CandidateApplicability.SYNTHETIC_RESOLVED) {
|
||||
|
||||
val session = components.session
|
||||
val boundInvokeCallInfo = CallInfo(
|
||||
invokeCallInfo.callKind,
|
||||
FirQualifiedAccessExpressionImpl(session, null, false).apply {
|
||||
calleeReference = FirNamedReferenceWithCandidate(
|
||||
session,
|
||||
null,
|
||||
(candidate.symbol as ConeCallableSymbol).callableId.callableName,
|
||||
candidate
|
||||
)
|
||||
typeRef = callResolver.typeCalculator.tryCalculateReturnType(candidate.symbol.firUnsafe())
|
||||
},
|
||||
invokeCallInfo.arguments,
|
||||
invokeCallInfo.isSafeCall,
|
||||
invokeCallInfo.typeArguments,
|
||||
session,
|
||||
invokeCallInfo.containingFile,
|
||||
invokeCallInfo.container,
|
||||
invokeCallInfo.typeProvider
|
||||
)
|
||||
val invokeConsumer =
|
||||
createSimpleFunctionConsumer(session, Name.identifier("invoke"), boundInvokeCallInfo, components, callResolver.collector)
|
||||
|
||||
multiplexer.addConsumer(invokeConsumer)
|
||||
}
|
||||
|
||||
return applicability
|
||||
}
|
||||
}
|
||||
|
||||
fun FirCallableDeclaration.dispatchReceiverValue(session: FirSession): ClassDispatchReceiverValue? {
|
||||
// TODO: this is not true at least for inner class constructors
|
||||
if (this is FirConstructor) return null
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||
@@ -14,7 +15,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
|
||||
class CandidateFactory(
|
||||
val inferenceComponents: InferenceComponents,
|
||||
callInfo: CallInfo
|
||||
val callInfo: CallInfo
|
||||
) {
|
||||
|
||||
val baseSystem: ConstraintStorage
|
||||
@@ -31,15 +32,20 @@ class CandidateFactory(
|
||||
fun createCandidate(
|
||||
symbol: ConeSymbol,
|
||||
dispatchReceiverValue: ClassDispatchReceiverValue?,
|
||||
implicitExtensionReceiverValue: ImplicitReceiverValue?,
|
||||
explicitReceiverKind: ExplicitReceiverKind
|
||||
): Candidate {
|
||||
return Candidate(symbol, dispatchReceiverValue, explicitReceiverKind, inferenceComponents, baseSystem)
|
||||
return Candidate(
|
||||
symbol, dispatchReceiverValue, implicitExtensionReceiverValue,
|
||||
explicitReceiverKind, inferenceComponents, baseSystem, callInfo
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun PostponedArgumentsAnalyzer.Context.addSubsystemFromExpression(expression: FirExpression) {
|
||||
when (expression) {
|
||||
is FirFunctionCall -> expression.candidate()?.let { addOtherSystem(it.system.asReadOnlyStorage()) }
|
||||
is FirWrappedArgumentExpression -> addSubsystemFromExpression(expression.expression)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystem
|
||||
|
||||
|
||||
internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
|
||||
override fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val declaration = candidate.symbol.firUnsafe<FirDeclaration>()
|
||||
if (declaration !is FirCallableMemberDeclaration || declaration.typeParameters.isEmpty()) {
|
||||
candidate.substitutor = ConeSubstitutor.Empty
|
||||
@@ -35,7 +35,7 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
|
||||
|
||||
// bad function -- error on declaration side
|
||||
if (csBuilder.hasContradiction) {
|
||||
sink.reportApplicability(CandidateApplicability.INAPPLICABLE) //TODO: auto report it
|
||||
sink.yieldApplicability(CandidateApplicability.INAPPLICABLE) //TODO: auto report it
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class ClassDispatchReceiverValue(val klassSymbol: FirClassSymbol) : ReceiverValu
|
||||
}
|
||||
|
||||
class ExpressionReceiverValue(
|
||||
private val explicitReceiverExpression: FirExpression,
|
||||
val explicitReceiverExpression: FirExpression,
|
||||
val typeProvider: (FirExpression) -> FirTypeRef?
|
||||
) : ReceiverValue {
|
||||
override val type: ConeKotlinType
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
||||
@@ -36,23 +37,41 @@ fun Candidate.computeCompletionMode(
|
||||
return when {
|
||||
// Consider call foo(bar(x)), if return type of bar is a proper one, then we can complete resolve for bar => full completion mode
|
||||
// Otherwise, we shouldn't complete bar until we process call foo
|
||||
system.getBuilder().isProperType(currentReturnType) -> KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.FULL
|
||||
csBuilder.isProperType(currentReturnType) -> KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.FULL
|
||||
|
||||
// Nested call is connected with the outer one through the UPPER constraint (returnType <: expectedOuterType)
|
||||
// This means that there will be no new LOWER constraints =>
|
||||
// it's possible to complete call now if there are proper LOWER constraints
|
||||
system.getBuilder().isTypeVariable(currentReturnType) ->
|
||||
csBuilder.isTypeVariable(currentReturnType) ->
|
||||
if (hasProperNonTrivialLowerConstraints(components, currentReturnType))
|
||||
KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.FULL
|
||||
else
|
||||
KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.PARTIAL
|
||||
|
||||
// Return type has proper equal constraints => there is no need in the outer call
|
||||
containsTypeVariablesWithProperEqualConstraints(components, currentReturnType) -> KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.FULL
|
||||
|
||||
else -> KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.PARTIAL
|
||||
}
|
||||
}
|
||||
|
||||
val Candidate.csBuilder get() = system.getBuilder()
|
||||
|
||||
private fun Candidate.containsTypeVariablesWithProperEqualConstraints(components: InferenceComponents, type: ConeKotlinType): Boolean =
|
||||
with(components.ctx){
|
||||
for ((variableConstructor, variableWithConstraints) in csBuilder.currentStorage().notFixedTypeVariables) {
|
||||
if (!type.contains { it.typeConstructor() == variableConstructor }) continue
|
||||
|
||||
val constraints = variableWithConstraints.constraints
|
||||
val onlyProperEqualConstraints =
|
||||
constraints.isNotEmpty() && constraints.all { it.kind.isEqual() && csBuilder.isProperType(it.type) }
|
||||
|
||||
if (!onlyProperEqualConstraints) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun Candidate.hasProperNonTrivialLowerConstraints(components: InferenceComponents, typeVariable: ConeKotlinType): Boolean {
|
||||
assert(csBuilder.isTypeVariable(typeVariable)) { "$typeVariable is not a type variable" }
|
||||
|
||||
@@ -162,6 +181,7 @@ class ConstraintSystemCompleter(val components: InferenceComponents) {
|
||||
}
|
||||
this.arguments.forEach { it.process(to) }
|
||||
}
|
||||
is FirWrappedArgumentExpression -> this.expression.process(to)
|
||||
// TOOD: WTF?
|
||||
}
|
||||
// if (analyzed) {
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
@@ -45,7 +46,7 @@ open class ConeTypeVariable(name: String) : TypeVariableMarker {
|
||||
val defaultType = ConeTypeVariableType(ConeNullability.NOT_NULL, typeConstructor)
|
||||
}
|
||||
|
||||
class InferenceComponents(val ctx: TypeSystemInferenceExtensionContextDelegate, val session: FirSession) {
|
||||
class InferenceComponents(val ctx: TypeSystemInferenceExtensionContextDelegate, val session: FirSession, val returnTypeCalculator: ReturnTypeCalculator) {
|
||||
private val approximator = object : AbstractTypeApproximator(ctx) {
|
||||
override fun createErrorType(message: String): SimpleTypeMarker {
|
||||
return ConeClassErrorType(message)
|
||||
@@ -59,5 +60,6 @@ class InferenceComponents(val ctx: TypeSystemInferenceExtensionContextDelegate,
|
||||
fun createConstraintSystem(): NewConstraintSystemImpl {
|
||||
return NewConstraintSystemImpl(injector, ctx)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -78,12 +78,11 @@ private fun isFunctionalTypeWithReceiver(typeRef: FirTypeRef) =
|
||||
coneTypeSafe.lookupTag.classId.asString() == "kotlin/ExtensionFunctionType"
|
||||
}
|
||||
|
||||
private val ConeKotlinType.returnType: ConeKotlinType
|
||||
private val ConeKotlinType.returnType: ConeKotlinType?
|
||||
get() {
|
||||
require(this is ConeClassType)
|
||||
val projection = typeArguments.last()
|
||||
require(projection is ConeTypedProjection)
|
||||
return projection.type
|
||||
return (projection as? ConeTypedProjection)?.type
|
||||
}
|
||||
|
||||
private val ConeKotlinType.valueParameterTypes: List<ConeKotlinType?>
|
||||
@@ -130,7 +129,7 @@ private fun extraLambdaInfo(
|
||||
return ResolvedLambdaAtom(argument, isSuspend, receiverType, parameters, returnType, typeVariable.takeIf { newTypeVariableUsed })
|
||||
}
|
||||
|
||||
private fun extractLambdaInfoFromFunctionalType(
|
||||
internal fun extractLambdaInfoFromFunctionalType(
|
||||
expectedType: ConeKotlinType?,
|
||||
expectedTypeRef: FirTypeRef,
|
||||
argument: FirAnonymousFunction
|
||||
@@ -139,8 +138,8 @@ private fun extractLambdaInfoFromFunctionalType(
|
||||
val parameters = extractLambdaParameters(expectedType, argument)
|
||||
|
||||
val argumentAsFunctionExpression = argument//.safeAs<FunctionExpression>()
|
||||
val receiverType = argumentAsFunctionExpression?.receiverType ?: expectedType.receiverType(expectedTypeRef)
|
||||
val returnType = argumentAsFunctionExpression?.returnType ?: expectedType.returnType
|
||||
val receiverType = argumentAsFunctionExpression.receiverType ?: expectedType.receiverType(expectedTypeRef)
|
||||
val returnType = argumentAsFunctionExpression.returnType ?: expectedType.returnType ?: return null
|
||||
|
||||
return ResolvedLambdaAtom(
|
||||
argument,
|
||||
|
||||
@@ -27,6 +27,7 @@ interface LambdaAnalyzer {
|
||||
receiverType: ConeKotlinType?,
|
||||
parameters: List<ConeKotlinType>,
|
||||
expectedReturnType: ConeKotlinType?, // null means, that return type is not proper i.e. it depends on some type variables
|
||||
rawReturnType: ConeKotlinType,
|
||||
stubsForPostponedVariables: Map<TypeVariableMarker, StubTypeMarker>
|
||||
): Pair<List<FirExpression>, InferenceSession>
|
||||
}
|
||||
@@ -93,6 +94,7 @@ class PostponedArgumentsAnalyzer(
|
||||
receiver,
|
||||
parameters,
|
||||
expectedTypeForReturnArguments,
|
||||
rawReturnType,
|
||||
stubsForPostponedVariables
|
||||
)
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firSafeNullable
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
||||
@@ -27,25 +28,26 @@ import java.lang.IllegalStateException
|
||||
|
||||
|
||||
abstract class ResolutionStage {
|
||||
abstract fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo)
|
||||
abstract suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo)
|
||||
}
|
||||
|
||||
abstract class CheckerStage : ResolutionStage()
|
||||
|
||||
internal object CheckExplicitReceiverConsistency : ResolutionStage() {
|
||||
override fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val receiverKind = candidate.explicitReceiverKind
|
||||
val explicitReceiver = callInfo.explicitReceiver
|
||||
// TODO: add invoke cases
|
||||
when (receiverKind) {
|
||||
NO_EXPLICIT_RECEIVER -> {
|
||||
if (explicitReceiver != null) return sink.reportApplicability(CandidateApplicability.WRONG_RECEIVER)
|
||||
if (explicitReceiver != null && explicitReceiver !is FirResolvedQualifier)
|
||||
return sink.yieldApplicability(CandidateApplicability.WRONG_RECEIVER)
|
||||
}
|
||||
EXTENSION_RECEIVER, DISPATCH_RECEIVER -> {
|
||||
if (explicitReceiver == null) return sink.reportApplicability(CandidateApplicability.WRONG_RECEIVER)
|
||||
if (explicitReceiver == null) return sink.yieldApplicability(CandidateApplicability.WRONG_RECEIVER)
|
||||
}
|
||||
BOTH_RECEIVERS -> {
|
||||
if (explicitReceiver == null) return sink.reportApplicability(CandidateApplicability.WRONG_RECEIVER)
|
||||
if (explicitReceiver == null) return sink.yieldApplicability(CandidateApplicability.WRONG_RECEIVER)
|
||||
// Here we should also check additional invoke receiver
|
||||
}
|
||||
}
|
||||
@@ -95,45 +97,57 @@ internal sealed class CheckReceivers : ResolutionStage() {
|
||||
|
||||
abstract fun ExplicitReceiverKind.shouldBeResolvedAsImplicit(): Boolean
|
||||
|
||||
override fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val receiverParameterValue = candidate.getReceiverValue()
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val expectedReceiverParameterValue = candidate.getReceiverValue()
|
||||
val explicitReceiverExpression = callInfo.explicitReceiver
|
||||
val explicitReceiverKind = candidate.explicitReceiverKind
|
||||
|
||||
if (receiverParameterValue != null) {
|
||||
if (expectedReceiverParameterValue != null) {
|
||||
if (explicitReceiverExpression != null && explicitReceiverKind.shouldBeResolvedAsExplicit()) {
|
||||
resolveArgumentExpression(
|
||||
candidate.csBuilder,
|
||||
explicitReceiverExpression,
|
||||
candidate.substitutor.substituteOrSelf(receiverParameterValue.type),
|
||||
explicitReceiverExpression.typeRef,
|
||||
sink,
|
||||
argument = explicitReceiverExpression,
|
||||
expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverParameterValue.type),
|
||||
expectedTypeRef = explicitReceiverExpression.typeRef,
|
||||
sink = sink,
|
||||
isReceiver = true,
|
||||
isSafeCall = callInfo.isSafeCall,
|
||||
typeProvider = callInfo.typeProvider,
|
||||
acceptLambdaAtoms = { candidate.postponedAtoms += it }
|
||||
)
|
||||
} else {
|
||||
val argumentExtensionReceiverValue = candidate.implicitExtensionReceiverValue
|
||||
if (argumentExtensionReceiverValue != null && explicitReceiverKind.shouldBeResolvedAsImplicit()) {
|
||||
resolvePlainArgumentType(
|
||||
candidate.csBuilder,
|
||||
argumentType = argumentExtensionReceiverValue.type,
|
||||
expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverParameterValue.type),
|
||||
sink = sink,
|
||||
isReceiver = true,
|
||||
isSafeCall = callInfo.isSafeCall
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal object MapArguments : ResolutionStage() {
|
||||
override fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val symbol = candidate.symbol as? FirFunctionSymbol ?: return sink.reportApplicability(CandidateApplicability.HIDDEN)
|
||||
val function = symbol.firUnsafe<FirFunction>()
|
||||
val processor = FirCallArgumentsProcessor(function, callInfo.arguments)
|
||||
val mappingResult = processor.process()
|
||||
candidate.argumentMapping = mappingResult.argumentMapping
|
||||
if (!mappingResult.isSuccess) {
|
||||
return sink.reportApplicability(CandidateApplicability.PARAMETER_MAPPING_ERROR)
|
||||
return sink.yieldApplicability(CandidateApplicability.PARAMETER_MAPPING_ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal object CheckArguments : CheckerStage() {
|
||||
override fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val argumentMapping =
|
||||
candidate.argumentMapping ?: throw IllegalStateException("Argument should be already mapped while checking arguments!")
|
||||
for ((argument, parameter) in argumentMapping) {
|
||||
@@ -145,16 +159,16 @@ internal object CheckArguments : CheckerStage() {
|
||||
typeProvider = callInfo.typeProvider,
|
||||
sink = sink
|
||||
)
|
||||
}
|
||||
|
||||
if (candidate.system.hasContradiction) {
|
||||
sink.reportApplicability(CandidateApplicability.INAPPLICABLE)
|
||||
if (candidate.system.hasContradiction) {
|
||||
sink.yieldApplicability(CandidateApplicability.INAPPLICABLE)
|
||||
}
|
||||
sink.yield()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal object DiscriminateSynthetics : CheckerStage() {
|
||||
override fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
if (candidate.symbol is SyntheticSymbol) {
|
||||
sink.reportApplicability(CandidateApplicability.SYNTHETIC_RESOLVED)
|
||||
}
|
||||
@@ -172,7 +186,7 @@ internal object CheckVisibility : CheckerStage() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val symbol = candidate.symbol
|
||||
val declaration = symbol.firSafeNullable<FirMemberDeclaration>()
|
||||
if (declaration != null && !declaration.visibility.isPublicAPI) {
|
||||
@@ -198,7 +212,7 @@ internal object CheckVisibility : CheckerStage() {
|
||||
}
|
||||
|
||||
if (!visible) {
|
||||
sink.reportApplicability(CandidateApplicability.HIDDEN)
|
||||
sink.yieldApplicability(CandidateApplicability.HIDDEN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
package org.jetbrains.kotlin.fir.resolve.transformers
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
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.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
@@ -123,6 +125,10 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
primaryConstructorParametersScope = null
|
||||
val type = regularClass.defaultType()
|
||||
scopes.addIfNotNull(type.scope(session, scopeSession))
|
||||
val companionObject = regularClass.companionObject
|
||||
if (companionObject != null) {
|
||||
scopes.addIfNotNull(symbolProvider.getClassUseSiteMemberScope(companionObject.classId, session, scopeSession))
|
||||
}
|
||||
val result = withLabelAndReceiverType(regularClass.name, regularClass, type) {
|
||||
super.transformRegularClass(regularClass, data)
|
||||
}
|
||||
@@ -159,10 +165,10 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
}
|
||||
FirOperation.SAFE_AS -> {
|
||||
resolved.resultType =
|
||||
resolved.conversionTypeRef.withReplacedConeType(
|
||||
session,
|
||||
resolved.conversionTypeRef.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NULLABLE)
|
||||
)
|
||||
resolved.conversionTypeRef.withReplacedConeType(
|
||||
session,
|
||||
resolved.conversionTypeRef.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NULLABLE)
|
||||
)
|
||||
}
|
||||
else -> error("Unknown type operator")
|
||||
}
|
||||
@@ -249,12 +255,81 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
override fun KotlinTypeMarker.removeExactAnnotation(): KotlinTypeMarker {
|
||||
return this
|
||||
}
|
||||
}, session)
|
||||
}, session, jump)
|
||||
|
||||
private fun <T : FirQualifiedAccess> transformCallee(qualifiedAccess: T): T {
|
||||
private var qualifierStack = mutableListOf<Name>()
|
||||
private var qualifierPartsToDrop = 0
|
||||
|
||||
private fun tryResolveAsQualifier(): FirStatement? {
|
||||
|
||||
val symbolProvider = session.service<FirSymbolProvider>()
|
||||
var qualifierParts = qualifierStack.asReversed().map { it.asString() }
|
||||
var resolved: PackageOrClass?
|
||||
do {
|
||||
resolved = resolveToPackageOrClass(
|
||||
symbolProvider,
|
||||
FqName.fromSegments(qualifierParts)
|
||||
)
|
||||
if (resolved == null)
|
||||
qualifierParts = qualifierParts.dropLast(1)
|
||||
} while (resolved == null && qualifierParts.isNotEmpty())
|
||||
|
||||
if (resolved != null) {
|
||||
qualifierPartsToDrop = qualifierParts.size - 1
|
||||
return FirResolvedQualifierImpl(session, null /* TODO */, resolved.packageFqName, resolved.relativeClassFqName)
|
||||
.apply { resultType = typeForQualifier(this) }
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun typeForQualifier(resolvedQualifier: FirResolvedQualifier): FirTypeRef {
|
||||
val classId = resolvedQualifier.classId
|
||||
val resultType = resolvedQualifier.resultType
|
||||
if (classId != null) {
|
||||
val classSymbol = symbolProvider.getClassLikeSymbolByFqName(classId)!!
|
||||
val declaration = classSymbol.firUnsafe<FirClassLikeDeclaration>()
|
||||
if (declaration is FirClass) {
|
||||
if (declaration.classKind == ClassKind.OBJECT) {
|
||||
return resultType.resolvedTypeFromPrototype(
|
||||
classSymbol.constructType(emptyArray(), false)
|
||||
)
|
||||
} else if (declaration.classKind == ClassKind.ENUM_ENTRY) {
|
||||
val enumClassSymbol = symbolProvider.getClassLikeSymbolByFqName(classSymbol.classId.outerClassId!!)!!
|
||||
return resultType.resolvedTypeFromPrototype(
|
||||
enumClassSymbol.constructType(emptyArray(), false)
|
||||
)
|
||||
} else {
|
||||
if (declaration is FirRegularClass) {
|
||||
val companionObject = declaration.companionObject
|
||||
if (companionObject != null) {
|
||||
return resultType.resolvedTypeFromPrototype(
|
||||
companionObject.symbol.constructType(emptyArray(), false)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: Handle no value type here
|
||||
return resultType.resolvedTypeFromPrototype(
|
||||
StandardClassIds.Unit(symbolProvider).constructType(emptyArray(), isNullable = false)
|
||||
)
|
||||
}
|
||||
|
||||
private fun <T : FirQualifiedAccess> transformCallee(qualifiedAccess: T): FirStatement {
|
||||
val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess
|
||||
if (qualifiedAccess.safe || callee.name.isSpecial) {
|
||||
qualifierStack.clear()
|
||||
} else {
|
||||
qualifierStack.add(callee.name)
|
||||
}
|
||||
|
||||
val qualifiedAccess = qualifiedAccess.transformExplicitReceiver(this, noExpectedType)
|
||||
if (qualifierPartsToDrop > 0) {
|
||||
qualifierPartsToDrop--
|
||||
return qualifiedAccess.explicitReceiver!!
|
||||
}
|
||||
|
||||
val info = CallInfo(
|
||||
CallKind.VariableAccess,
|
||||
@@ -273,16 +348,37 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
val consumer = createVariableAndObjectConsumer(
|
||||
session,
|
||||
callee.name,
|
||||
info, inferenceComponents
|
||||
info, inferenceComponents,
|
||||
resolver.collector
|
||||
)
|
||||
val result = resolver.runTowerResolver(consumer, implicitReceiverStack.asReversed())
|
||||
|
||||
val candidates = result.bestCandidates()
|
||||
val nameReference = createResolvedNamedReference(
|
||||
callee,
|
||||
result.bestCandidates(),
|
||||
candidates,
|
||||
result.currentApplicability
|
||||
)
|
||||
|
||||
if (qualifiedAccess.explicitReceiver == null &&
|
||||
(candidates.size <= 1 && result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED)
|
||||
) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (qualifiedAccess.explicitReceiver == null) {
|
||||
qualifierStack.clear()
|
||||
}
|
||||
|
||||
val resultExpression =
|
||||
qualifiedAccess.transformCalleeReference(StoreNameReference, nameReference) as T
|
||||
if (resultExpression is FirExpression) storeTypeFromCallee(resultExpression)
|
||||
@@ -304,15 +400,14 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
}
|
||||
is FirSuperReference -> {
|
||||
qualifiedAccessExpression.resultType =
|
||||
callee.superTypeRef as? FirResolvedTypeRef ?:
|
||||
implicitReceiverStack.filterIsInstance<ImplicitDispatchReceiverValue>().lastOrNull()
|
||||
callee.superTypeRef as? FirResolvedTypeRef
|
||||
?: implicitReceiverStack.filterIsInstance<ImplicitDispatchReceiverValue>().lastOrNull()
|
||||
?.boundSymbol?.fir?.superTypeRefs?.firstOrNull()
|
||||
?: FirErrorTypeRefImpl(session, qualifiedAccessExpression.psi, "No super type")
|
||||
?: FirErrorTypeRefImpl(session, qualifiedAccessExpression.psi, "No super type")
|
||||
}
|
||||
is FirResolvedCallableReference -> {
|
||||
if (qualifiedAccessExpression.typeRef !is FirResolvedTypeRef) {
|
||||
qualifiedAccessExpression.resultType =
|
||||
jump.tryCalculateReturnType(callee.coneSymbol.firUnsafe<FirCallableDeclaration>())
|
||||
storeTypeFromCallee(qualifiedAccessExpression)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -328,12 +423,78 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
}
|
||||
|
||||
override fun transformAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
if (data == null) return anonymousFunction.compose()
|
||||
if (data is LambdaResolution) return transformAnonymousFunction(anonymousFunction, data).compose()
|
||||
return super.transformAnonymousFunction(anonymousFunction, data)
|
||||
return when (data) {
|
||||
null -> {
|
||||
anonymousFunction.compose()
|
||||
}
|
||||
is LambdaResolution -> {
|
||||
transformAnonymousFunctionWithLambdaResolution(anonymousFunction, data).compose()
|
||||
}
|
||||
is FirTypeRef -> {
|
||||
val resolvedLambdaAtom = (data as? FirResolvedTypeRef)?.let {
|
||||
extractLambdaInfoFromFunctionalType(
|
||||
it.type, it, anonymousFunction
|
||||
)
|
||||
}
|
||||
var af = super.transformAnonymousFunction(anonymousFunction, data).single as FirAnonymousFunction
|
||||
val valueParameters =
|
||||
if (resolvedLambdaAtom == null) af.valueParameters
|
||||
else {
|
||||
val singleParameterType = resolvedLambdaAtom.parameters.singleOrNull()
|
||||
val itParam = when {
|
||||
af.valueParameters.isEmpty() && singleParameterType != null ->
|
||||
FirValueParameterImpl(
|
||||
session,
|
||||
null,
|
||||
Name.identifier("it"),
|
||||
FirResolvedTypeRefImpl(session, null, singleParameterType, emptyList()),
|
||||
defaultValue = null,
|
||||
isCrossinline = false,
|
||||
isNoinline = false,
|
||||
isVararg = false
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
if (itParam != null) {
|
||||
listOf(itParam)
|
||||
} else {
|
||||
af.valueParameters.mapIndexed { index, param ->
|
||||
if (param.returnTypeRef is FirResolvedTypeRef) {
|
||||
param
|
||||
} else {
|
||||
param.transformReturnTypeRef(
|
||||
StoreType,
|
||||
param.returnTypeRef.resolvedTypeFromPrototype(
|
||||
resolvedLambdaAtom.parameters[index]
|
||||
)
|
||||
)
|
||||
param
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
af = af.copy(
|
||||
receiverTypeRef = af.receiverTypeRef?.takeIf { it !is FirImplicitTypeRef }
|
||||
?: resolvedLambdaAtom?.receiver?.let { af.receiverTypeRef?.resolvedTypeFromPrototype(it) },
|
||||
valueParameters = valueParameters,
|
||||
returnTypeRef = (af.returnTypeRef as? FirResolvedTypeRef)
|
||||
?: resolvedLambdaAtom?.returnType?.let { af.returnTypeRef.resolvedTypeFromPrototype(it) }
|
||||
?: af.body?.resultType?.takeIf { af.returnTypeRef is FirImplicitTypeRef }
|
||||
?: FirErrorTypeRefImpl(session, af.psi, "No result type for lambda")
|
||||
)
|
||||
af.replaceTypeRef(af.constructFunctionalTypeRef(session))
|
||||
af.compose()
|
||||
}
|
||||
else -> {
|
||||
super.transformAnonymousFunction(anonymousFunction, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun transformAnonymousFunction(anonymousFunction: FirAnonymousFunction, lambdaResolution: LambdaResolution): FirAnonymousFunction {
|
||||
private fun transformAnonymousFunctionWithLambdaResolution(
|
||||
anonymousFunction: FirAnonymousFunction, lambdaResolution: LambdaResolution
|
||||
): FirAnonymousFunction {
|
||||
val receiverTypeRef = anonymousFunction.receiverTypeRef
|
||||
fun transform(): FirAnonymousFunction {
|
||||
return withScopeCleanup(scopes) {
|
||||
@@ -365,6 +526,8 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
|
||||
private fun resolveCallAndSelectCandidate(functionCall: FirFunctionCall, expectedTypeRef: FirTypeRef?): FirFunctionCall {
|
||||
|
||||
qualifierStack.clear()
|
||||
|
||||
val functionCall =
|
||||
(functionCall.transformExplicitReceiver(this, noExpectedType) as FirFunctionCall)
|
||||
.transformArguments(this, null) as FirFunctionCall
|
||||
@@ -389,11 +552,15 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
resolver.callInfo = info
|
||||
resolver.scopes = (scopes + localScopes).asReversed()
|
||||
|
||||
val consumer = createFunctionConsumer(session, name, info, inferenceComponents)
|
||||
val consumer = createFunctionConsumer(session, name, info, inferenceComponents, resolver.collector, resolver)
|
||||
val result = resolver.runTowerResolver(consumer, implicitReceiverStack.asReversed())
|
||||
val bestCandidates = result.bestCandidates()
|
||||
val reducedCandidates = ConeOverloadConflictResolver(TypeSpecificityComparator.NONE, inferenceComponents)
|
||||
.chooseMaximallySpecificCandidates(bestCandidates, discriminateGenerics = false)
|
||||
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
|
||||
bestCandidates.toSet()
|
||||
} else {
|
||||
ConeOverloadConflictResolver(TypeSpecificityComparator.NONE, inferenceComponents)
|
||||
.chooseMaximallySpecificCandidates(bestCandidates, discriminateGenerics = false)
|
||||
}
|
||||
|
||||
|
||||
// fun isInvoke()
|
||||
@@ -462,6 +629,7 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
receiverType: ConeKotlinType?,
|
||||
parameters: List<ConeKotlinType>,
|
||||
expectedReturnType: ConeKotlinType?,
|
||||
rawReturnType: ConeKotlinType,
|
||||
stubsForPostponedVariables: Map<TypeVariableMarker, StubTypeMarker>
|
||||
): Pair<List<FirExpression>, InferenceSession> {
|
||||
|
||||
@@ -485,10 +653,10 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
valueParameters = lambdaArgument.valueParameters.mapIndexed { index, parameter ->
|
||||
parameter.transformReturnTypeRef(StoreType, parameter.returnTypeRef.resolvedTypeFromPrototype(parameters[index]))
|
||||
parameter
|
||||
} + listOfNotNull(itParam)
|
||||
} + listOfNotNull(itParam),
|
||||
returnTypeRef = lambdaArgument.returnTypeRef.resolvedTypeFromPrototype(rawReturnType)
|
||||
)
|
||||
|
||||
|
||||
val expectedReturnTypeRef = expectedReturnType?.let { newLambdaExpression.returnTypeRef.resolvedTypeFromPrototype(it) }
|
||||
replacements[lambdaArgument] =
|
||||
newLambdaExpression.transformSingle(this@FirBodyResolveTransformer, LambdaResolution(expectedReturnTypeRef))
|
||||
@@ -609,7 +777,11 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
is FirExpression -> statement
|
||||
else -> null
|
||||
}
|
||||
block.resultType = (resultExpression?.resultType as? FirResolvedTypeRef) ?: FirErrorTypeRefImpl(session, null, "No type for block")
|
||||
block.resultType = if (resultExpression == null) {
|
||||
FirImplicitUnitTypeRef(session, block.psi)
|
||||
} else {
|
||||
(resultExpression.resultType as? FirResolvedTypeRef) ?: FirErrorTypeRefImpl(session, null, "No type for block")
|
||||
}
|
||||
|
||||
return block.compose()
|
||||
}
|
||||
@@ -774,7 +946,9 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
if (property.returnTypeRef !is FirImplicitTypeRef && implicitTypeOnly) return property.compose()
|
||||
return withScopeCleanup(localScopes) {
|
||||
localScopes.addIfNotNull(primaryConstructorParametersScope)
|
||||
transformVariable(property, data)
|
||||
(transformVariable(property, data).single as FirProperty).apply {
|
||||
setter?.let { it.valueParameters[0].transformReturnTypeRef(StoreType, property.returnTypeRef) }
|
||||
}.compose()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -795,13 +969,33 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
override fun transformGetClassCall(getClassCall: FirGetClassCall, data: Any?): CompositeTransformResult<FirStatement> {
|
||||
val transformedGetClassCall = super.transformGetClassCall(getClassCall, data).single as FirGetClassCall
|
||||
val kClassSymbol = ClassId.fromString("kotlin/reflect/KClass")(session.service())
|
||||
|
||||
val typeOfExpression = when (val lhs = transformedGetClassCall.argument) {
|
||||
is FirResolvedQualifier -> {
|
||||
val classId = lhs.classId
|
||||
if (classId != null) {
|
||||
val symbol = symbolProvider.getClassLikeSymbolByFqName(classId)!!
|
||||
// TODO: Unify logic?
|
||||
symbol.constructType(
|
||||
Array(symbol.firUnsafe<FirClassLikeDeclaration>().typeParameters.size) {
|
||||
ConeStarProjection
|
||||
},
|
||||
isNullable = false
|
||||
)
|
||||
} else {
|
||||
lhs.resultType.coneTypeUnsafe<ConeKotlinType>()
|
||||
}
|
||||
}
|
||||
else -> lhs.resultType.coneTypeUnsafe<ConeKotlinType>()
|
||||
}
|
||||
|
||||
transformedGetClassCall.resultType =
|
||||
FirResolvedTypeRefImpl(
|
||||
session,
|
||||
null,
|
||||
kClassSymbol.constructType(arrayOf(transformedGetClassCall.argument.resultType.coneTypeUnsafe()), false),
|
||||
emptyList()
|
||||
)
|
||||
FirResolvedTypeRefImpl(
|
||||
session,
|
||||
null,
|
||||
kClassSymbol.constructType(arrayOf(typeOfExpression), false),
|
||||
emptyList()
|
||||
)
|
||||
return transformedGetClassCall.compose()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,16 +7,18 @@ package org.jetbrains.kotlin.fir.resolve.transformers
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.copy
|
||||
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.FirStatement
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||
import org.jetbrains.kotlin.fir.resolve.constructFunctionalTypeRef
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substituteOrNull
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeProjectionWithVariance
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirTypeProjectionWithVarianceImpl
|
||||
@@ -82,4 +84,21 @@ class FirCallCompleterTransformer(
|
||||
|
||||
}
|
||||
|
||||
override fun transformAnonymousFunction(
|
||||
anonymousFunction: FirAnonymousFunction,
|
||||
data: Nothing?
|
||||
): CompositeTransformResult<FirDeclaration> {
|
||||
val initialType = anonymousFunction.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||
if (initialType != null) {
|
||||
val finalType = finalSubstitutor.substituteOrNull(initialType)
|
||||
|
||||
val resultType = anonymousFunction.returnTypeRef.withReplacedConeType(session, finalType)
|
||||
|
||||
anonymousFunction.transformReturnTypeRef(StoreType, resultType)
|
||||
|
||||
anonymousFunction.replaceTypeRef(anonymousFunction.constructFunctionalTypeRef(session))
|
||||
}
|
||||
return super.transformAnonymousFunction(anonymousFunction, data)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -49,32 +49,34 @@ class FirImportResolveTransformer() : FirAbstractTreeTransformer() {
|
||||
}
|
||||
|
||||
private fun transformImportForFqName(fqName: FqName, delegate: FirImport): CompositeTransformResult<FirImport> {
|
||||
val (packageFqName, relativeClassFqName) = resolveToPackageOrClass(fqName) ?: return delegate.compose()
|
||||
val (packageFqName, relativeClassFqName) = resolveToPackageOrClass(symbolProvider, fqName) ?: return delegate.compose()
|
||||
return FirResolvedImportImpl(session, delegate, packageFqName, relativeClassFqName).compose()
|
||||
}
|
||||
|
||||
private fun resolveToPackageOrClass(fqName: FqName): PackageOrClass? {
|
||||
var currentPackage = fqName
|
||||
|
||||
val pathSegments = fqName.pathSegments()
|
||||
var prefixSize = pathSegments.size
|
||||
while (!currentPackage.isRoot) {
|
||||
if (symbolProvider.getPackage(currentPackage) != null) {
|
||||
break
|
||||
}
|
||||
currentPackage = currentPackage.parent()
|
||||
prefixSize--
|
||||
}
|
||||
|
||||
fun resolveToPackageOrClass(symbolProvider: FirSymbolProvider, fqName: FqName): PackageOrClass? {
|
||||
var currentPackage = fqName
|
||||
|
||||
val pathSegments = fqName.pathSegments()
|
||||
var prefixSize = pathSegments.size
|
||||
while (!currentPackage.isRoot && prefixSize > 0) {
|
||||
if (symbolProvider.getPackage(currentPackage) != null) {
|
||||
break
|
||||
}
|
||||
|
||||
if (currentPackage == fqName) return PackageOrClass(currentPackage, null)
|
||||
val relativeClassFqName =
|
||||
FqName.fromSegments((prefixSize until pathSegments.size).map { pathSegments[it].asString() })
|
||||
|
||||
val classId = ClassId(currentPackage, relativeClassFqName, false)
|
||||
if (symbolProvider.getClassLikeSymbolByFqName(classId) == null) return null
|
||||
|
||||
return PackageOrClass(currentPackage, relativeClassFqName)
|
||||
currentPackage = currentPackage.parent()
|
||||
prefixSize--
|
||||
}
|
||||
|
||||
private data class PackageOrClass(val packageFqName: FqName, val relativeClassFqName: FqName?)
|
||||
if (currentPackage == fqName) return PackageOrClass(currentPackage, null)
|
||||
val relativeClassFqName =
|
||||
FqName.fromSegments((prefixSize until pathSegments.size).map { pathSegments[it].asString() })
|
||||
|
||||
val classId = ClassId(currentPackage, relativeClassFqName, false)
|
||||
if (symbolProvider.getClassLikeSymbolByFqName(classId) == null) return null
|
||||
|
||||
return PackageOrClass(currentPackage, relativeClassFqName)
|
||||
}
|
||||
|
||||
data class PackageOrClass(val packageFqName: FqName, val relativeClassFqName: FqName?)
|
||||
|
||||
@@ -43,7 +43,7 @@ class FirStatusResolveTransformer : FirAbstractTreeTransformer() {
|
||||
Modality.FINAL
|
||||
this is FirNamedFunction && body == null ->
|
||||
Modality.ABSTRACT
|
||||
this is FirProperty && initializer == null && getter.body == null && setter.body == null ->
|
||||
this is FirProperty && initializer == null && getter.body == null && setter?.body == null ->
|
||||
Modality.ABSTRACT
|
||||
else ->
|
||||
Modality.OPEN
|
||||
|
||||
@@ -7,8 +7,13 @@ package org.jetbrains.kotlin.fir.scopes.impl
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
||||
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.TowerScopeLevel
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.processConstructors
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
@@ -21,7 +26,23 @@ abstract class FirAbstractImportingScope(session: FirSession, lookupInFir: Boole
|
||||
|
||||
protected val scopeCache = ScopeSession()
|
||||
|
||||
fun <T : ConeCallableSymbol> processCallables(
|
||||
|
||||
private fun getStaticsScope(classId: ClassId): FirScope? {
|
||||
provider.getClassUseSiteMemberScope(classId, session, scopeCache)?.let { return it }
|
||||
|
||||
|
||||
val symbol = provider.getClassLikeSymbolByFqName(classId) ?: error("No scope/symbol for $classId")
|
||||
if (symbol is ConeTypeAliasSymbol) {
|
||||
val expansionSymbol = symbol.firUnsafe<FirTypeAlias>().expandedConeType?.lookupTag?.toSymbol(session)
|
||||
if (expansionSymbol as? ConeClassLikeSymbol != null) {
|
||||
return getStaticsScope(expansionSymbol.classId)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
protected fun <T : ConeCallableSymbol> processCallables(
|
||||
import: FirResolvedImport,
|
||||
name: Name,
|
||||
token: TowerScopeLevel.Token<T>,
|
||||
@@ -31,9 +52,8 @@ abstract class FirAbstractImportingScope(session: FirSession, lookupInFir: Boole
|
||||
|
||||
val classId = import.resolvedClassId
|
||||
if (classId != null) {
|
||||
val scope = getStaticsScope(classId) ?: return ProcessorAction.NEXT
|
||||
|
||||
val scope =
|
||||
provider.getClassUseSiteMemberScope(classId, session, scopeCache) ?: error("No scope for $classId")
|
||||
|
||||
val action = when (token) {
|
||||
TowerScopeLevel.Token.Functions -> scope.processFunctionsByName(
|
||||
@@ -75,7 +95,7 @@ abstract class FirAbstractImportingScope(session: FirSession, lookupInFir: Boole
|
||||
return ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
protected abstract fun <T : ConeCallableSymbol> processCallables(
|
||||
abstract fun <T : ConeCallableSymbol> processCallables(
|
||||
name: Name,
|
||||
token: TowerScopeLevel.Token<T>,
|
||||
processor: (ConeCallableSymbol) -> ProcessorAction
|
||||
|
||||
@@ -5,4 +5,6 @@ public open class NonNullNever : R|kotlin/Any| {
|
||||
|
||||
@R|MyNullable|() public open operator fun foo(@R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.NEVER|()) x: R|kotlin/String|?, @R|MyNullable|() y: R|kotlin/CharSequence|?): R|kotlin/String|?
|
||||
|
||||
public constructor(): R|NonNullNever|
|
||||
|
||||
}
|
||||
|
||||
@@ -5,4 +5,6 @@ public open class Simple : R|kotlin/Any| {
|
||||
|
||||
@R|javax/annotation/Nonnull|() public open operator fun bar(): R|kotlin/String|
|
||||
|
||||
public constructor(): R|Simple|
|
||||
|
||||
}
|
||||
|
||||
@@ -5,4 +5,6 @@ public open class Strange : R|kotlin/Any| {
|
||||
|
||||
@R|javax/annotation/Nonnull|() public open operator fun bar(): R|kotlin/String|
|
||||
|
||||
public constructor(): R|Strange|
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
@R|javax/annotation/Nonnull|() public open operator fun bar(): R|kotlin/String|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class FieldsAreNullable : R|kotlin/Annotation| {
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
@R|spr/ForceFlexibility|() public open operator fun bar(x: R|ft<kotlin/String, kotlin/String?>|!, @R|javax/annotation/Nonnull|() y: R|kotlin/CharSequence|): R|ft<kotlin/String, kotlin/String?>|!
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|spr/UnknownNullability|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class ForceFlexibility : R|kotlin/Annotation| {
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
public open operator fun foobar(@R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.UNKNOWN|()) x: R|ft<kotlin/String, kotlin/String?>|!): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
public abstract interface B : R|kotlin/Any| {
|
||||
public abstract operator fun foo(@R|javax/annotation/Nonnull|() x: R|kotlin/String|): R|kotlin/Unit|
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
public open operator fun baz(@R|javax/annotation/Nonnull|() x: R|kotlin/String|): R|kotlin/String|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
@R|NonNullApi|() public abstract interface AInt : R|kotlin/Any| {
|
||||
public abstract operator fun foo1(x: R|kotlin/String|): R|kotlin/CharSequence|
|
||||
@@ -35,6 +37,8 @@
|
||||
|
||||
public open operator fun baz(x: R|kotlin/String|): R|kotlin/String|
|
||||
|
||||
public constructor(): R|B|
|
||||
|
||||
}
|
||||
@R|NonNullApi|() public open class C : R|A|, R|AInt| {
|
||||
public open operator fun foo1(x: R|kotlin/String|): R|kotlin/String|
|
||||
@@ -47,6 +51,8 @@
|
||||
|
||||
public open operator fun baz(x: R|kotlin/String|): R|kotlin/String|
|
||||
|
||||
public constructor(): R|C|
|
||||
|
||||
}
|
||||
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.TYPE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
@R|javax/annotation/Nullable|() public open operator fun baz(): R|ft<kotlin/collections/MutableList<ft<kotlin/String, kotlin/String?>>?, kotlin/collections/List<ft<kotlin/String, kotlin/String?>>?>|?
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class FieldsAreNullable : R|kotlin/Annotation| {
|
||||
}
|
||||
|
||||
@@ -5,4 +5,6 @@
|
||||
|
||||
@R|javax/annotation/Nonnull|() public open operator fun bar(): R|kotlin/String|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ public open class A : R|kotlin/Any| {
|
||||
|
||||
@R|javax/annotation/Nonnull|() public open operator fun bar(): R|kotlin/String|
|
||||
|
||||
public constructor(): R|test/A|
|
||||
|
||||
}
|
||||
public open class A2 : R|kotlin/Any| {
|
||||
@R|javax/annotation/Nullable|() public open field field: R|kotlin/String|?
|
||||
@@ -13,4 +15,6 @@ public open class A2 : R|kotlin/Any| {
|
||||
|
||||
@R|javax/annotation/Nonnull|() public open operator fun bar(): R|kotlin/String|
|
||||
|
||||
public constructor(): R|test2/A2|
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
@R|spr/Nullable|() public open operator fun baz(): R|ft<kotlin/collections/MutableList<ft<kotlin/String, kotlin/String?>>?, kotlin/collections/List<ft<kotlin/String, kotlin/String?>>?>|?
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.TYPE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ public open class A : R|kotlin/Any| {
|
||||
|
||||
@R|spr/Nullable|() public open operator fun baz(): R|ft<kotlin/collections/MutableList<ft<kotlin/String, kotlin/String?>>?, kotlin/collections/List<ft<kotlin/String, kotlin/String?>>?>|?
|
||||
|
||||
public constructor(): R|test/A|
|
||||
|
||||
}
|
||||
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.PACKAGE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
||||
}
|
||||
|
||||
4
compiler/fir/resolve/testData/enhancement/mapping/AbstractMap.fir.txt
vendored
Normal file
4
compiler/fir/resolve/testData/enhancement/mapping/AbstractMap.fir.txt
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
public abstract class AbstractMap : R|kotlin/Any|, R|kotlin/collections/MutableMap<kotlin/String, kotlin/String>| {
|
||||
public constructor(): R|AbstractMap|
|
||||
|
||||
}
|
||||
3
compiler/fir/resolve/testData/enhancement/mapping/AbstractMap.java
vendored
Normal file
3
compiler/fir/resolve/testData/enhancement/mapping/AbstractMap.java
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
public abstract class AbstractMap implements java.util.Map<String, String> {
|
||||
|
||||
}
|
||||
@@ -7,6 +7,8 @@ public/*package*/ open class A : R|kotlin/Any| {
|
||||
|
||||
public open operator fun bam(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(NOT_ENTRY_EITHER)) arg: R|ft<Mixed, Mixed?>|! = R|/Mixed.NOT_ENTRY_EITHER|): R|ft<Mixed, Mixed?>|!
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
public final enum class Mixed : R|kotlin/Enum<Mixed>| {
|
||||
public final static field NOT_ENTRY_EITHER: R|ft<Mixed, Mixed?>|!
|
||||
|
||||
@@ -7,6 +7,8 @@ public open class A : R|kotlin/Any| {
|
||||
|
||||
public open operator fun fourth(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0B1010)) value: R|ft<kotlin/Long, kotlin/Long?>|! = Long(10)): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
public open class B : R|kotlin/Any| {
|
||||
public open operator fun first(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0x)) value: R|ft<kotlin/Long, kotlin/Long?>|!): R|kotlin/Unit|
|
||||
@@ -17,4 +19,6 @@ public open class B : R|kotlin/Any| {
|
||||
|
||||
public open operator fun fourth(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0B1234)) value: R|ft<kotlin/Long, kotlin/Long?>|!): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|B|
|
||||
|
||||
}
|
||||
|
||||
@@ -3,8 +3,12 @@ public open class A : R|kotlin/Any| {
|
||||
|
||||
public open operator fun bar(@R|kotlin/annotations/jvm/internal/DefaultNull|() x: R|kotlin/Int| = Null(null)): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
public open class B<T> : R|kotlin/Any| {
|
||||
public open operator fun foo(@R|kotlin/annotations/jvm/internal/DefaultNull|() t: R|ft<T, T?>|! = Null(null)): R|kotlin/Unit|
|
||||
|
||||
public constructor<T>(): R|B<T>|
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ public open class A : R|kotlin/Any| {
|
||||
|
||||
public open operator fun baz(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(42)) a: R|ft<kotlin/Int, kotlin/Int?>|! = Int(42)): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
public abstract interface AInt : R|kotlin/Any| {
|
||||
public abstract operator fun foo(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(42)) i: R|ft<kotlin/Int, kotlin/Int?>|! = Int(42)): R|kotlin/Unit|
|
||||
@@ -21,6 +23,10 @@ public open class B : R|A| {
|
||||
|
||||
public open operator fun bam(@R|kotlin/annotations/jvm/internal/DefaultNull|() @R|kotlin/annotations/jvm/internal/DefaultValue|(String(42)) a: R|ft<kotlin/Int, kotlin/Int?>|! = Int(42)): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|B|
|
||||
|
||||
}
|
||||
public open class C : R|A|, R|AInt| {
|
||||
public constructor(): R|C|
|
||||
|
||||
}
|
||||
|
||||
@@ -9,4 +9,6 @@ public/*package*/ open class A : R|kotlin/Any| {
|
||||
|
||||
public open operator fun wrong(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(hello)) i: R|ft<kotlin/Int, kotlin/Int?>|!): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
|
||||
@@ -5,4 +5,6 @@ public/*package*/ open class A : R|kotlin/Any| {
|
||||
|
||||
public open operator fun numberName(@R|kotlin/annotations/jvm/internal/ParameterName|(Int(42)) first: R|ft<kotlin/String, kotlin/String?>|!): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
public open class A : R|kotlin/Any| {
|
||||
public open operator fun connect(@R|kotlin/annotations/jvm/internal/ParameterName|(String(host)) host: R|ft<kotlin/String, kotlin/String?>|!, @R|kotlin/annotations/jvm/internal/ParameterName|(String(port)) port: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
public open class A : R|kotlin/Any| {
|
||||
public open operator fun same(@R|kotlin/annotations/jvm/internal/ParameterName|(String(ok)) first: R|ft<kotlin/String, kotlin/String?>|!, @R|kotlin/annotations/jvm/internal/ParameterName|(String(ok)) second: R|ft<kotlin/String, kotlin/String?>|!): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
|
||||
@@ -3,4 +3,6 @@ public open class A : R|kotlin/Any| {
|
||||
|
||||
public open operator fun numberName(@R|kotlin/annotations/jvm/internal/ParameterName|(String(42)) field: R|ft<kotlin/String, kotlin/String?>|!): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
public/*package*/ open class A : R|kotlin/Any| {
|
||||
public open static operator fun withDefault(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(OK)) arg: R|ft<kotlin/String, kotlin/String?>|! = String(OK)): R|ft<kotlin/String, kotlin/String?>|!
|
||||
|
||||
public constructor(): R|A|
|
||||
|
||||
}
|
||||
|
||||
7
compiler/fir/resolve/testData/resolve/cast.kt
vendored
Normal file
7
compiler/fir/resolve/testData/resolve/cast.kt
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
val x = 1
|
||||
val y = 2 as Any
|
||||
|
||||
val f = fun() = 3 as Any
|
||||
val g = {}
|
||||
val h: (String) -> Boolean = { _ -> false }
|
||||
val hError = { _ -> true }
|
||||
25
compiler/fir/resolve/testData/resolve/cast.txt
vendored
Normal file
25
compiler/fir/resolve/testData/resolve/cast.txt
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
FILE: cast.kt
|
||||
public final val x: R|kotlin/Int| = Int(1)
|
||||
public get(): R|kotlin/Int|
|
||||
public final val y: R|kotlin/Any| = (Int(2) as R|kotlin/Any|)
|
||||
public get(): R|kotlin/Any|
|
||||
public final val f: R|kotlin/Function0<kotlin/Any>| = fun <anonymous>(): R|kotlin/Any| {
|
||||
^ (Int(3) as R|kotlin/Any|)
|
||||
}
|
||||
|
||||
public get(): R|kotlin/Function0<kotlin/Any>|
|
||||
public final val g: R|kotlin/Function0<kotlin/Unit>| = fun <anonymous>(): R|kotlin/Unit| {
|
||||
Unit
|
||||
}
|
||||
|
||||
public get(): R|kotlin/Function0<kotlin/Unit>|
|
||||
public final val h: R|kotlin/Function1<kotlin/String, kotlin/Boolean>| = fun R|kotlin/Function1<kotlin/String, kotlin/Boolean>|.<anonymous>(_: R|kotlin/String|): R|kotlin/Function1<kotlin/String, kotlin/Boolean>| {
|
||||
Boolean(false)
|
||||
}
|
||||
|
||||
public get(): R|kotlin/Function1<kotlin/String, kotlin/Boolean>|
|
||||
public final val hError: R|kotlin/Function1<class error: No type for parameter, kotlin/Boolean>| = fun <anonymous>(_: R|class error: No type for parameter|): R|kotlin/Boolean| {
|
||||
Boolean(true)
|
||||
}
|
||||
|
||||
public get(): R|kotlin/Function1<class error: No type for parameter, kotlin/Boolean>|
|
||||
@@ -23,7 +23,7 @@ FILE: enum.kt
|
||||
|
||||
public final enum entry FIRST : R|SomeEnum| {
|
||||
public constructor(): R|SomeEnum.FIRST| {
|
||||
super<R|SomeEnum|>(R|/O1|)
|
||||
super<R|SomeEnum|>(Q|O1|)
|
||||
}
|
||||
|
||||
public final override fun check(y: R|Some|): R|kotlin/Boolean| {
|
||||
@@ -34,11 +34,11 @@ FILE: enum.kt
|
||||
|
||||
public final enum entry SECOND : R|SomeEnum| {
|
||||
public constructor(): R|SomeEnum.SECOND| {
|
||||
super<R|SomeEnum|>(R|/O2|)
|
||||
super<R|SomeEnum|>(Q|O2|)
|
||||
}
|
||||
|
||||
public final override fun check(y: R|Some|): R|kotlin/Boolean| {
|
||||
^check ==(R|<local>/y|, R|/O2|)
|
||||
^check ==(R|<local>/y|, Q|O2|)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,10 +42,10 @@ FILE: companion.kt
|
||||
|
||||
}
|
||||
public final fun test(): R|kotlin/Unit| {
|
||||
R|/A|.R|/A.Companion.foo|()
|
||||
R|/B|.<Inapplicable(WRONG_RECEIVER): [/A.bar]>#()
|
||||
R|/B|.R|/B.Companion.baz|()
|
||||
lval x: R|kotlin/String| = R|/A|.R|/A.Companion.D|
|
||||
lval y: R|kotlin/String| = R|/B|.R|/B.Companion.C|
|
||||
lval z: <ERROR TYPE REF: Unresolved name: D> = R|/B|.<Unresolved name: D>#
|
||||
Q|A|.R|/A.Companion.foo|()
|
||||
Q|B|.R|/A.bar|()
|
||||
Q|B|.R|/B.Companion.baz|()
|
||||
lval x: R|kotlin/String| = Q|A|.R|/A.Companion.D|
|
||||
lval y: R|kotlin/String| = Q|B|.R|/B.Companion.C|
|
||||
lval z: <ERROR TYPE REF: Unresolved name: D> = Q|B|.<Unresolved name: D>#
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ FILE: explicitReceiver.kt
|
||||
^invoke this#
|
||||
}
|
||||
|
||||
public final fun bar(): R|kotlin/Unit| {
|
||||
^bar R|/x|()
|
||||
public final fun bar(): R|Foo| {
|
||||
^bar R|/Foo.invoke|()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ FILE: explicitReceiver2.kt
|
||||
public final val x: R|Bar| = R|/Bar.Bar|()
|
||||
public get(): R|Bar|
|
||||
|
||||
public final fun bar(): R|kotlin/Unit| {
|
||||
^bar R|/x|()
|
||||
public final fun bar(): R|Foo| {
|
||||
^bar R|/Bar.invoke|()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,5 +7,5 @@ class Foo {
|
||||
|
||||
val x = 0
|
||||
|
||||
fun foo() = x()
|
||||
fun foo() = x() // should resolve to invoke
|
||||
}
|
||||
@@ -8,5 +8,5 @@ class Foo {
|
||||
|
||||
val x = 0
|
||||
|
||||
fun foo() = x()
|
||||
fun foo() = x() // should resolve to fun x
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
class A {
|
||||
fun bar() = foo()
|
||||
fun bar() = foo() // should resolve to invoke
|
||||
|
||||
fun invoke() = this
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ FILE: implicitTypeOrder.kt
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun bar(): <ERROR TYPE REF: Unresolved name: foo> {
|
||||
^bar <Unresolved name: foo>#()
|
||||
public final fun bar(): R|A| {
|
||||
^bar R|/A.invoke|()
|
||||
}
|
||||
|
||||
public final fun invoke(): R|A| {
|
||||
|
||||
7
compiler/fir/resolve/testData/resolve/expresssions/invoke/simple.kt
vendored
Normal file
7
compiler/fir/resolve/testData/resolve/expresssions/invoke/simple.kt
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
class Simple {
|
||||
operator fun invoke(): String = "invoke"
|
||||
}
|
||||
|
||||
fun test(s: Simple) {
|
||||
val result = s()
|
||||
}
|
||||
14
compiler/fir/resolve/testData/resolve/expresssions/invoke/simple.txt
vendored
Normal file
14
compiler/fir/resolve/testData/resolve/expresssions/invoke/simple.txt
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
FILE: simple.kt
|
||||
public final class Simple : R|kotlin/Any| {
|
||||
public constructor(): R|Simple| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final operator fun invoke(): R|kotlin/String| {
|
||||
^invoke String(invoke)
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test(s: R|Simple|): R|kotlin/Unit| {
|
||||
lval result: R|kotlin/String| = R|/Simple.invoke|()
|
||||
}
|
||||
@@ -10,8 +10,8 @@ FILE: objects.kt
|
||||
|
||||
}
|
||||
public final fun use(): R|A| {
|
||||
^use R|/A|
|
||||
^use Q|A|
|
||||
}
|
||||
public final fun bar(): R|A| {
|
||||
^bar R|/A|.R|/A.foo|()
|
||||
^bar Q|A|.R|/A.foo|()
|
||||
}
|
||||
|
||||
33
compiler/fir/resolve/testData/resolve/expresssions/qualifiedExpressions.kt
vendored
Normal file
33
compiler/fir/resolve/testData/resolve/expresssions/qualifiedExpressions.kt
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
package a.b
|
||||
|
||||
class C {
|
||||
object D {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
enum class E {
|
||||
entry
|
||||
}
|
||||
|
||||
fun foo() {}
|
||||
|
||||
val f = 10
|
||||
|
||||
fun main() {
|
||||
a.b.foo()
|
||||
a.b.C.foo()
|
||||
a.b.C.D.foo()
|
||||
val x = a.b.f
|
||||
C.foo()
|
||||
C().foo()
|
||||
val e = a.b.E.entry
|
||||
val e1 = E.entry
|
||||
}
|
||||
57
compiler/fir/resolve/testData/resolve/expresssions/qualifiedExpressions.txt
vendored
Normal file
57
compiler/fir/resolve/testData/resolve/expresssions/qualifiedExpressions.txt
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
FILE: qualifiedExpressions.kt
|
||||
public final class C : R|kotlin/Any| {
|
||||
public constructor(): R|a/b/C| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final object D : R|kotlin/Any| {
|
||||
private constructor(): R|a/b/C.D| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public final companion object Companion : R|kotlin/Any| {
|
||||
private constructor(): R|a/b/C.Companion| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
}
|
||||
public final enum class E : R|kotlin/Enum| {
|
||||
private constructor(): R|a/b/E| {
|
||||
super<R|kotlin/Enum|>()
|
||||
}
|
||||
|
||||
public final enum entry entry : R|kotlin/Any| {
|
||||
public constructor(): R|a/b/E.entry| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
}
|
||||
public final val f: R|kotlin/Int| = Int(10)
|
||||
public get(): R|kotlin/Int|
|
||||
public final fun main(): R|kotlin/Unit| {
|
||||
Q|a/b|.R|a/b/foo|()
|
||||
Q|a/b/C|.R|a/b/C.Companion.foo|()
|
||||
Q|a/b/C.D|.R|a/b/C.D.foo|()
|
||||
lval x: R|kotlin/Int| = Q|a/b|.R|a/b/f|
|
||||
Q|a/b/C|.R|a/b/C.Companion.foo|()
|
||||
R|a/b/C.C|().R|a/b/C.foo|()
|
||||
lval e: R|a/b/E| = Q|a/b/E.entry|
|
||||
lval e1: R|a/b/E| = Q|a/b/E.entry|
|
||||
}
|
||||
13
compiler/fir/resolve/testData/resolve/extension.kt
vendored
Normal file
13
compiler/fir/resolve/testData/resolve/extension.kt
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
fun String.foo() {}
|
||||
|
||||
fun String.bar() {
|
||||
foo()
|
||||
}
|
||||
|
||||
class My {
|
||||
fun bar() {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
fun My.foo() {}
|
||||
18
compiler/fir/resolve/testData/resolve/extension.txt
vendored
Normal file
18
compiler/fir/resolve/testData/resolve/extension.txt
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
FILE: extension.kt
|
||||
public final fun R|kotlin/String|.foo(): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun R|kotlin/String|.bar(): R|kotlin/Unit| {
|
||||
R|/foo|()
|
||||
}
|
||||
public final class My : R|kotlin/Any| {
|
||||
public constructor(): R|My| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun bar(): R|kotlin/Unit| {
|
||||
R|/foo|()
|
||||
}
|
||||
|
||||
}
|
||||
public final fun R|My|.foo(): R|kotlin/Unit| {
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
|
||||
class C
|
||||
class D
|
||||
|
||||
open class A {
|
||||
open fun foo(): A = this
|
||||
@@ -9,12 +10,12 @@ open class A {
|
||||
class B : A() {
|
||||
override fun foo(): B = this
|
||||
fun bar(): B = this // Ambiguity, no override here (really it's just "missing override" and no ambiguity)
|
||||
override fun buz(p: B): B = this //No override as B <!:> A
|
||||
override fun buz(p: C): B = this //No override as C <!:> A
|
||||
|
||||
fun test() {
|
||||
foo()
|
||||
bar()
|
||||
buz()
|
||||
buz(D())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
FILE: simple.kt
|
||||
public final class C : R|kotlin/Any| {
|
||||
public constructor(): R|C| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class D : R|kotlin/Any| {
|
||||
public constructor(): R|D| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public open class A : R|kotlin/Any| {
|
||||
public constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
@@ -30,14 +42,14 @@ FILE: simple.kt
|
||||
^bar this#
|
||||
}
|
||||
|
||||
public final override fun buz(p: R|B|): R|B| {
|
||||
public final override fun buz(p: R|C|): R|B| {
|
||||
^buz this#
|
||||
}
|
||||
|
||||
public final fun test(): R|kotlin/Unit| {
|
||||
R|/B.foo|()
|
||||
R|/B.bar|()
|
||||
<Inapplicable(PARAMETER_MAPPING_ERROR): [/B.buz, /A.buz]>#()
|
||||
<Inapplicable(INAPPLICABLE): [/B.buz, /A.buz]>#(R|/D.D|())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ FILE: arrayFirstOrNull.kt
|
||||
}
|
||||
public final fun <T> R|kotlin/Array<out T>|.firstOrNullX(): R|T|? {
|
||||
^firstOrNullX when () {
|
||||
<Unresolved name: isEmpty>#() -> {
|
||||
R|kotlin/collections/isEmpty|<R|T|>() -> {
|
||||
Null(null)
|
||||
}
|
||||
else -> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FILE: companionLoad.kt
|
||||
public final fun main(): R|kotlin/Unit| {
|
||||
lval y: R|kotlin/Int| = R|kotlin/Int|.R|kotlin/Int.Companion.MAX_VALUE|
|
||||
lval y: R|kotlin/Int| = Q|kotlin/Int|.R|kotlin/Int.Companion.MAX_VALUE|
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
FILE: reflectionClass.kt
|
||||
public final val javaClass: R|java/lang/Class<kotlin/String>| = <getClass>(R|kotlin/String|).R|kotlin/jvm/java|
|
||||
public final val javaClass: R|java/lang/Class<kotlin/String>| = <getClass>(Q|kotlin/String|).R|kotlin/jvm/java|
|
||||
public get(): R|java/lang/Class<kotlin/String>|
|
||||
public final val kotlinClass: R|kotlin/reflect/KClass<kotlin/String>| = <getClass>(R|kotlin/String|)
|
||||
public final val kotlinClass: R|kotlin/reflect/KClass<kotlin/String>| = <getClass>(Q|kotlin/String|)
|
||||
public get(): R|kotlin/reflect/KClass<kotlin/String>|
|
||||
|
||||
34
compiler/fir/resolve/testData/resolve/stdlib/topLevelResolve.kt
vendored
Normal file
34
compiler/fir/resolve/testData/resolve/stdlib/topLevelResolve.kt
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
fun testPlus() {
|
||||
val x = 1 + 2
|
||||
val y = 3.0 + 4.0
|
||||
val z = 5 + 6.0
|
||||
val w = 7.0 + 8
|
||||
val c = 'a' + 1
|
||||
val s = "." + ".."
|
||||
val ss = "" + 1
|
||||
val list = listOf(1, 2, 3) + 4
|
||||
val listAndList = listOf(4, 5, 6) + listOf(7, 8)
|
||||
val mutableList = mutableListOf(9, 10) + listOf(11, 12, 13)
|
||||
val setAndList = setOf(0) + listOf(1, 2)
|
||||
val stringAndList = "" + emptyList<Boolean>()
|
||||
val map = mapOf("" to 1, "." to 2) + (".." to 3)
|
||||
val mapAndMap = mapOf("-" to 4) + mapOf("_" to 5)
|
||||
}
|
||||
|
||||
fun <T> id(arg: T): T = arg
|
||||
|
||||
fun testMap() {
|
||||
val first = listOf(1, 2, 3).map { it * 2 }
|
||||
val second = intArrayOf(4, 5, 6).map { it * 2 }
|
||||
val withId = listOf(1, 2, 3).map { id(it) }
|
||||
val stringToInt = listOf("alpha", "omega").map { it.length }
|
||||
val viaWith = with(listOf(42)) {
|
||||
map { it * it }
|
||||
}
|
||||
}
|
||||
|
||||
fun testWith() {
|
||||
val length = with("") { length }
|
||||
val indices = with("") { indices }
|
||||
val indicesNoWith = "".indices
|
||||
}
|
||||
56
compiler/fir/resolve/testData/resolve/stdlib/topLevelResolve.txt
vendored
Normal file
56
compiler/fir/resolve/testData/resolve/stdlib/topLevelResolve.txt
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
FILE: topLevelResolve.kt
|
||||
public final fun testPlus(): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Int| = Int(1).R|kotlin/Int.plus|(Int(2))
|
||||
lval y: R|kotlin/Double| = Double(3.0).R|kotlin/Double.plus|(Double(4.0))
|
||||
lval z: R|kotlin/Double| = Int(5).R|kotlin/Int.plus|(Double(6.0))
|
||||
lval w: R|kotlin/Double| = Double(7.0).R|kotlin/Double.plus|(Int(8))
|
||||
lval c: R|kotlin/Char| = Char(a).R|kotlin/Char.plus|(Int(1))
|
||||
lval s: R|kotlin/String| = String(.).R|kotlin/String.plus|(String(..))
|
||||
lval ss: R|kotlin/String| = String().R|kotlin/String.plus|(Int(1))
|
||||
lval list: R|kotlin/collections/List<kotlin/Int>| = R|kotlin/collections/listOf|<R|kotlin/Int|>(Int(1), Int(2), Int(3)).R|kotlin/collections/plus|<R|kotlin/Int|>(Int(4))
|
||||
lval listAndList: R|kotlin/collections/List<kotlin/Int>| = R|kotlin/collections/listOf|<R|kotlin/Int|>(Int(4), Int(5), Int(6)).R|kotlin/collections/plus|<R|kotlin/Int|>(R|kotlin/collections/listOf|<R|kotlin/Int|>(Int(7), Int(8)))
|
||||
lval mutableList: R|kotlin/collections/List<kotlin/Int>| = R|kotlin/collections/mutableListOf|<R|kotlin/Int|>(Int(9), Int(10)).R|kotlin/collections/plus|<R|kotlin/Int|>(R|kotlin/collections/listOf|<R|kotlin/Int|>(Int(11), Int(12), Int(13)))
|
||||
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))))
|
||||
}
|
||||
public final fun <T> id(arg: R|T|): R|T| {
|
||||
^id R|<local>/arg|
|
||||
}
|
||||
public final fun testMap(): R|kotlin/Unit| {
|
||||
lval first: R|kotlin/collections/List<kotlin/Int>| = R|kotlin/collections/listOf|<R|kotlin/Int|>(Int(1), Int(2), Int(3)).R|kotlin/collections/map|<R|kotlin/Int|, R|kotlin/Int|>(<L> = map@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Function1<kotlin/Int, kotlin/Int>| {
|
||||
R|<local>/it|.R|kotlin/Int.times|(Int(2))
|
||||
}
|
||||
)
|
||||
lval second: R|kotlin/collections/List<kotlin/Int>| = R|kotlin/intArrayOf|(Int(4), Int(5), Int(6)).R|kotlin/collections/map|<R|kotlin/Int|>(<L> = map@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Function1<kotlin/Int, kotlin/Int>| {
|
||||
R|<local>/it|.R|kotlin/Int.times|(Int(2))
|
||||
}
|
||||
)
|
||||
lval withId: R|kotlin/collections/List<kotlin/Int>| = R|kotlin/collections/listOf|<R|kotlin/Int|>(Int(1), Int(2), Int(3)).R|kotlin/collections/map|<R|kotlin/Int|, R|kotlin/Int|>(<L> = map@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Function1<kotlin/Int, kotlin/Int>| {
|
||||
R|/id|<R|kotlin/Int|>(R|<local>/it|)
|
||||
}
|
||||
)
|
||||
lval stringToInt: R|kotlin/collections/List<kotlin/Int>| = R|kotlin/collections/listOf|<R|kotlin/String|>(String(alpha), String(omega)).R|kotlin/collections/map|<R|kotlin/String|, R|kotlin/Int|>(<L> = map@fun <anonymous>(it: R|kotlin/String|): R|kotlin/Function1<kotlin/String, kotlin/Int>| {
|
||||
R|<local>/it|.R|kotlin/String.length|
|
||||
}
|
||||
)
|
||||
lval viaWith: R|kotlin/collections/List<kotlin/Int>| = R|kotlin/with|<R|kotlin/collections/List<kotlin/Int>|, R|kotlin/collections/List<kotlin/Int>|>(R|kotlin/collections/listOf|<R|kotlin/Int|>(Int(42)), <L> = with@fun R|kotlin/collections/List<kotlin/Int>|.<anonymous>(it: R|kotlin/collections/List<kotlin/Int>|): R|kotlin/Function2<kotlin/collections/List<kotlin/Int>, kotlin/collections/List<kotlin/Int>, kotlin/collections/List<kotlin/Int>>| {
|
||||
R|kotlin/collections/map|<R|kotlin/Int|, R|kotlin/Int|>(<L> = map@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Function1<kotlin/Int, kotlin/Int>| {
|
||||
R|<local>/it|.R|kotlin/Int.times|(R|<local>/it|)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
public final fun testWith(): R|kotlin/Unit| {
|
||||
lval length: R|kotlin/Int| = R|kotlin/with|<R|kotlin/String|, R|kotlin/Int|>(String(), <L> = with@fun R|kotlin/String|.<anonymous>(it: R|kotlin/String|): R|kotlin/Function2<kotlin/String, kotlin/String, kotlin/Int>| {
|
||||
R|kotlin/String.length|
|
||||
}
|
||||
)
|
||||
lval indices: R|kotlin/ranges/IntRange| = R|kotlin/with|<R|kotlin/String|, R|kotlin/ranges/IntRange|>(String(), <L> = with@fun R|kotlin/String|.<anonymous>(it: R|kotlin/String|): R|kotlin/Function2<kotlin/String, kotlin/String, kotlin/ranges/IntRange>| {
|
||||
R|kotlin/text/indices|
|
||||
}
|
||||
)
|
||||
lval indicesNoWith: R|kotlin/ranges/IntRange| = String().R|kotlin/text/indices|
|
||||
}
|
||||
@@ -29,6 +29,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true, "stdlib");
|
||||
}
|
||||
|
||||
@TestMetadata("cast.kt")
|
||||
public void testCast() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/cast.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("companion.kt")
|
||||
public void testCompanion() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/companion.kt");
|
||||
@@ -49,6 +54,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
||||
runTest("compiler/fir/resolve/testData/resolve/enum.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extension.kt")
|
||||
public void testExtension() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/extension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("F.kt")
|
||||
public void testF() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/F.kt");
|
||||
@@ -257,6 +267,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/objects.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("qualifiedExpressions.kt")
|
||||
public void testQualifiedExpressions() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/qualifiedExpressions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receiverConsistency.kt")
|
||||
public void testReceiverConsistency() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/receiverConsistency.kt");
|
||||
@@ -352,6 +367,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/implicitTypeOrder.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("threeReceivers.kt")
|
||||
public void testThreeReceivers() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.kt");
|
||||
|
||||
@@ -79,6 +79,11 @@ public class FirResolveTestCaseWithStdlibGenerated extends AbstractFirResolveTes
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/reflectionClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelResolve.kt")
|
||||
public void testTopLevelResolve() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/topLevelResolve.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeAliasDeserialization.kt")
|
||||
public void testTypeAliasDeserialization() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/typeAliasDeserialization.kt");
|
||||
|
||||
@@ -115,6 +115,24 @@ public class OwnFirTypeEnhancementTestGenerated extends AbstractOwnFirTypeEnhanc
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/resolve/testData/enhancement/mapping")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Mapping extends AbstractOwnFirTypeEnhancementTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("AbstractMap.java")
|
||||
public void testAbstractMap() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/enhancement/mapping/AbstractMap.java");
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMapping() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/enhancement/mapping"), Pattern.compile("^(.+)\\.java$"), TargetBackend.ANY, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/resolve/testData/enhancement/signatureAnnotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -350,8 +350,8 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
println()
|
||||
}
|
||||
if (property.isVar) {
|
||||
property.setter.accept(this)
|
||||
if (property.setter.body == null) {
|
||||
property.setter?.accept(this)
|
||||
if (property.setter?.body == null) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
@@ -930,4 +930,15 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
uncheckedNotNullCast.expression.accept(this)
|
||||
print("!")
|
||||
}
|
||||
|
||||
override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier) {
|
||||
print("Q|")
|
||||
val classId = resolvedQualifier.classId
|
||||
if (classId != null) {
|
||||
print(classId.asString())
|
||||
} else {
|
||||
print(resolvedQualifier.packageFqName.asString().replace(".", "/"))
|
||||
}
|
||||
print("|")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ interface FirProperty : @VisitedSupertype FirDeclaration, FirCallableMemberDecla
|
||||
// Should it be nullable or have some default?
|
||||
val getter: FirPropertyAccessor
|
||||
|
||||
val setter: FirPropertyAccessor
|
||||
val setter: FirPropertyAccessor?
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitProperty(this, data)
|
||||
@@ -32,6 +32,6 @@ interface FirProperty : @VisitedSupertype FirDeclaration, FirCallableMemberDecla
|
||||
initializer?.accept(visitor, data)
|
||||
delegate?.accept(visitor, data)
|
||||
getter.accept(visitor, data)
|
||||
setter.accept(visitor, data)
|
||||
setter?.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.transformInplace
|
||||
import org.jetbrains.kotlin.fir.transformSingle
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitEnumTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -42,7 +43,7 @@ class FirEnumEntryImpl(
|
||||
isData = false,
|
||||
isInline = false
|
||||
), FirEnumEntry {
|
||||
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(session, null)
|
||||
override var typeRef: FirTypeRef = FirImplicitEnumTypeRef(session, null)
|
||||
|
||||
override val arguments = mutableListOf<FirExpression>()
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class FirMemberPropertyImpl(
|
||||
override val isVar: Boolean,
|
||||
override var initializer: FirExpression?,
|
||||
override var getter: FirPropertyAccessor,
|
||||
override var setter: FirPropertyAccessor,
|
||||
override var setter: FirPropertyAccessor?,
|
||||
override var delegate: FirExpression?
|
||||
) : FirAbstractCallableMember(
|
||||
session, psi, name, visibility, modality, isExpect, isActual, isOverride, receiverTypeRef, returnTypeRef
|
||||
@@ -49,7 +49,7 @@ class FirMemberPropertyImpl(
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
||||
getter = getter.transformSingle(transformer, data)
|
||||
setter = setter.transformSingle(transformer, data)
|
||||
setter = setter?.transformSingle(transformer, data)
|
||||
initializer = initializer?.transformSingle(transformer, data)
|
||||
delegate = delegate?.transformSingle(transformer, data)
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.expressions
|
||||
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
interface FirResolvedQualifier : FirExpression {
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitResolvedQualifier(this, data)
|
||||
|
||||
val packageFqName: FqName
|
||||
val relativeClassFqName: FqName?
|
||||
val classId
|
||||
get() = relativeClassFqName?.let {
|
||||
ClassId(packageFqName, it, false)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.expressions.impl
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
class FirResolvedQualifierImpl(
|
||||
session: FirSession,
|
||||
psi: PsiElement?,
|
||||
override val packageFqName: FqName,
|
||||
override val relativeClassFqName: FqName?
|
||||
) : FirResolvedQualifier, FirAbstractExpression(session, psi) {
|
||||
constructor(session: FirSession, psi: PsiElement?, classId: ClassId) : this(
|
||||
session,
|
||||
psi,
|
||||
classId.packageFqName,
|
||||
classId.relativeClassName
|
||||
)
|
||||
}
|
||||
@@ -268,6 +268,10 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
|
||||
return transformJump(returnExpression, data)
|
||||
}
|
||||
|
||||
open fun transformResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: D): CompositeTransformResult<FirStatement> {
|
||||
return transformExpression(resolvedQualifier, data)
|
||||
}
|
||||
|
||||
open fun transformThrowExpression(throwExpression: FirThrowExpression, data: D): CompositeTransformResult<FirStatement> {
|
||||
return transformExpression(throwExpression, data)
|
||||
}
|
||||
@@ -664,6 +668,10 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
|
||||
return transformResolvedImport(resolvedImport, data)
|
||||
}
|
||||
|
||||
final override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: D): CompositeTransformResult<FirElement> {
|
||||
return transformResolvedQualifier(resolvedQualifier, data)
|
||||
}
|
||||
|
||||
final override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: D): CompositeTransformResult<FirElement> {
|
||||
return transformResolvedTypeRef(resolvedTypeRef, data)
|
||||
}
|
||||
|
||||
@@ -268,6 +268,10 @@ abstract class FirVisitor<out R, in D> {
|
||||
return visitJump(returnExpression, data)
|
||||
}
|
||||
|
||||
open fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: D): R {
|
||||
return visitExpression(resolvedQualifier, data)
|
||||
}
|
||||
|
||||
open fun visitThrowExpression(throwExpression: FirThrowExpression, data: D): R {
|
||||
return visitExpression(throwExpression, data)
|
||||
}
|
||||
|
||||
@@ -268,6 +268,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
|
||||
visitJump(returnExpression, null)
|
||||
}
|
||||
|
||||
open fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier) {
|
||||
visitExpression(resolvedQualifier, null)
|
||||
}
|
||||
|
||||
open fun visitThrowExpression(throwExpression: FirThrowExpression) {
|
||||
visitExpression(throwExpression, null)
|
||||
}
|
||||
@@ -664,6 +668,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
|
||||
visitResolvedImport(resolvedImport)
|
||||
}
|
||||
|
||||
final override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: Nothing?) {
|
||||
visitResolvedQualifier(resolvedQualifier)
|
||||
}
|
||||
|
||||
final override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: Nothing?) {
|
||||
visitResolvedTypeRef(resolvedTypeRef)
|
||||
}
|
||||
|
||||
@@ -179,8 +179,8 @@ class NewConstraintSystemImpl(
|
||||
return !type.contains {
|
||||
val capturedType = it.asSimpleType()?.asCapturedType()
|
||||
// TODO: change NewCapturedType to markered one for FE-IR
|
||||
val typeToCheck = if (capturedType is NewCapturedType && capturedType.captureStatus() == CaptureStatus.FROM_EXPRESSION)
|
||||
capturedType.constructor.projection.type
|
||||
val typeToCheck = if (capturedType is CapturedTypeMarker && capturedType.captureStatus() == CaptureStatus.FROM_EXPRESSION)
|
||||
capturedType.typeConstructorProjection().getType()
|
||||
else
|
||||
it
|
||||
|
||||
|
||||
@@ -284,7 +284,11 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
||||
|
||||
// Once NI will be more stabilized, we'll use more specific type
|
||||
|
||||
else -> type.typeConstructorProjection().getType()//.unwrap()
|
||||
else -> {
|
||||
val projection = type.typeConstructorProjection()
|
||||
if (projection.isStarProjection()) intersectTypes(supertypes.toList())
|
||||
else projection.getType()
|
||||
}
|
||||
}
|
||||
val baseSubType = type.lowerType() ?: nothingType()
|
||||
|
||||
@@ -422,7 +426,7 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
||||
when (effectiveVariance) {
|
||||
null -> {
|
||||
return if (conf.errorType) {
|
||||
ErrorUtils.createErrorType(
|
||||
createErrorType(
|
||||
"Inconsistent type: $type ($index parameter has declared variance: ${parameter.getVariance()}, " +
|
||||
"but argument variance is ${argument.getVariance()})"
|
||||
)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
public final class ArrayTypeVariance : R|kotlin/Any| {
|
||||
public final operator fun toArray(p0: R|kotlin/Array<ft<kotlin/Any, kotlin/Any?>>|): R|kotlin/Array<ft<kotlin/Any, kotlin/Any?>>|
|
||||
|
||||
public constructor(): R|test/ArrayTypeVariance|
|
||||
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
public abstract class ClassDoesNotOverrideMethod : R|java/util/Date| {
|
||||
public constructor(): R|test/ClassDoesNotOverrideMethod|
|
||||
|
||||
}
|
||||
|
||||
@@ -3,4 +3,6 @@ public final class ClassWithConstVal : R|kotlin/Any| {
|
||||
|
||||
public final field f2: R|kotlin/Int|
|
||||
|
||||
public constructor(): R|test/ClassWithConstVal|
|
||||
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
public final class ClassWithTypeP<P> : R|kotlin/Any| {
|
||||
public constructor<P>(): R|test/ClassWithTypeP<P>|
|
||||
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
public abstract class ClassWithTypePExtendsIterableP<P> : R|kotlin/Any|, R|kotlin/collections/Iterable<P>| {
|
||||
public abstract class ClassWithTypePExtendsIterableP<P> : R|kotlin/Any|, R|kotlin/collections/MutableIterable<P>| {
|
||||
public constructor<P>(): R|test/ClassWithTypePExtendsIterableP<P>|
|
||||
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
public final class ClassWithTypePP<P, Q : R|P|> : R|kotlin/Any| {
|
||||
public final class ClassWithTypePP<P, Q : R|P|, R|P|> : R|kotlin/Any| {
|
||||
public constructor<P, Q : R|P|, R|P|>(): R|test/ClassWithTypePP<P, Q>|
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user