[FIR] Initialize outer type parameters for local classes
This commit is contained in:
committed by
TeamCityServer
parent
38820d3e41
commit
e52a410599
+1
-3
@@ -34,9 +34,7 @@ internal class FirDesignatedAnnotationArgumentsResolveTransformerForIDE(
|
||||
}
|
||||
}
|
||||
is FirRegularClass -> {
|
||||
context.withContainingClass(nextElement) {
|
||||
moveNextDeclaration(designationIterator)
|
||||
}
|
||||
moveNextDeclaration(designationIterator)
|
||||
}
|
||||
is FirEnumEntry -> {
|
||||
context.forEnumEntry {
|
||||
|
||||
+6
@@ -11345,6 +11345,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/generics/kt9985.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localClassWithTypeArgumentFromFunction.kt")
|
||||
public void testLocalClassWithTypeArgumentFromFunction() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Projections.kt")
|
||||
public void testProjections() throws Exception {
|
||||
|
||||
@@ -39,8 +39,8 @@ FILE: throwableSubclass.kt
|
||||
}
|
||||
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
local final class Test7 : R|kotlin/Throwable| {
|
||||
public constructor(): R|Test5.Test7| {
|
||||
local final class Test7<T, B> : R|kotlin/Throwable| {
|
||||
public constructor(): R|Test5.Test7<T, B>| {
|
||||
super<R|kotlin/Throwable|>()
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ FILE: throwableSubclass.kt
|
||||
|
||||
}
|
||||
public final fun <Z> topLevelFun(): R|kotlin/Unit| {
|
||||
local final class Test8 : R|kotlin/Error| {
|
||||
public constructor(): R|Test8| {
|
||||
local final class Test8<Z> : R|kotlin/Error| {
|
||||
public constructor(): R|Test8<Z>| {
|
||||
super<R|kotlin/Error|>()
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -11345,6 +11345,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/generics/kt9985.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localClassWithTypeArgumentFromFunction.kt")
|
||||
public void testLocalClassWithTypeArgumentFromFunction() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Projections.kt")
|
||||
public void testProjections() throws Exception {
|
||||
|
||||
+6
@@ -11345,6 +11345,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/generics/kt9985.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localClassWithTypeArgumentFromFunction.kt")
|
||||
public void testLocalClassWithTypeArgumentFromFunction() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Projections.kt")
|
||||
public void testProjections() throws Exception {
|
||||
|
||||
+3
@@ -1102,6 +1102,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
}
|
||||
|
||||
val CASTS_AND_IS_CHECKS by object : DiagnosticGroup("Casts and is-checks") {
|
||||
val CANNOT_CHECK_FOR_ERASED by error<PsiElement> {
|
||||
parameter<ConeKotlinType>("type")
|
||||
}
|
||||
val USELESS_CAST by warning<KtBinaryExpressionWithTypeRHS>(PositioningStrategy.AS_TYPE)
|
||||
val USELESS_IS_CHECK by warning<KtElement> {
|
||||
parameter<Boolean>("compileTimeCheckResult")
|
||||
|
||||
@@ -590,6 +590,7 @@ object FirErrors {
|
||||
val USELESS_ELVIS_RIGHT_IS_NULL by warning0<KtBinaryExpression>(SourceElementPositioningStrategies.USELESS_ELVIS)
|
||||
|
||||
// Casts and is-checks
|
||||
val CANNOT_CHECK_FOR_ERASED by error1<PsiElement, ConeKotlinType>()
|
||||
val USELESS_CAST by warning0<KtBinaryExpressionWithTypeRHS>(SourceElementPositioningStrategies.AS_TYPE)
|
||||
val USELESS_IS_CHECK by warning1<KtElement, Boolean>()
|
||||
val IS_ENUM_ENTRY by error0<KtTypeReference>()
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.resolve.isValidTypeParameterFromOuterClass
|
||||
import org.jetbrains.kotlin.fir.resolve.isValidTypeParameterFromOuterDeclaration
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.toTypeProjections
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
@@ -47,7 +47,7 @@ object FirOuterClassArgumentsRequiredChecker : FirRegularClassChecker() {
|
||||
|
||||
for (index in typeArguments.size until typeParameters.size) {
|
||||
val typeParameter = typeParameters[index]
|
||||
if (!isValidTypeParameterFromOuterClass(typeParameter, declaration, context.session)) {
|
||||
if (!isValidTypeParameterFromOuterDeclaration(typeParameter, declaration, context.session)) {
|
||||
val outerClass = typeParameter.containingDeclarationSymbol as? FirRegularClassSymbol ?: break
|
||||
reporter.reportOn(typeRef.source, FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED, outerClass, context)
|
||||
break
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ object FirThrowableSubclassChecker : FirClassChecker() {
|
||||
reporter.reportOn(declaration.typeParameters.firstOrNull()?.source, FirErrors.GENERIC_THROWABLE_SUBCLASS, context)
|
||||
|
||||
val source = when {
|
||||
(declaration as? FirRegularClass)?.isInner == true -> declaration.source
|
||||
(declaration as? FirRegularClass)?.let { it.isInner || it.isLocal } == true -> declaration.source
|
||||
declaration is FirAnonymousObject -> (declaration.declarations.firstOrNull())?.source
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -8,11 +8,13 @@ package org.jetbrains.kotlin.fir.scopes.impl
|
||||
import kotlinx.collections.immutable.PersistentMap
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.BACKING_FIELD
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirVariable
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
@@ -24,29 +26,30 @@ import org.jetbrains.kotlin.name.Name
|
||||
class FirLocalScope private constructor(
|
||||
val properties: PersistentMap<Name, FirVariableSymbol<*>>,
|
||||
val functions: PersistentMultimap<Name, FirNamedFunctionSymbol>,
|
||||
val classes: PersistentMap<Name, FirRegularClassSymbol>
|
||||
val classes: PersistentMap<Name, FirRegularClassSymbol>,
|
||||
val useSiteSession: FirSession
|
||||
) : FirContainingNamesAwareScope() {
|
||||
constructor() : this(persistentMapOf(), PersistentMultimap(), persistentMapOf())
|
||||
constructor(session: FirSession) : this(persistentMapOf(), PersistentMultimap(), persistentMapOf(), session)
|
||||
|
||||
fun storeClass(klass: FirRegularClass): FirLocalScope {
|
||||
fun storeClass(klass: FirRegularClass, session: FirSession): FirLocalScope {
|
||||
return FirLocalScope(
|
||||
properties, functions, classes.put(klass.name, klass.symbol)
|
||||
properties, functions, classes.put(klass.name, klass.symbol), session
|
||||
)
|
||||
}
|
||||
|
||||
fun storeFunction(function: FirSimpleFunction): FirLocalScope {
|
||||
fun storeFunction(function: FirSimpleFunction, session: FirSession): FirLocalScope {
|
||||
return FirLocalScope(
|
||||
properties, functions.put(function.name, function.symbol), classes
|
||||
properties, functions.put(function.name, function.symbol), classes, session
|
||||
)
|
||||
}
|
||||
|
||||
fun storeVariable(variable: FirVariable): FirLocalScope {
|
||||
fun storeVariable(variable: FirVariable, session: FirSession): FirLocalScope {
|
||||
return FirLocalScope(
|
||||
properties.put(variable.name, variable.symbol), functions, classes
|
||||
properties.put(variable.name, variable.symbol), functions, classes, session
|
||||
)
|
||||
}
|
||||
|
||||
fun storeBackingField(property: FirProperty): FirLocalScope {
|
||||
fun storeBackingField(property: FirProperty, session: FirSession): FirLocalScope {
|
||||
val enhancedProperties = property.backingField?.symbol?.let {
|
||||
properties.put(BACKING_FIELD, it)
|
||||
}
|
||||
@@ -54,7 +57,8 @@ class FirLocalScope private constructor(
|
||||
return FirLocalScope(
|
||||
enhancedProperties ?: properties,
|
||||
functions,
|
||||
classes
|
||||
classes,
|
||||
session
|
||||
)
|
||||
}
|
||||
|
||||
@@ -74,7 +78,8 @@ class FirLocalScope private constructor(
|
||||
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
||||
val klass = classes[name]
|
||||
if (klass != null) {
|
||||
processor(klass, ConeSubstitutor.Empty)
|
||||
val substitution = klass.typeParameterSymbols.associateWith { it.toConeType() }
|
||||
processor(klass, ConeSubstitutorByMap(substitution, useSiteSession))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -436,7 +436,7 @@ class DeclarationsConverter(
|
||||
|
||||
typeParameterList?.let { firTypeParameters += convertTypeParameters(it, typeConstraints, classSymbol) }
|
||||
|
||||
withCapturedTypeParameters(status.isInner, firTypeParameters) {
|
||||
withCapturedTypeParameters(status.isInner || isLocal, firTypeParameters) {
|
||||
buildRegularClass {
|
||||
source = classNode.toFirSourceElement()
|
||||
moduleData = baseModuleData
|
||||
|
||||
@@ -1044,7 +1044,7 @@ open class RawFirBuilder(
|
||||
isExternal = classOrObject.hasModifier(EXTERNAL_KEYWORD)
|
||||
}
|
||||
|
||||
withCapturedTypeParameters(status.isInner, listOf()) {
|
||||
withCapturedTypeParameters(status.isInner || isLocal, listOf()) {
|
||||
buildRegularClass {
|
||||
source = classOrObject.toFirSourceElement()
|
||||
moduleData = baseModuleData
|
||||
@@ -1060,7 +1060,7 @@ open class RawFirBuilder(
|
||||
|
||||
context.appendOuterTypeParameters(ignoreLastLevel = true, typeParameters)
|
||||
context.pushFirTypeParameters(
|
||||
status.isInner,
|
||||
status.isInner || isLocal,
|
||||
typeParameters.subList(0, classOrObject.typeParameters.size)
|
||||
)
|
||||
|
||||
|
||||
@@ -49,8 +49,8 @@ class Context<T> {
|
||||
val dispatchReceiverTypesStack = mutableListOf<ConeClassLikeType>()
|
||||
var containerIsExpect: Boolean = false
|
||||
|
||||
fun pushFirTypeParameters(notNested: Boolean, parameters: List<FirTypeParameterRef>) {
|
||||
capturedTypeParameters.add(StatusFirTypeParameterSymbolList(notNested, parameters.map { it.symbol }))
|
||||
fun pushFirTypeParameters(isInnerOrLocal: Boolean, parameters: List<FirTypeParameterRef>) {
|
||||
capturedTypeParameters.add(StatusFirTypeParameterSymbolList(isInnerOrLocal, parameters.map { it.symbol }))
|
||||
}
|
||||
|
||||
fun popFirTypeParameters() {
|
||||
@@ -68,7 +68,7 @@ class Context<T> {
|
||||
}
|
||||
}
|
||||
|
||||
if (!element.notNested) {
|
||||
if (!element.isInnerOrLocal) {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -119,5 +119,5 @@ class Context<T> {
|
||||
}
|
||||
}
|
||||
|
||||
data class StatusFirTypeParameterSymbolList(val notNested: Boolean, val list: List<FirTypeParameterSymbol> = listOf())
|
||||
data class StatusFirTypeParameterSymbolList(val isInnerOrLocal: Boolean, val list: List<FirTypeParameterSymbol> = listOf())
|
||||
}
|
||||
|
||||
@@ -466,20 +466,3 @@ fun FirFunction.getAsForbiddenNamedArgumentsTarget(session: FirSession): Forbidd
|
||||
// org.jetbrains.kotlin.fir.serialization.FirElementSerializer.functionProto
|
||||
// org.jetbrains.kotlin.fir.serialization.FirElementSerializer.constructorProto
|
||||
fun FirFunction.getHasStableParameterNames(session: FirSession): Boolean = getAsForbiddenNamedArgumentsTarget(session) == null
|
||||
|
||||
|
||||
|
||||
fun FirClassLikeDeclaration.getActualTypeParametersCount(session: FirSession): Int {
|
||||
var result = (if (this is FirTypeAlias) this.typeParameters else (this as FirClass).typeParameters).size
|
||||
|
||||
if (this is FirRegularClass && !isInner) {
|
||||
return result
|
||||
}
|
||||
|
||||
val containingClass = getContainingDeclaration(session) as? FirRegularClass
|
||||
if (containingClass != null) {
|
||||
result -= containingClass.typeParameters.size
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
+68
-43
@@ -197,7 +197,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
symbol: FirBasedSymbol<*>?,
|
||||
substitutor: ConeSubstitutor?,
|
||||
areBareTypesAllowed: Boolean,
|
||||
topDeclaration: FirRegularClass?,
|
||||
topContainer: FirDeclaration?,
|
||||
isOperandOfIsOperator: Boolean
|
||||
): ConeKotlinType {
|
||||
if (symbol == null || symbol !is FirClassifierSymbol<*>) {
|
||||
@@ -240,14 +240,25 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
if (!isPossibleBareType) {
|
||||
val actualSubstitutor = substitutor ?: ConeSubstitutor.Empty
|
||||
|
||||
val typeParameters = calculateTypeParameters(symbol)
|
||||
val originalTypeParameters = collectTypeParameters(symbol)
|
||||
|
||||
val (typeParametersAlignedToQualifierParts, outerClasses) = getClassesAlignedToQualifierParts(symbol, qualifier, session)
|
||||
val (typeParametersAlignedToQualifierParts, outerDeclarations) = getClassesAlignedToQualifierParts(
|
||||
symbol,
|
||||
qualifier,
|
||||
session
|
||||
)
|
||||
|
||||
for ((index, typeParameter) in typeParameters.withIndex()) {
|
||||
val actualTypeParametersCount =
|
||||
when (symbol) {
|
||||
is FirTypeAliasSymbol ->
|
||||
outerDeclarations.sumOf { it?.let { d -> getActualTypeParametersCount(d) } ?: 0 }
|
||||
else -> (symbol as FirClassSymbol<*>).typeParameterSymbols.size
|
||||
}
|
||||
|
||||
for ((typeParameterIndex, typeParameter) in originalTypeParameters.withIndex()) {
|
||||
val (parameterClass, qualifierPartIndex) = typeParametersAlignedToQualifierParts[typeParameter.symbol] ?: continue
|
||||
|
||||
if (index < typeArgumentsCount) {
|
||||
if (typeParameterIndex < typeArgumentsCount) {
|
||||
// Check if type argument matches type parameter in respective qualifier part
|
||||
val qualifierPartArgumentsCount = qualifier[qualifierPartIndex].typeArgumentList.typeArguments.size
|
||||
createDiagnosticsIfExists(
|
||||
@@ -261,12 +272,18 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
}
|
||||
|
||||
if (typeParameter !is FirOuterClassTypeParameterRef ||
|
||||
isValidTypeParameterFromOuterClass(typeParameter.symbol, topDeclaration, session)
|
||||
isValidTypeParameterFromOuterDeclaration(typeParameter.symbol, topContainer, session)
|
||||
) {
|
||||
val type = ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(typeParameter.symbol), isNullable = false)
|
||||
val substituted = actualSubstitutor.substituteOrNull(type)
|
||||
if (substituted == null) {
|
||||
createDiagnosticsIfExists(parameterClass, qualifierPartIndex, symbol, typeRef)?.let { return it }
|
||||
createDiagnosticsIfExists(
|
||||
parameterClass,
|
||||
qualifierPartIndex,
|
||||
symbol,
|
||||
typeRef,
|
||||
qualifierPartArgumentsCount = null
|
||||
)?.let { return it }
|
||||
} else {
|
||||
allTypeArguments.add(substituted)
|
||||
}
|
||||
@@ -276,15 +293,16 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
}
|
||||
|
||||
// Check rest type arguments
|
||||
if (typeArgumentsCount > typeParameters.size) {
|
||||
if (typeArgumentsCount > actualTypeParametersCount) {
|
||||
for (index in qualifier.indices) {
|
||||
if (qualifier[index].typeArgumentList.typeArguments.isNotEmpty()) {
|
||||
val parameterClass = outerClasses.elementAtOrNull(index)
|
||||
val parameterClass = outerDeclarations.elementAtOrNull(index)
|
||||
createDiagnosticsIfExists(
|
||||
parameterClass,
|
||||
index,
|
||||
symbol,
|
||||
typeRef
|
||||
typeRef,
|
||||
qualifierPartArgumentsCount = null
|
||||
)?.let { return it }
|
||||
}
|
||||
}
|
||||
@@ -304,43 +322,43 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateTypeParameters(symbol: FirClassLikeSymbol<*>): List<FirTypeParameterRef> {
|
||||
return if (symbol is FirTypeAliasSymbol) {
|
||||
val typeAliasFir = symbol.fir
|
||||
val typeAliasTypeParameters = typeAliasFir.typeParameters.toMutableList()
|
||||
val fullyExpandedClass = typeAliasFir.fullyExpandedClass(session)
|
||||
val newTypeParameters: MutableList<FirTypeParameterRef>
|
||||
private fun collectTypeParameters(symbol: FirClassLikeSymbol<*>): List<FirTypeParameterRef> {
|
||||
if (symbol is FirClassSymbol<*>) {
|
||||
return symbol.fir.typeParameters
|
||||
}
|
||||
|
||||
if (fullyExpandedClass != null) { // TODO: Should not be null, move to resolver?
|
||||
val expandedTypeRef = typeAliasFir.expandedTypeRef
|
||||
require(symbol is FirTypeAliasSymbol)
|
||||
|
||||
fun checkTypeArguments(typeArgument: ConeTypeProjection) {
|
||||
when (typeArgument) {
|
||||
is ConeTypeParameterType -> typeAliasTypeParameters.removeIf { it.symbol == typeArgument.lookupTag.symbol }
|
||||
is ConeClassLikeType -> {
|
||||
for (subTypeArgument in typeArgument.typeArguments) {
|
||||
checkTypeArguments(subTypeArgument)
|
||||
}
|
||||
}
|
||||
is ConeKotlinTypeProjection -> checkTypeArguments(typeArgument.type)
|
||||
else -> {
|
||||
val typeAliasFir = symbol.fir
|
||||
val typeAliasTypeParameters = typeAliasFir.typeParameters.toMutableList()
|
||||
val fullyExpandedClass = typeAliasFir.fullyExpandedClass(session)
|
||||
val newTypeParameters = if (fullyExpandedClass != null) { // TODO: Should not be null, move to resolver?
|
||||
val expandedTypeRef = typeAliasFir.expandedTypeRef
|
||||
|
||||
fun checkTypeArguments(typeArgument: ConeTypeProjection) {
|
||||
when (typeArgument) {
|
||||
is ConeTypeParameterType -> typeAliasTypeParameters.removeIf { it.symbol == typeArgument.lookupTag.symbol }
|
||||
is ConeClassLikeType -> {
|
||||
for (subTypeArgument in typeArgument.typeArguments) {
|
||||
checkTypeArguments(subTypeArgument)
|
||||
}
|
||||
}
|
||||
is ConeKotlinTypeProjection -> checkTypeArguments(typeArgument.type)
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
|
||||
checkTypeArguments(expandedTypeRef.coneType)
|
||||
newTypeParameters = fullyExpandedClass.typeParameters.toMutableList()
|
||||
} else {
|
||||
newTypeParameters = mutableListOf()
|
||||
}
|
||||
|
||||
for (typeParameter in typeAliasTypeParameters) {
|
||||
newTypeParameters.add(typeParameter)
|
||||
}
|
||||
newTypeParameters
|
||||
checkTypeArguments(expandedTypeRef.coneType)
|
||||
fullyExpandedClass.typeParameters.toMutableList()
|
||||
} else {
|
||||
(symbol as FirClassSymbol<*>).fir.typeParameters
|
||||
mutableListOf()
|
||||
}
|
||||
|
||||
for (typeParameter in typeAliasTypeParameters) {
|
||||
newTypeParameters.add(typeParameter)
|
||||
}
|
||||
return newTypeParameters
|
||||
}
|
||||
|
||||
@OptIn(SymbolInternals::class)
|
||||
@@ -373,8 +391,10 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
|
||||
for (index in reversedOuterClasses.indices) {
|
||||
currentClassLikeDeclaration = reversedOuterClasses[index]
|
||||
val typeParameters = if (currentClassLikeDeclaration is FirTypeAlias) currentClassLikeDeclaration.typeParameters else
|
||||
(currentClassLikeDeclaration as? FirClass)?.typeParameters
|
||||
val typeParameters = when (currentClassLikeDeclaration) {
|
||||
is FirTypeAlias -> currentClassLikeDeclaration.typeParameters
|
||||
else -> (currentClassLikeDeclaration as? FirClass)?.typeParameters
|
||||
}
|
||||
if (currentClassLikeDeclaration != null && typeParameters != null) {
|
||||
for (typeParameter in typeParameters) {
|
||||
val typeParameterSymbol = typeParameter.symbol
|
||||
@@ -404,10 +424,10 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
qualifierPartIndex: Int,
|
||||
symbol: FirClassLikeSymbol<*>,
|
||||
userTypeRef: FirUserTypeRef,
|
||||
qualifierPartArgumentsCount: Int? = null
|
||||
qualifierPartArgumentsCount: Int?
|
||||
): ConeClassErrorType? {
|
||||
// TODO: It should be TYPE_ARGUMENTS_NOT_ALLOWED diagnostics when parameterClass is null
|
||||
val actualTypeParametersCount = (parameterClass ?: symbol.fir).getActualTypeParametersCount(session)
|
||||
val actualTypeParametersCount = getActualTypeParametersCount(parameterClass ?: symbol.fir)
|
||||
|
||||
if (qualifierPartArgumentsCount == null || actualTypeParametersCount != qualifierPartArgumentsCount) {
|
||||
val source = getTypeArgumentsOrNameSource(userTypeRef, qualifierPartIndex)
|
||||
@@ -425,6 +445,11 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getActualTypeParametersCount(element: FirClassLikeDeclaration): Int {
|
||||
return (element as FirTypeParameterRefsOwner).typeParameters
|
||||
.count { it !is FirOuterClassTypeParameterRef }
|
||||
}
|
||||
|
||||
private fun getTypeArgumentsOrNameSource(typeRef: FirUserTypeRef, qualifierIndex: Int?): KtSourceElement? {
|
||||
val qualifierPart = if (qualifierIndex != null) typeRef.qualifier.elementAtOrNull(qualifierIndex) else null
|
||||
val typeArgumentsList = qualifierPart?.typeArgumentList
|
||||
@@ -475,7 +500,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
symbol,
|
||||
substitutor,
|
||||
areBareTypesAllowed,
|
||||
scopeClassDeclaration.containingDeclarations.lastOrNull(),
|
||||
scopeClassDeclaration.topContainer ?: scopeClassDeclaration.containingDeclarations.lastOrNull(),
|
||||
isOperandOfIsOperator
|
||||
)
|
||||
}
|
||||
|
||||
+3
-2
@@ -5,10 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.transformers
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
|
||||
data class ScopeClassDeclaration(
|
||||
val scopes: List<FirScope>,
|
||||
val containingDeclarations: List<FirRegularClass>
|
||||
val containingDeclarations: List<FirDeclaration>,
|
||||
val topContainer: FirDeclaration? = null
|
||||
)
|
||||
+39
-33
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
|
||||
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.PrivateForInline
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||
@@ -211,8 +212,8 @@ class BodyResolveContext(
|
||||
}
|
||||
|
||||
@PrivateForInline
|
||||
fun storeFunction(function: FirSimpleFunction) {
|
||||
updateLastScope { storeFunction(function) }
|
||||
fun storeFunction(function: FirSimpleFunction, session: FirSession) {
|
||||
updateLastScope { storeFunction(function, session) }
|
||||
}
|
||||
|
||||
@PrivateForInline
|
||||
@@ -251,8 +252,8 @@ class BodyResolveContext(
|
||||
return FirMemberTypeParameterScope(this)
|
||||
}
|
||||
|
||||
fun buildSecondaryConstructorParametersScope(constructor: FirConstructor): FirLocalScope =
|
||||
constructor.valueParameters.fold(FirLocalScope()) { acc, param -> acc.storeVariable(param) }
|
||||
fun buildSecondaryConstructorParametersScope(constructor: FirConstructor, session: FirSession): FirLocalScope =
|
||||
constructor.valueParameters.fold(FirLocalScope(session)) { acc, param -> acc.storeVariable(param, session) }
|
||||
|
||||
@PrivateForInline
|
||||
fun addInaccessibleImplicitReceiverValue(
|
||||
@@ -272,8 +273,8 @@ class BodyResolveContext(
|
||||
}
|
||||
|
||||
@PrivateForInline
|
||||
private fun storeBackingField(property: FirProperty) {
|
||||
updateLastScope { storeBackingField(property) }
|
||||
private fun storeBackingField(property: FirProperty, session: FirSession) {
|
||||
updateLastScope { storeBackingField(property, session) }
|
||||
}
|
||||
|
||||
// ANALYSIS PUBLIC API
|
||||
@@ -285,14 +286,14 @@ class BodyResolveContext(
|
||||
towerDataContextsForClassParts.primaryConstructorAllParametersScope
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
fun storeClassIfNotNested(klass: FirRegularClass) {
|
||||
fun storeClassIfNotNested(klass: FirRegularClass, session: FirSession) {
|
||||
if (containerIfAny is FirClass) return
|
||||
updateLastScope { storeClass(klass) }
|
||||
updateLastScope { storeClass(klass, session) }
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
fun storeVariable(variable: FirVariable) {
|
||||
updateLastScope { storeVariable(variable) }
|
||||
fun storeVariable(variable: FirVariable, session: FirSession) {
|
||||
updateLastScope { storeVariable(variable, session) }
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
@@ -368,7 +369,7 @@ class BodyResolveContext(
|
||||
forContracts: Boolean = false,
|
||||
f: () -> T
|
||||
): T {
|
||||
storeClassIfNotNested(regularClass)
|
||||
storeClassIfNotNested(regularClass, holder.session)
|
||||
if (forContracts) {
|
||||
return withTypeParametersOf(regularClass) {
|
||||
withContainerClass(regularClass, f)
|
||||
@@ -452,7 +453,7 @@ class BodyResolveContext(
|
||||
val constructor = (owner as? FirRegularClass)?.declarations?.firstOrNull { it is FirConstructor } as? FirConstructor
|
||||
val (primaryConstructorPureParametersScope, primaryConstructorAllParametersScope) =
|
||||
if (constructor?.isPrimary == true) {
|
||||
constructor.scopesWithPrimaryConstructorParameters(owner)
|
||||
constructor.scopesWithPrimaryConstructorParameters(owner, holder.session)
|
||||
} else {
|
||||
null to null
|
||||
}
|
||||
@@ -473,16 +474,17 @@ class BodyResolveContext(
|
||||
}
|
||||
|
||||
private fun FirConstructor.scopesWithPrimaryConstructorParameters(
|
||||
ownerClass: FirClass
|
||||
ownerClass: FirClass,
|
||||
session: FirSession
|
||||
): Pair<FirLocalScope, FirLocalScope> {
|
||||
var parameterScope = FirLocalScope()
|
||||
var allScope = FirLocalScope()
|
||||
var parameterScope = FirLocalScope(session)
|
||||
var allScope = FirLocalScope(session)
|
||||
val properties = ownerClass.declarations.filterIsInstance<FirProperty>().associateBy { it.name }
|
||||
for (parameter in valueParameters) {
|
||||
allScope = allScope.storeVariable(parameter)
|
||||
allScope = allScope.storeVariable(parameter, session)
|
||||
val property = properties[parameter.name]
|
||||
if (property?.source?.kind != KtFakeSourceElementKind.PropertyFromParameter) {
|
||||
parameterScope = parameterScope.storeVariable(parameter)
|
||||
parameterScope = parameterScope.storeVariable(parameter, session)
|
||||
}
|
||||
}
|
||||
return parameterScope to allScope
|
||||
@@ -491,10 +493,11 @@ class BodyResolveContext(
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun <T> withSimpleFunction(
|
||||
simpleFunction: FirSimpleFunction,
|
||||
session: FirSession,
|
||||
f: () -> T
|
||||
): T {
|
||||
if (containerIfAny !is FirClass) {
|
||||
storeFunction(simpleFunction)
|
||||
storeFunction(simpleFunction, session)
|
||||
}
|
||||
|
||||
return withTypeParametersOf(simpleFunction) {
|
||||
@@ -509,13 +512,13 @@ class BodyResolveContext(
|
||||
f: () -> T
|
||||
): T {
|
||||
return withTowerDataCleanup {
|
||||
addLocalScope(FirLocalScope())
|
||||
addLocalScope(FirLocalScope(holder.session))
|
||||
if (function is FirSimpleFunction) {
|
||||
// Make all value parameters available in the local scope so that even one parameter that refers to another parameter,
|
||||
// which may not be initialized yet, can be resolved. [FirFunctionParameterChecker] will detect and report an error
|
||||
// if an uninitialized parameter is accessed by a preceding parameter.
|
||||
for (parameter in function.valueParameters) {
|
||||
storeVariable(parameter)
|
||||
storeVariable(parameter, holder.session)
|
||||
}
|
||||
val receiverTypeRef = function.receiverTypeRef
|
||||
withLabelAndReceiverType(function.name, function, receiverTypeRef?.coneType, holder, f)
|
||||
@@ -528,6 +531,7 @@ class BodyResolveContext(
|
||||
@OptIn(PrivateForInline::class)
|
||||
fun <T> forConstructorBody(
|
||||
constructor: FirConstructor,
|
||||
session: FirSession,
|
||||
f: () -> T
|
||||
): T {
|
||||
return if (constructor.isPrimary) {
|
||||
@@ -542,7 +546,7 @@ class BodyResolveContext(
|
||||
}
|
||||
} else {
|
||||
withTowerDataCleanup {
|
||||
addLocalScope(buildSecondaryConstructorParametersScope(constructor))
|
||||
addLocalScope(buildSecondaryConstructorParametersScope(constructor, session))
|
||||
f()
|
||||
}
|
||||
}
|
||||
@@ -562,7 +566,7 @@ class BodyResolveContext(
|
||||
return f()
|
||||
}
|
||||
return withTowerDataCleanup {
|
||||
addLocalScope(FirLocalScope())
|
||||
addLocalScope(FirLocalScope(holder.session))
|
||||
val receiverTypeRef = anonymousFunction.receiverTypeRef
|
||||
val labelName = anonymousFunction.label?.name?.let { Name.identifier(it) }
|
||||
withContainer(anonymousFunction) {
|
||||
@@ -600,11 +604,12 @@ class BodyResolveContext(
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun <T> withAnonymousInitializer(
|
||||
anonymousInitializer: FirAnonymousInitializer,
|
||||
session: FirSession,
|
||||
f: () -> T
|
||||
): T {
|
||||
return withTowerDataCleanup {
|
||||
getPrimaryConstructorPureParametersScope()?.let { addLocalScope(it) }
|
||||
addLocalScope(FirLocalScope())
|
||||
addLocalScope(FirLocalScope(session))
|
||||
withContainer(anonymousInitializer, f)
|
||||
}
|
||||
}
|
||||
@@ -612,10 +617,11 @@ class BodyResolveContext(
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun <T> withValueParameter(
|
||||
valueParameter: FirValueParameter,
|
||||
session: FirSession,
|
||||
f: () -> T
|
||||
): T {
|
||||
if (!valueParameter.name.isSpecial || valueParameter.name != UNDERSCORE_FOR_UNUSED_VAR) {
|
||||
storeVariable(valueParameter)
|
||||
storeVariable(valueParameter, session)
|
||||
}
|
||||
return withContainer(valueParameter, f)
|
||||
}
|
||||
@@ -641,17 +647,17 @@ class BodyResolveContext(
|
||||
if (accessor is FirDefaultPropertyAccessor || accessor.body == null) {
|
||||
return if (accessor.isGetter) withContainer(accessor, f)
|
||||
else withTowerDataCleanup {
|
||||
addLocalScope(FirLocalScope())
|
||||
addLocalScope(FirLocalScope(holder.session))
|
||||
withContainer(accessor, f)
|
||||
}
|
||||
}
|
||||
return withTowerDataCleanup {
|
||||
val receiverTypeRef = property.receiverTypeRef
|
||||
addLocalScope(FirLocalScope())
|
||||
addLocalScope(FirLocalScope(holder.session))
|
||||
if (!forContracts && receiverTypeRef == null && property.returnTypeRef !is FirImplicitTypeRef &&
|
||||
!property.isLocal && property.delegate == null
|
||||
) {
|
||||
storeBackingField(property)
|
||||
storeBackingField(property, holder.session)
|
||||
}
|
||||
withContainer(accessor) {
|
||||
withLabelAndReceiverType(property.name, property, receiverTypeRef?.coneType, holder, f)
|
||||
@@ -731,8 +737,8 @@ class BodyResolveContext(
|
||||
} else {
|
||||
addInaccessibleImplicitReceiverValue(owningClass, holder)
|
||||
withTowerDataCleanup {
|
||||
addLocalScope(buildSecondaryConstructorParametersScope(constructor))
|
||||
constructor.valueParameters.forEach { storeVariable(it) }
|
||||
addLocalScope(buildSecondaryConstructorParametersScope(constructor, holder.session))
|
||||
constructor.valueParameters.forEach { storeVariable(it, holder.session) }
|
||||
f()
|
||||
}
|
||||
}
|
||||
@@ -747,15 +753,15 @@ class BodyResolveContext(
|
||||
towerDataContextForCallableReferences.remove(callableReferenceAccess)
|
||||
}
|
||||
|
||||
fun <T> withWhenExpression(whenExpression: FirWhenExpression, f: () -> T): T {
|
||||
fun <T> withWhenExpression(whenExpression: FirWhenExpression, session: FirSession, f: () -> T): T {
|
||||
if (whenExpression.subjectVariable == null) return f()
|
||||
return forBlock(f)
|
||||
return forBlock(session, f)
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun <T> forBlock(f: () -> T): T {
|
||||
inline fun <T> forBlock(session: FirSession, f: () -> T): T {
|
||||
return withTowerDataCleanup {
|
||||
addLocalScope(FirLocalScope())
|
||||
addLocalScope(FirLocalScope(session))
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -70,7 +70,8 @@ open class FirBodyResolveTransformer(
|
||||
typeRef,
|
||||
ScopeClassDeclaration(
|
||||
components.createCurrentScopeList(),
|
||||
context.containingClassDeclarations
|
||||
context.containingClassDeclarations,
|
||||
context.containers.lastOrNull { it is FirTypeParameterRefsOwner && it !is FirAnonymousFunction }
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
+3
-3
@@ -41,7 +41,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran
|
||||
|
||||
override fun transformDoWhileLoop(doWhileLoop: FirDoWhileLoop, data: ResolutionMode): FirStatement {
|
||||
// Do-while has a specific scope structure (its block and condition effectively share the scope)
|
||||
return context.forBlock {
|
||||
return context.forBlock(session) {
|
||||
val context = ResolutionMode.ContextIndependent
|
||||
doWhileLoop.also(dataFlowAnalyzer::enterDoWhileLoop)
|
||||
.also {
|
||||
@@ -61,7 +61,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran
|
||||
}
|
||||
whenExpression.annotations.forEach { it.accept(this, data) }
|
||||
dataFlowAnalyzer.enterWhenExpression(whenExpression)
|
||||
return context.withWhenExpression(whenExpression) with@{
|
||||
return context.withWhenExpression(whenExpression, session) with@{
|
||||
@Suppress("NAME_SHADOWING")
|
||||
var whenExpression = whenExpression.transformSubject(transformer, ResolutionMode.ContextIndependent)
|
||||
|
||||
@@ -164,7 +164,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran
|
||||
override fun transformCatch(catch: FirCatch, data: ResolutionMode): FirCatch {
|
||||
dataFlowAnalyzer.enterCatchClause(catch)
|
||||
catch.parameter.transformReturnTypeRef(transformer, ResolutionMode.ContextIndependent)
|
||||
return context.forBlock {
|
||||
return context.forBlock(session) {
|
||||
catch.transformParameter(transformer, ResolutionMode.ContextIndependent)
|
||||
catch.transformBlock(transformer, ResolutionMode.ContextDependent)
|
||||
}.also { dataFlowAnalyzer.exitCatchClause(it) }
|
||||
|
||||
+5
-5
@@ -330,7 +330,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
variable.transformAccessors()
|
||||
}
|
||||
variable.transformOtherChildren(transformer, ResolutionMode.ContextIndependent)
|
||||
context.storeVariable(variable)
|
||||
context.storeVariable(variable, session)
|
||||
dataFlowAnalyzer.exitLocalVariableDeclaration(variable, hadExplicitType)
|
||||
return variable
|
||||
}
|
||||
@@ -540,7 +540,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
doTransformTypeParameters(simpleFunction)
|
||||
|
||||
val containingDeclaration = context.containerIfAny
|
||||
return context.withSimpleFunction(simpleFunction) {
|
||||
return context.withSimpleFunction(simpleFunction, session) {
|
||||
// TODO: I think it worth creating something like runAllPhasesForLocalFunction
|
||||
if (containingDeclaration != null && containingDeclaration !is FirClass) {
|
||||
// For class members everything should be already prepared
|
||||
@@ -635,7 +635,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
constructor.transformValueParameters(transformer, data)
|
||||
}
|
||||
constructor.transformDelegatedConstructor(transformer, data)
|
||||
context.forConstructorBody(constructor) {
|
||||
context.forConstructorBody(constructor, session) {
|
||||
constructor.transformBody(transformer, data)
|
||||
}
|
||||
}
|
||||
@@ -651,7 +651,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
): FirAnonymousInitializer {
|
||||
if (implicitTypeOnly) return anonymousInitializer
|
||||
dataFlowAnalyzer.enterInitBlock(anonymousInitializer)
|
||||
return context.withAnonymousInitializer(anonymousInitializer) {
|
||||
return context.withAnonymousInitializer(anonymousInitializer, session) {
|
||||
val result =
|
||||
transformDeclarationContent(anonymousInitializer, ResolutionMode.ContextIndependent) as FirAnonymousInitializer
|
||||
val graph = dataFlowAnalyzer.exitInitBlock(result)
|
||||
@@ -671,7 +671,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
}
|
||||
|
||||
dataFlowAnalyzer.enterValueParameter(valueParameter)
|
||||
val result = context.withValueParameter(valueParameter) {
|
||||
val result = context.withValueParameter(valueParameter, session) {
|
||||
transformDeclarationContent(
|
||||
valueParameter,
|
||||
withExpectedType(valueParameter.returnTypeRef)
|
||||
|
||||
+1
-1
@@ -384,7 +384,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
||||
}
|
||||
|
||||
override fun transformBlock(block: FirBlock, data: ResolutionMode): FirStatement {
|
||||
context.forBlock {
|
||||
context.forBlock(session) {
|
||||
transformBlockInCurrentScope(block, data)
|
||||
}
|
||||
return block
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ fun <F : FirClassLikeDeclaration> F.runAllPhasesForLocalClass(
|
||||
): F {
|
||||
if (status is FirResolvedDeclarationStatus) return this
|
||||
if (this is FirRegularClass) {
|
||||
components.context.storeClassIfNotNested(this)
|
||||
components.context.storeClassIfNotNested(this, components.session)
|
||||
}
|
||||
this.transformAnnotations(transformer, ResolutionMode.ContextIndependent)
|
||||
val localClassesNavigationInfo = collectLocalClassesNavigationInfo()
|
||||
|
||||
+2
-2
@@ -71,7 +71,7 @@ open class FirContractResolveTransformer(
|
||||
return simpleFunction
|
||||
}
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return context.withSimpleFunction(simpleFunction) {
|
||||
return context.withSimpleFunction(simpleFunction, session) {
|
||||
context.forFunctionBody(simpleFunction, components) {
|
||||
transformContractDescriptionOwner(simpleFunction)
|
||||
}
|
||||
@@ -129,7 +129,7 @@ open class FirContractResolveTransformer(
|
||||
): T {
|
||||
val valueParameters = owner.valueParameters
|
||||
for (valueParameter in valueParameters) {
|
||||
context.storeVariable(valueParameter)
|
||||
context.storeVariable(valueParameter, session)
|
||||
}
|
||||
val contractCall = contractDescription.contractCall.transformSingle(transformer, ResolutionMode.ContextIndependent)
|
||||
val resolvedId = contractCall.toResolvedCallableSymbol()?.callableId ?: return transformOwnerWithUnresolvedContract(owner)
|
||||
|
||||
@@ -32,31 +32,38 @@ fun FirClassLikeDeclaration.getContainingDeclaration(session: FirSession): FirCl
|
||||
return null
|
||||
}
|
||||
|
||||
fun isValidTypeParameterFromOuterClass(
|
||||
fun isValidTypeParameterFromOuterDeclaration(
|
||||
typeParameterSymbol: FirTypeParameterSymbol,
|
||||
classDeclaration: FirRegularClass?,
|
||||
declaration: FirDeclaration?,
|
||||
session: FirSession
|
||||
): Boolean {
|
||||
if (classDeclaration == null) {
|
||||
if (declaration == null) {
|
||||
return true // Extra check is required because of classDeclaration will be resolved later
|
||||
}
|
||||
|
||||
fun containsTypeParameter(currentClassDeclaration: FirRegularClass): Boolean {
|
||||
if (currentClassDeclaration.typeParameters.any { it.symbol == typeParameterSymbol }) {
|
||||
return true
|
||||
}
|
||||
|
||||
for (superTypeRef in currentClassDeclaration.superTypeRefs) {
|
||||
val superClassFir = superTypeRef.firClassLike(session)
|
||||
if (superClassFir == null || superClassFir is FirRegularClass && containsTypeParameter(superClassFir)) {
|
||||
fun containsTypeParameter(currentDeclaration: FirDeclaration?): Boolean {
|
||||
if (currentDeclaration is FirTypeParameterRefsOwner) {
|
||||
if (currentDeclaration.typeParameters.any { it.symbol == typeParameterSymbol }) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (currentDeclaration is FirCallableDeclaration) {
|
||||
val containingClassId = currentDeclaration.symbol.callableId.classId ?: return true
|
||||
return containsTypeParameter(session.symbolProvider.getClassLikeSymbolByClassId(containingClassId)?.fir)
|
||||
} else if (currentDeclaration is FirClass) {
|
||||
for (superTypeRef in currentDeclaration.superTypeRefs) {
|
||||
val superClassFir = superTypeRef.firClassLike(session)
|
||||
if (superClassFir == null || superClassFir is FirRegularClass && containsTypeParameter(superClassFir)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return containsTypeParameter(classDeclaration)
|
||||
return containsTypeParameter(declaration)
|
||||
}
|
||||
|
||||
fun FirTypeRef.firClassLike(session: FirSession): FirClassLikeDeclaration? {
|
||||
|
||||
+4
-4
@@ -19,14 +19,14 @@ private class Outer<E> {
|
||||
private var doubleStringInt = Outer<Double>().Inner<String>().foo<Int>()()
|
||||
|
||||
private fun bar() {
|
||||
doubleCharSequenceInt = doubleStringNumber
|
||||
doubleCharSequenceInt = <!ASSIGNMENT_TYPE_MISMATCH!>doubleStringNumber<!>
|
||||
doubleCharSequenceInt = doubleStringInt
|
||||
|
||||
doubleStringInt = Outer<Double>().Inner<String>().foo<Int>()()
|
||||
|
||||
doubleStringInt.e.checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Double>() }
|
||||
doubleStringInt.f.checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><String>() }
|
||||
doubleStringInt.g.checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Int>() }
|
||||
doubleStringInt.e.checkType { _<Double>() }
|
||||
doubleStringInt.f.checkType { _<String>() }
|
||||
doubleStringInt.g.checkType { _<Int>() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -14,11 +14,11 @@ class Q {
|
||||
private var y = foo<String>()()
|
||||
|
||||
fun bar() {
|
||||
x = y
|
||||
x = <!ASSIGNMENT_TYPE_MISMATCH!>y<!>
|
||||
x = foo<CharSequence>()()
|
||||
y = foo<String>()()
|
||||
|
||||
x.prop.checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><CharSequence>() }
|
||||
y.prop.checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><String>() }
|
||||
x.prop.checkType { _<CharSequence>() }
|
||||
y.prop.checkType { _<String>() }
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -15,8 +15,8 @@ class Q {
|
||||
private var x = foo<CharSequence, Number>()()
|
||||
|
||||
fun bar() {
|
||||
x.e.checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><CharSequence>() }
|
||||
x.f.checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Number>() }
|
||||
x.e.checkType { _<CharSequence>() }
|
||||
x.f.checkType { _<Number>() }
|
||||
x.g.checkType { _<Number>() }
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,16 +1,16 @@
|
||||
fun <E> foo(x: Any, y: Any) : Any {
|
||||
class C
|
||||
// without E?
|
||||
if(x is C) {
|
||||
if(x is <!NO_TYPE_ARGUMENTS_ON_RHS!>C<!>) {
|
||||
return x
|
||||
}
|
||||
|
||||
if (1 == 2) {
|
||||
x as C
|
||||
x as <!NO_TYPE_ARGUMENTS_ON_RHS!>C<!>
|
||||
}
|
||||
|
||||
if (2 == 3) {
|
||||
x as? C
|
||||
x as? <!NO_TYPE_ARGUMENTS_ON_RHS, NO_TYPE_ARGUMENTS_ON_RHS!>C<!>
|
||||
}
|
||||
|
||||
class Outer<F> {
|
||||
|
||||
+2
-2
@@ -41,10 +41,10 @@ fun test() {
|
||||
var x = foobar<String>()
|
||||
x = foobar<String>()
|
||||
|
||||
x().foo().a() checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><A<String, Double, Short, Long>>() }
|
||||
x().foo().a() checkType { _<A<String, Double, Short, Long>>() }
|
||||
x().bar() <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>checkType<!> { _<A<String, Double, Short, Char>>() }
|
||||
|
||||
x = foobar<Int>()
|
||||
x = <!ASSIGNMENT_TYPE_MISMATCH!>foobar<Int>()<!>
|
||||
|
||||
var y = noParameters()
|
||||
y = noParameters()
|
||||
|
||||
+3
-3
@@ -42,11 +42,11 @@ class Outer<T> {
|
||||
var x = foobar<String>()
|
||||
x = foobar<String>()
|
||||
|
||||
x().foo().a() checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><A<T, F, String, Double, Short, Long>>() }
|
||||
x().foo().a() checkType { _<A<T, F, String, Double, Short, Long>>() }
|
||||
x().bar() <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>checkType<!> { _<A<T, F, String, Double, Short, Char>>() }
|
||||
|
||||
x = foobar<Int>()
|
||||
x = z.foobar<String>()
|
||||
x = <!ASSIGNMENT_TYPE_MISMATCH!>foobar<Int>()<!>
|
||||
x = <!ASSIGNMENT_TYPE_MISMATCH!>z.foobar<String>()<!>
|
||||
|
||||
var y = noParameters()
|
||||
y = noParameters()
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// FIR_IDENTICAL
|
||||
class C1<T1>
|
||||
|
||||
class C2<T3> {
|
||||
fun <T2> test() {
|
||||
class LocalClass
|
||||
C1<LocalClass>()
|
||||
}
|
||||
}
|
||||
|
||||
class A<T> {
|
||||
private inner class Inner
|
||||
private val test = ArrayList<Inner>()
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package
|
||||
|
||||
public final class A</*0*/ T> {
|
||||
public constructor A</*0*/ T>()
|
||||
private final val test: kotlin.collections.ArrayList<A<T>.Inner> /* = java.util.ArrayList<A<T>.Inner> */
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
private final inner class Inner /*captured type parameters: /*0*/ T*/ {
|
||||
public constructor Inner()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
|
||||
public final class C1</*0*/ T1> {
|
||||
public constructor C1</*0*/ T1>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class C2</*0*/ T3> {
|
||||
public constructor C2</*0*/ T3>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final fun </*0*/ T2> test(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -4,8 +4,8 @@ class A<T> {
|
||||
class B {
|
||||
fun test() {
|
||||
class C<W>() : P<W, <!UNRESOLVED_REFERENCE!>T<!>> {
|
||||
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>companion<!> object : P<W, <!UNRESOLVED_REFERENCE!>T<!>> {
|
||||
}
|
||||
<!TYPE_PARAMETERS_IN_OBJECT!><!WRONG_MODIFIER_CONTAINING_DECLARATION!>companion<!> object : P<W, <!UNRESOLVED_REFERENCE!>T<!>> {
|
||||
}<!>
|
||||
|
||||
inner class D : P<W, <!UNRESOLVED_REFERENCE!>T<!>>
|
||||
}
|
||||
|
||||
@@ -18,12 +18,12 @@ class Outer<T> {
|
||||
fun test5(x: <!UNRESOLVED_REFERENCE!>GenericInnerAlias<Int><!>) = x
|
||||
fun <T> test6(x: <!UNRESOLVED_REFERENCE!>GenericInnerAlias<T><!>) = x
|
||||
}
|
||||
fun test1(x: Outer<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>.NestedAlias) = x
|
||||
fun <T> test2(x: Outer<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><T><!>.NestedAlias) = x
|
||||
fun test1(x: Outer<Int>.NestedAlias) = x
|
||||
fun <T> test2(x: Outer<T>.NestedAlias) = x
|
||||
fun test3(x: Outer.NestedAlias) = x
|
||||
fun test4(x: Outer<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>.GenericNestedAlias<Int>) = x
|
||||
fun <T> test5(x: Outer<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><T><!>.GenericNestedAlias<Int>) = x
|
||||
fun <T> test6(x: Outer<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>.GenericNestedAlias<T>) = x
|
||||
fun test4(x: Outer<Int>.GenericNestedAlias<Int>) = x
|
||||
fun <T> test5(x: Outer<T>.GenericNestedAlias<Int>) = x
|
||||
fun <T> test6(x: Outer<Int>.GenericNestedAlias<T>) = x
|
||||
fun test7(x: Outer.GenericNestedAlias<Int>) = x
|
||||
fun <T> test8(x: Outer.GenericNestedAlias<T>) = x
|
||||
fun test9(x: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Outer<!>.InnerAlias) = x
|
||||
|
||||
@@ -6,5 +6,5 @@ class OuterClass<T1> {
|
||||
}
|
||||
|
||||
typealias ON1<T1, T2> = OuterClass<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><T1><!>.NestedClass<T2>
|
||||
typealias ON2<T1, T2> = OuterClass<T1>.NestedType<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><T2><!>
|
||||
typealias ON3<T2> = OuterClass.NestedType<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><T2><!>
|
||||
typealias ON2<T1, T2> = OuterClass<T1>.NestedType<T2>
|
||||
typealias ON3<T2> = OuterClass.NestedType<T2>
|
||||
|
||||
@@ -30,6 +30,6 @@ fun testWrong4(x: List<Any>) = x is <!NO_TYPE_ARGUMENTS_ON_RHS!>ReadableList<!>
|
||||
fun <T> testLocal(x: Any) {
|
||||
class C
|
||||
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>CA<!> = C
|
||||
if (x is C) {}
|
||||
if (x is <!NO_TYPE_ARGUMENTS_ON_RHS!>C<!>) {}
|
||||
if (x is <!UNRESOLVED_REFERENCE!>CA<!>) {}
|
||||
}
|
||||
|
||||
+16
-16
@@ -70,9 +70,9 @@ FILE fqName:<root> fileName:/genericLocalClassConstructorReference.kt
|
||||
$receiver: VALUE_PARAMETER name:<this> type:<root>.Rec<PT of <root>.<get-p>>
|
||||
BLOCK_BODY
|
||||
CLASS CLASS name:PLocal modality:FINAL visibility:local superTypes:[<root>.L<LT of <root>.<get-p>.PLocal>]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.<get-p>.PLocal<LT of <root>.<get-p>.PLocal>
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.<get-p>.PLocal<LT of <root>.<get-p>.PLocal, PT of <root>.<get-p>>
|
||||
TYPE_PARAMETER name:LT index:0 variance: superTypes:[kotlin.Any?]
|
||||
CONSTRUCTOR visibility:public <> (lt:LT of <root>.<get-p>.PLocal, pt:PT of <root>.<get-p>) returnType:<root>.<get-p>.PLocal<LT of <root>.<get-p>.PLocal> [primary]
|
||||
CONSTRUCTOR visibility:public <> (lt:LT of <root>.<get-p>.PLocal, pt:PT of <root>.<get-p>) returnType:<root>.<get-p>.PLocal<LT of <root>.<get-p>.PLocal, PT of <root>.<get-p>> [primary]
|
||||
VALUE_PARAMETER name:lt index:0 type:LT of <root>.<get-p>.PLocal
|
||||
VALUE_PARAMETER name:pt index:1 type:PT of <root>.<get-p>
|
||||
BLOCK_BODY
|
||||
@@ -84,13 +84,13 @@ FILE fqName:<root> fileName:/genericLocalClassConstructorReference.kt
|
||||
FIELD PROPERTY_BACKING_FIELD name:pt type:PT of <root>.<get-p> visibility:private [final]
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'pt: PT of <root>.<get-p> declared in <root>.<get-p>.PLocal.<init>' type=PT of <root>.<get-p> origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-pt> visibility:public modality:FINAL <> ($this:<root>.<get-p>.PLocal<LT of <root>.<get-p>.PLocal>) returnType:PT of <root>.<get-p>
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-pt> visibility:public modality:FINAL <> ($this:<root>.<get-p>.PLocal<LT of <root>.<get-p>.PLocal, PT of <root>.<get-p>>) returnType:PT of <root>.<get-p>
|
||||
correspondingProperty: PROPERTY name:pt visibility:public modality:FINAL [val]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.<get-p>.PLocal<LT of <root>.<get-p>.PLocal>
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.<get-p>.PLocal<LT of <root>.<get-p>.PLocal, PT of <root>.<get-p>>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-pt> (): PT of <root>.<get-p> declared in <root>.<get-p>.PLocal'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:pt type:PT of <root>.<get-p> visibility:private [final]' type=PT of <root>.<get-p> origin=null
|
||||
receiver: GET_VAR '<this>: <root>.<get-p>.PLocal<LT of <root>.<get-p>.PLocal> declared in <root>.<get-p>.PLocal.<get-pt>' type=<root>.<get-p>.PLocal<LT of <root>.<get-p>.PLocal> origin=null
|
||||
receiver: GET_VAR '<this>: <root>.<get-p>.PLocal<LT of <root>.<get-p>.PLocal, PT of <root>.<get-p>> declared in <root>.<get-p>.PLocal.<get-pt>' type=<root>.<get-p>.PLocal<LT of <root>.<get-p>.PLocal, PT of <root>.<get-p>> origin=null
|
||||
PROPERTY FAKE_OVERRIDE name:ll visibility:public modality:FINAL [fake_override,val]
|
||||
overridden:
|
||||
public final ll: LL of <root>.L [val]
|
||||
@@ -113,24 +113,24 @@ FILE fqName:<root> fileName:/genericLocalClassConstructorReference.kt
|
||||
public open fun toString (): kotlin.String [fake_override] declared in <root>.L
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-p> <PT> (): <root>.L<PT of <root>.<get-p>> declared in <root>'
|
||||
CALL 'public final fun foo2 <T1, T2, R> (t1: T1 of <root>.foo2, t2: T2 of <root>.foo2, bb: kotlin.Function2<T1 of <root>.foo2, T2 of <root>.foo2, R of <root>.foo2>): R of <root>.foo2 declared in <root>' type=<root>.<get-p>.PLocal<PT of <root>.<get-p>> origin=null
|
||||
CALL 'public final fun foo2 <T1, T2, R> (t1: T1 of <root>.foo2, t2: T2 of <root>.foo2, bb: kotlin.Function2<T1 of <root>.foo2, T2 of <root>.foo2, R of <root>.foo2>): R of <root>.foo2 declared in <root>' type=<root>.<get-p>.PLocal<PT of <root>.<get-p>, PT of <root>.<get-p>> origin=null
|
||||
<T1>: PT of <root>.<get-p>
|
||||
<T2>: PT of <root>.<get-p>
|
||||
<R>: <root>.<get-p>.PLocal<PT of <root>.<get-p>>
|
||||
<R>: <root>.<get-p>.PLocal<PT of <root>.<get-p>, PT of <root>.<get-p>>
|
||||
t1: CALL 'public final fun <get-rt> (): T of <root>.Rec declared in <root>.Rec' type=PT of <root>.<get-p> origin=GET_PROPERTY
|
||||
$this: GET_VAR '<this>: <root>.Rec<PT of <root>.<get-p>> declared in <root>.<get-p>' type=<root>.Rec<PT of <root>.<get-p>> origin=null
|
||||
t2: CALL 'public final fun <get-rt> (): T of <root>.Rec declared in <root>.Rec' type=PT of <root>.<get-p> origin=GET_PROPERTY
|
||||
$this: GET_VAR '<this>: <root>.Rec<PT of <root>.<get-p>> declared in <root>.<get-p>' type=<root>.Rec<PT of <root>.<get-p>> origin=null
|
||||
bb: FUNCTION_REFERENCE 'public constructor <init> (lt: LT of <root>.<get-p>.PLocal, pt: PT of <root>.<get-p>) [primary] declared in <root>.<get-p>.PLocal' type=kotlin.reflect.KFunction2<PT of <root>.<get-p>, PT of <root>.<get-p>, <root>.<get-p>.PLocal<PT of <root>.<get-p>>> origin=null reflectionTarget=<same>
|
||||
bb: FUNCTION_REFERENCE 'public constructor <init> (lt: LT of <root>.<get-p>.PLocal, pt: PT of <root>.<get-p>) [primary] declared in <root>.<get-p>.PLocal' type=kotlin.reflect.KFunction2<PT of <root>.<get-p>, PT of <root>.<get-p>, <root>.<get-p>.PLocal<PT of <root>.<get-p>, PT of <root>.<get-p>>> origin=null reflectionTarget=<same>
|
||||
<LT>: PT of <root>.<get-p>
|
||||
FUN name:fn visibility:public modality:FINAL <FT> ($receiver:<root>.Rec<FT of <root>.fn>) returnType:<root>.L<FT of <root>.fn>
|
||||
TYPE_PARAMETER name:FT index:0 variance: superTypes:[kotlin.Any?]
|
||||
$receiver: VALUE_PARAMETER name:<this> type:<root>.Rec<FT of <root>.fn>
|
||||
BLOCK_BODY
|
||||
CLASS CLASS name:FLocal modality:FINAL visibility:local superTypes:[<root>.L<LT of <root>.fn.FLocal>]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.fn.FLocal<LT of <root>.fn.FLocal>
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.fn.FLocal<LT of <root>.fn.FLocal, FT of <root>.fn>
|
||||
TYPE_PARAMETER name:LT index:0 variance: superTypes:[kotlin.Any?]
|
||||
CONSTRUCTOR visibility:public <> (lt:LT of <root>.fn.FLocal, pt:FT of <root>.fn) returnType:<root>.fn.FLocal<LT of <root>.fn.FLocal> [primary]
|
||||
CONSTRUCTOR visibility:public <> (lt:LT of <root>.fn.FLocal, pt:FT of <root>.fn) returnType:<root>.fn.FLocal<LT of <root>.fn.FLocal, FT of <root>.fn> [primary]
|
||||
VALUE_PARAMETER name:lt index:0 type:LT of <root>.fn.FLocal
|
||||
VALUE_PARAMETER name:pt index:1 type:FT of <root>.fn
|
||||
BLOCK_BODY
|
||||
@@ -142,13 +142,13 @@ FILE fqName:<root> fileName:/genericLocalClassConstructorReference.kt
|
||||
FIELD PROPERTY_BACKING_FIELD name:pt type:FT of <root>.fn visibility:private [final]
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'pt: FT of <root>.fn declared in <root>.fn.FLocal.<init>' type=FT of <root>.fn origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-pt> visibility:public modality:FINAL <> ($this:<root>.fn.FLocal<LT of <root>.fn.FLocal>) returnType:FT of <root>.fn
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-pt> visibility:public modality:FINAL <> ($this:<root>.fn.FLocal<LT of <root>.fn.FLocal, FT of <root>.fn>) returnType:FT of <root>.fn
|
||||
correspondingProperty: PROPERTY name:pt visibility:public modality:FINAL [val]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.fn.FLocal<LT of <root>.fn.FLocal>
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.fn.FLocal<LT of <root>.fn.FLocal, FT of <root>.fn>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-pt> (): FT of <root>.fn declared in <root>.fn.FLocal'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:pt type:FT of <root>.fn visibility:private [final]' type=FT of <root>.fn origin=null
|
||||
receiver: GET_VAR '<this>: <root>.fn.FLocal<LT of <root>.fn.FLocal> declared in <root>.fn.FLocal.<get-pt>' type=<root>.fn.FLocal<LT of <root>.fn.FLocal> origin=null
|
||||
receiver: GET_VAR '<this>: <root>.fn.FLocal<LT of <root>.fn.FLocal, FT of <root>.fn> declared in <root>.fn.FLocal.<get-pt>' type=<root>.fn.FLocal<LT of <root>.fn.FLocal, FT of <root>.fn> origin=null
|
||||
PROPERTY FAKE_OVERRIDE name:ll visibility:public modality:FINAL [fake_override,val]
|
||||
overridden:
|
||||
public final ll: LL of <root>.L [val]
|
||||
@@ -171,15 +171,15 @@ FILE fqName:<root> fileName:/genericLocalClassConstructorReference.kt
|
||||
public open fun toString (): kotlin.String [fake_override] declared in <root>.L
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
RETURN type=kotlin.Nothing from='public final fun fn <FT> (): <root>.L<FT of <root>.fn> declared in <root>'
|
||||
CALL 'public final fun foo2 <T1, T2, R> (t1: T1 of <root>.foo2, t2: T2 of <root>.foo2, bb: kotlin.Function2<T1 of <root>.foo2, T2 of <root>.foo2, R of <root>.foo2>): R of <root>.foo2 declared in <root>' type=<root>.fn.FLocal<FT of <root>.fn> origin=null
|
||||
CALL 'public final fun foo2 <T1, T2, R> (t1: T1 of <root>.foo2, t2: T2 of <root>.foo2, bb: kotlin.Function2<T1 of <root>.foo2, T2 of <root>.foo2, R of <root>.foo2>): R of <root>.foo2 declared in <root>' type=<root>.fn.FLocal<FT of <root>.fn, FT of <root>.fn> origin=null
|
||||
<T1>: FT of <root>.fn
|
||||
<T2>: FT of <root>.fn
|
||||
<R>: <root>.fn.FLocal<FT of <root>.fn>
|
||||
<R>: <root>.fn.FLocal<FT of <root>.fn, FT of <root>.fn>
|
||||
t1: CALL 'public final fun <get-rt> (): T of <root>.Rec declared in <root>.Rec' type=FT of <root>.fn origin=GET_PROPERTY
|
||||
$this: GET_VAR '<this>: <root>.Rec<FT of <root>.fn> declared in <root>.fn' type=<root>.Rec<FT of <root>.fn> origin=null
|
||||
t2: CALL 'public final fun <get-rt> (): T of <root>.Rec declared in <root>.Rec' type=FT of <root>.fn origin=GET_PROPERTY
|
||||
$this: GET_VAR '<this>: <root>.Rec<FT of <root>.fn> declared in <root>.fn' type=<root>.Rec<FT of <root>.fn> origin=null
|
||||
bb: FUNCTION_REFERENCE 'public constructor <init> (lt: LT of <root>.fn.FLocal, pt: FT of <root>.fn) [primary] declared in <root>.fn.FLocal' type=kotlin.reflect.KFunction2<FT of <root>.fn, FT of <root>.fn, <root>.fn.FLocal<FT of <root>.fn>> origin=null reflectionTarget=<same>
|
||||
bb: FUNCTION_REFERENCE 'public constructor <init> (lt: LT of <root>.fn.FLocal, pt: FT of <root>.fn) [primary] declared in <root>.fn.FLocal' type=kotlin.reflect.KFunction2<FT of <root>.fn, FT of <root>.fn, <root>.fn.FLocal<FT of <root>.fn, FT of <root>.fn>> origin=null reflectionTarget=<same>
|
||||
<LT>: FT of <root>.fn
|
||||
FUN name:foo2 visibility:public modality:FINAL <T1, T2, R> (t1:T1 of <root>.foo2, t2:T2 of <root>.foo2, bb:kotlin.Function2<T1 of <root>.foo2, T2 of <root>.foo2, R of <root>.foo2>) returnType:R of <root>.foo2
|
||||
TYPE_PARAMETER name:T1 index:0 variance: superTypes:[kotlin.Any?]
|
||||
|
||||
+3
-2
@@ -39,7 +39,7 @@ val <PT : Any?> Rec<PT>.p: L<PT>
|
||||
|
||||
}
|
||||
|
||||
return foo2<PT, PT, PLocal<PT>>(t1 = <this>.<get-rt>(), t2 = <this>.<get-rt>(), bb = PLocal::<init>/*<PT>()*/)
|
||||
return foo2<PT, PT, PLocal<PT, PT>>(t1 = <this>.<get-rt>(), t2 = <this>.<get-rt>(), bb = PLocal::<init>/*<PT>()*/)
|
||||
}
|
||||
|
||||
fun <FT : Any?> Rec<FT>.fn(): L<FT> {
|
||||
@@ -56,9 +56,10 @@ fun <FT : Any?> Rec<FT>.fn(): L<FT> {
|
||||
|
||||
}
|
||||
|
||||
return foo2<FT, FT, FLocal<FT>>(t1 = <this>.<get-rt>(), t2 = <this>.<get-rt>(), bb = FLocal::<init>/*<FT>()*/)
|
||||
return foo2<FT, FT, FLocal<FT, FT>>(t1 = <this>.<get-rt>(), t2 = <this>.<get-rt>(), bb = FLocal::<init>/*<FT>()*/)
|
||||
}
|
||||
|
||||
fun <T1 : Any?, T2 : Any?, R : Any?> foo2(t1: T1, t2: T2, bb: Function2<T1, T2, R>): R {
|
||||
return bb.invoke(p1 = t1, p2 = t2)
|
||||
}
|
||||
|
||||
|
||||
Generated
+6
@@ -11351,6 +11351,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/generics/kt9985.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localClassWithTypeArgumentFromFunction.kt")
|
||||
public void testLocalClassWithTypeArgumentFromFunction() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Projections.kt")
|
||||
public void testProjections() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user