[FIR] Resolve array literals in independent context
This commit is contained in:
@@ -73,6 +73,9 @@ val ConeKotlinType.isArrayType: Boolean
|
|||||||
val ConeKotlinType.isNonPrimitiveArray: Boolean
|
val ConeKotlinType.isNonPrimitiveArray: Boolean
|
||||||
get() = this is ConeClassLikeType && lookupTag.classId == StandardClassIds.Array
|
get() = this is ConeClassLikeType && lookupTag.classId == StandardClassIds.Array
|
||||||
|
|
||||||
|
val ConeKotlinType.isPrimitiveArray: Boolean
|
||||||
|
get() = this is ConeClassLikeType && lookupTag.classId in StandardClassIds.primitiveArrayTypeByElementType.values
|
||||||
|
|
||||||
private val builtinUnsignedTypes = setOf(StandardClassIds.UInt, StandardClassIds.UByte, StandardClassIds.ULong, StandardClassIds.UShort)
|
private val builtinUnsignedTypes = setOf(StandardClassIds.UInt, StandardClassIds.UByte, StandardClassIds.ULong, StandardClassIds.UShort)
|
||||||
val ConeKotlinType.isUnsignedTypeOrNullableUnsignedType: Boolean get() = isAnyOfBuiltinType(builtinUnsignedTypes)
|
val ConeKotlinType.isUnsignedTypeOrNullableUnsignedType: Boolean get() = isAnyOfBuiltinType(builtinUnsignedTypes)
|
||||||
|
|
||||||
|
|||||||
+15
-9
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.fir.types.builder.buildStarProjection
|
|||||||
import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance
|
import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.visitors.*
|
import org.jetbrains.kotlin.fir.visitors.*
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeApproximator
|
|
||||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
@@ -44,7 +43,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
override val session: FirSession,
|
override val session: FirSession,
|
||||||
private val finalSubstitutor: ConeSubstitutor,
|
private val finalSubstitutor: ConeSubstitutor,
|
||||||
private val typeCalculator: ReturnTypeCalculator,
|
private val typeCalculator: ReturnTypeCalculator,
|
||||||
private val typeApproximator: AbstractTypeApproximator,
|
private val typeApproximator: ConeTypeApproximator,
|
||||||
private val dataFlowAnalyzer: FirDataFlowAnalyzer<*>,
|
private val dataFlowAnalyzer: FirDataFlowAnalyzer<*>,
|
||||||
private val mode: Mode = Mode.Normal
|
private val mode: Mode = Mode.Normal
|
||||||
) : FirAbstractTreeTransformer<ExpectedArgumentType?>(phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) {
|
) : FirAbstractTreeTransformer<ExpectedArgumentType?>(phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) {
|
||||||
@@ -287,7 +286,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
val substitutedType = finalSubstitutor.substituteOrNull(initialType)
|
val substitutedType = finalSubstitutor.substituteOrNull(initialType)
|
||||||
val finalType = typeApproximator.approximateToSuperType(
|
val finalType = typeApproximator.approximateToSuperType(
|
||||||
type = substitutedType ?: initialType, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference,
|
type = substitutedType ?: initialType, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference,
|
||||||
) as ConeKotlinType? ?: substitutedType
|
) ?: substitutedType
|
||||||
|
|
||||||
return withReplacedConeType(finalType)
|
return withReplacedConeType(finalType)
|
||||||
}
|
}
|
||||||
@@ -475,7 +474,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
finalSubstitutor.substituteOrSelf(it).let { substitutedType ->
|
finalSubstitutor.substituteOrSelf(it).let { substitutedType ->
|
||||||
typeApproximator.approximateToSuperType(
|
typeApproximator.approximateToSuperType(
|
||||||
substitutedType, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference,
|
substitutedType, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference,
|
||||||
) as ConeKotlinType? ?: substitutedType
|
) ?: substitutedType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -537,7 +536,8 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (needUpdateLambdaType) {
|
if (needUpdateLambdaType) {
|
||||||
val resolvedTypeRef = anonymousFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
|
val resolvedTypeRef =
|
||||||
|
anonymousFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
|
||||||
anonymousFunction.replaceTypeRef(resolvedTypeRef)
|
anonymousFunction.replaceTypeRef(resolvedTypeRef)
|
||||||
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, anonymousFunction.source, null)
|
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, anonymousFunction.source, null)
|
||||||
}
|
}
|
||||||
@@ -558,7 +558,8 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
|
|
||||||
val newReturnTypeRef = resultFunction.returnTypeRef.withReplacedConeType(lastExpressionType)
|
val newReturnTypeRef = resultFunction.returnTypeRef.withReplacedConeType(lastExpressionType)
|
||||||
resultFunction.replaceReturnTypeRef(newReturnTypeRef)
|
resultFunction.replaceReturnTypeRef(newReturnTypeRef)
|
||||||
val resolvedTypeRef = resultFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
|
val resolvedTypeRef =
|
||||||
|
resultFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
|
||||||
resultFunction.replaceTypeRef(resolvedTypeRef)
|
resultFunction.replaceTypeRef(resolvedTypeRef)
|
||||||
session.lookupTracker?.let {
|
session.lookupTracker?.let {
|
||||||
it.recordTypeResolveAsLookup(newReturnTypeRef, anonymousFunction.source, null)
|
it.recordTypeResolveAsLookup(newReturnTypeRef, anonymousFunction.source, null)
|
||||||
@@ -710,9 +711,14 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
val expectedArrayType = data?.getExpectedType(arrayOfCall)
|
val expectedArrayType = data?.getExpectedType(arrayOfCall)
|
||||||
val expectedArrayElementType = expectedArrayType?.arrayElementType()
|
val expectedArrayElementType = expectedArrayType?.arrayElementType()
|
||||||
arrayOfCall.transformChildren(this, expectedArrayElementType?.toExpectedType())
|
arrayOfCall.transformChildren(this, expectedArrayElementType?.toExpectedType())
|
||||||
val arrayElementType = session.inferenceComponents.ctx.commonSuperTypeOrNull(arrayOfCall.arguments.map { it.typeRef.coneType })
|
val arrayElementType =
|
||||||
?: session.builtinTypes.nullableAnyType.type
|
session.inferenceComponents.ctx.commonSuperTypeOrNull(arrayOfCall.arguments.map { it.typeRef.coneType })?.let {
|
||||||
arrayOfCall.resultType = arrayOfCall.typeRef.resolvedTypeFromPrototype(arrayElementType.createArrayType())
|
typeApproximator.approximateToSuperType(it, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference)
|
||||||
|
?: it
|
||||||
|
} ?: expectedArrayElementType ?: session.builtinTypes.nullableAnyType.type
|
||||||
|
arrayOfCall.resultType = arrayOfCall.typeRef.resolvedTypeFromPrototype(
|
||||||
|
arrayElementType.createArrayType(createPrimitiveArrayType = expectedArrayType?.isPrimitiveArray == true)
|
||||||
|
)
|
||||||
return arrayOfCall
|
return arrayOfCall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
@@ -127,6 +127,22 @@ class FirSyntheticCallGenerator(
|
|||||||
return elvisExpression.transformCalleeReference(UpdateReference, reference)
|
return elvisExpression.transformCalleeReference(UpdateReference, reference)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun generateSyntheticCallForArrayOfCall(arrayOfCall: FirArrayOfCall, context: ResolutionContext): FirFunctionCall {
|
||||||
|
val argumentList = buildArgumentList {
|
||||||
|
arguments += arrayOfCall
|
||||||
|
}
|
||||||
|
return buildFunctionCall {
|
||||||
|
this.argumentList = argumentList
|
||||||
|
calleeReference = generateCalleeReferenceWithCandidate(
|
||||||
|
arrayOfCall,
|
||||||
|
idFunction,
|
||||||
|
argumentList,
|
||||||
|
SyntheticCallableId.ID.callableName,
|
||||||
|
context = context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun resolveCallableReferenceWithSyntheticOuterCall(
|
fun resolveCallableReferenceWithSyntheticOuterCall(
|
||||||
callableReferenceAccess: FirCallableReferenceAccess,
|
callableReferenceAccess: FirCallableReferenceAccess,
|
||||||
expectedTypeRef: FirTypeRef?,
|
expectedTypeRef: FirTypeRef?,
|
||||||
|
|||||||
+4
@@ -224,6 +224,10 @@ open class FirBodyResolveTransformer(
|
|||||||
return expressionsTransformer.transformCheckedSafeCallSubject(checkedSafeCallSubject, data)
|
return expressionsTransformer.transformCheckedSafeCallSubject(checkedSafeCallSubject, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ResolutionMode): FirStatement {
|
||||||
|
return expressionsTransformer.transformArrayOfCall(arrayOfCall, data)
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------- Declarations -------------------------------------
|
// ------------------------------------- Declarations -------------------------------------
|
||||||
|
|
||||||
override fun transformDeclaration(declaration: FirDeclaration, data: ResolutionMode): FirDeclaration {
|
override fun transformDeclaration(declaration: FirDeclaration, data: ResolutionMode): FirDeclaration {
|
||||||
|
|||||||
+11
@@ -968,6 +968,17 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ResolutionMode): FirStatement {
|
||||||
|
if (data is ResolutionMode.ContextDependent) {
|
||||||
|
arrayOfCall.transformChildren(transformer, data)
|
||||||
|
return arrayOfCall
|
||||||
|
}
|
||||||
|
val syntheticIdCall = components.syntheticCallGenerator.generateSyntheticCallForArrayOfCall(arrayOfCall, resolutionContext)
|
||||||
|
arrayOfCall.transformChildren(transformer, ResolutionMode.ContextDependent)
|
||||||
|
callCompleter.completeCall(syntheticIdCall, data.expectedType ?: components.noExpectedType)
|
||||||
|
return arrayOfCall
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
internal fun <T> storeTypeFromCallee(access: T) where T : FirQualifiedAccess, T : FirExpression {
|
internal fun <T> storeTypeFromCallee(access: T) where T : FirQualifiedAccess, T : FirExpression {
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ import org.jetbrains.kotlin.name.StandardClassIds
|
|||||||
val ConeKotlinType.isArrayOrPrimitiveArray: Boolean
|
val ConeKotlinType.isArrayOrPrimitiveArray: Boolean
|
||||||
get() = arrayElementType() != null
|
get() = arrayElementType() != null
|
||||||
|
|
||||||
fun ConeKotlinType.createOutArrayType(nullable: Boolean = false): ConeKotlinType {
|
fun ConeKotlinType.createOutArrayType(nullable: Boolean = false, createPrimitiveArrayType: Boolean = true): ConeKotlinType {
|
||||||
return ConeKotlinTypeProjectionOut(this).createArrayType(nullable)
|
return ConeKotlinTypeProjectionOut(this).createArrayType(nullable, createPrimitiveArrayType)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ConeTypeProjection.createArrayType(nullable: Boolean = false): ConeClassLikeType {
|
fun ConeTypeProjection.createArrayType(nullable: Boolean = false, createPrimitiveArrayType: Boolean = true): ConeClassLikeType {
|
||||||
if (this is ConeKotlinTypeProjection) {
|
if (this is ConeKotlinTypeProjection && createPrimitiveArrayType) {
|
||||||
val type = type.lowerBoundIfFlexible()
|
val type = type.lowerBoundIfFlexible()
|
||||||
if (type is ConeClassLikeType && type.nullability != ConeNullability.NULLABLE) {
|
if (type is ConeClassLikeType && type.nullability != ConeNullability.NULLABLE) {
|
||||||
val classId = type.lookupTag.classId
|
val classId = type.lookupTag.classId
|
||||||
|
|||||||
+5
-5
@@ -7,18 +7,18 @@ fun test() {
|
|||||||
val b: Array<Int> = []
|
val b: Array<Int> = []
|
||||||
val c = [1, 2]
|
val c = [1, 2]
|
||||||
val d: Array<Int> = [1, 2]
|
val d: Array<Int> = [1, 2]
|
||||||
val e: Array<String> = [1]
|
val e: Array<String> = <!INITIALIZER_TYPE_MISMATCH!>[1]<!>
|
||||||
|
|
||||||
val f: IntArray = [1, 2]
|
val f: IntArray = [1, 2]
|
||||||
val g = [f]
|
val g = [f]
|
||||||
}
|
}
|
||||||
|
|
||||||
fun check() {
|
fun check() {
|
||||||
[1, 2] <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<Int>>() }
|
[1, 2] checkType { _<Array<Int>>() }
|
||||||
[""] <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<String>>() }
|
[""] checkType { _<Array<String>>() }
|
||||||
|
|
||||||
val f: IntArray = [1]
|
val f: IntArray = [1]
|
||||||
[f] <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<IntArray>>() }
|
[f] checkType { _<Array<IntArray>>() }
|
||||||
|
|
||||||
[1, ""] <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<Any>>() }
|
[1, ""] checkType { <!INAPPLICABLE_CANDIDATE!>_<!><Array<Any>>() }
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+4
-4
@@ -12,7 +12,7 @@ fun basicTypes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun basicTypesWithErrors() {
|
fun basicTypesWithErrors() {
|
||||||
val a: IntArray = [1.0]
|
val a: IntArray = <!INITIALIZER_TYPE_MISMATCH!>[1.0]<!>
|
||||||
val b: ShortArray = [1.0]
|
val b: ShortArray = <!INITIALIZER_TYPE_MISMATCH!>[1.0]<!>
|
||||||
val c: CharArray = ["a"]
|
val c: CharArray = <!INITIALIZER_TYPE_MISMATCH!>["a"]<!>
|
||||||
}
|
}
|
||||||
|
|||||||
compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsOutsideOfAnnotations.fir.kt
Vendored
+1
-1
@@ -10,7 +10,7 @@ fun test() {
|
|||||||
takeArray([""])
|
takeArray([""])
|
||||||
val v = [""]
|
val v = [""]
|
||||||
[""]
|
[""]
|
||||||
[1, 2, 3].<!UNRESOLVED_REFERENCE!>size<!>
|
[1, 2, 3].size
|
||||||
}
|
}
|
||||||
|
|
||||||
fun baz(arg: Array<Int> = []) {
|
fun baz(arg: Array<Int> = []) {
|
||||||
|
|||||||
+3
-3
@@ -1,12 +1,12 @@
|
|||||||
// !WITH_NEW_INFERENCE
|
// !WITH_NEW_INFERENCE
|
||||||
fun test(): Array<Int> {
|
fun test(): Array<Int> {
|
||||||
[1, 2]
|
[1, 2]
|
||||||
[1, 2]<!NO_GET_METHOD!>[0]<!>
|
[1, 2][0]
|
||||||
[1, 2].<!UNRESOLVED_REFERENCE!>get<!>(0)
|
[1, 2].get(0)
|
||||||
|
|
||||||
foo([""])
|
foo([""])
|
||||||
|
|
||||||
val p = [1, 2] + [3, 4]
|
val p = [1, 2] <!UNRESOLVED_REFERENCE!>+<!> [3, 4]
|
||||||
|
|
||||||
return [1, 2]
|
return [1, 2]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user