[FIR] Implement Int -> Long conversions for literals and operators over them

^KT-38895
^KT-50996 Fixed
^KT-51000 Fixed
^KT-51003 Fixed
^KT-51018 Fixed
This commit is contained in:
Dmitriy Novozhilov
2022-01-25 12:41:04 +03:00
committed by teamcity
parent cc86ca2a0f
commit 52b72a7dac
98 changed files with 1318 additions and 232 deletions
@@ -12,7 +12,7 @@ internal object PublicApproximatorConfiguration : TypeApproximatorConfiguration.
override val allFlexible: Boolean get() = false override val allFlexible: Boolean get() = false
override val errorType: Boolean get() = true override val errorType: Boolean get() = true
override val definitelyNotNullType: Boolean get() = false override val definitelyNotNullType: Boolean get() = false
override val integerLiteralType: Boolean get() = true override val integerLiteralConstantType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true override val intersectionTypesInContravariantPositions: Boolean get() = true
override val localTypes: Boolean get() = true override val localTypes: Boolean get() = true
} }
@@ -13,10 +13,12 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirModuleResolveSta
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.originalIfFakeOverride import org.jetbrains.kotlin.fir.originalIfFakeOverride
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData
import org.jetbrains.kotlin.fir.scopes.impl.originalForWrappedIntegerOperator
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
internal interface KtFirSymbol<out S : FirBasedSymbol<*>> : KtSymbol, ValidityTokenOwner { internal interface KtFirSymbol<out S : FirBasedSymbol<*>> : KtSymbol, ValidityTokenOwner {
@@ -64,6 +66,12 @@ internal tailrec fun FirDeclaration.ktSymbolOrigin(): KtSymbolOrigin = when (ori
importedFromObjectData.original.ktSymbolOrigin() importedFromObjectData.original.ktSymbolOrigin()
} }
FirDeclarationOrigin.WrappedIntegerOperator -> {
val original = (this as FirSimpleFunction).originalForWrappedIntegerOperator?.fir
?: error("Declaration has WrappedIntegerOperator origin, but no originalForWrappedIntegerOperator present")
original.ktSymbolOrigin()
}
else -> { else -> {
val overridden = (this as? FirCallableDeclaration)?.originalIfFakeOverride() val overridden = (this as? FirCallableDeclaration)?.originalIfFakeOverride()
?: throw InvalidFirDeclarationOriginForSymbol(this) ?: throw InvalidFirDeclarationOriginForSymbol(this)
@@ -26,7 +26,7 @@ internal object PublicTypeApproximator {
override val allFlexible: Boolean get() = false override val allFlexible: Boolean get() = false
override val errorType: Boolean get() = true override val errorType: Boolean get() = true
override val definitelyNotNullType: Boolean get() = false override val definitelyNotNullType: Boolean get() = false
override val integerLiteralType: Boolean get() = true override val integerLiteralConstantType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true override val intersectionTypesInContravariantPositions: Boolean get() = true
override val anonymous: Boolean get() = true override val anonymous: Boolean get() = true
} }
@@ -1,5 +1,5 @@
KT element: KtBinaryExpression KT element: KtBinaryExpression
FIR element: FirFunctionCallImpl FIR element: FirIntegerLiteralOperatorCallImpl
FIR source kind: KtRealSourceElementKind FIR source kind: KtRealSourceElementKind
FIR element rendered: FIR element rendered:
@@ -1,5 +1,5 @@
KT element: KtParenthesizedExpression KT element: KtParenthesizedExpression
FIR element: FirFunctionCallImpl FIR element: FirIntegerLiteralOperatorCallImpl
FIR source kind: KtRealSourceElementKind FIR source kind: KtRealSourceElementKind
FIR element rendered: FIR element rendered:
@@ -1,6 +1,6 @@
KT element: KtBlockStringTemplateEntry KT element: KtBlockStringTemplateEntry
FIR element: FirFunctionCallImpl FIR element: FirIntegerLiteralOperatorCallImpl
FIR source kind: KtRealSourceElementKind FIR source kind: KtRealSourceElementKind
FIR element rendered: FIR element rendered:
Int(1).R|kotlin/Int.plus|(Int(2)) Int(1).R|kotlin/Int.plus|(Int(2))
@@ -17477,6 +17477,28 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
} }
} }
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/integerLiterals")
@TestDataPath("$PROJECT_ROOT")
public class IntegerLiterals {
@Test
public void testAllFilesPresentInIntegerLiterals() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/integerLiterals"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("intToLongConversion.kt")
public void testIntToLongConversion() throws Exception {
runTest("compiler/testData/diagnostics/tests/integerLiterals/intToLongConversion.kt");
}
@Test
@TestMetadata("literalsInInference.kt")
public void testLiteralsInInference() throws Exception {
runTest("compiler/testData/diagnostics/tests/integerLiterals/literalsInInference.kt");
}
}
@Nested @Nested
@TestMetadata("compiler/testData/diagnostics/tests/j+k") @TestMetadata("compiler/testData/diagnostics/tests/j+k")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@@ -1,6 +1,6 @@
FILE: lambda.kt FILE: lambda.kt
public final fun f(t: R|(@R|kotlin/ParameterName|(name = String(v)) kotlin/Int) -> kotlin/Unit|): R|kotlin/Unit| { public final fun f(t: R|(@R|kotlin/ParameterName|(name = String(v)) kotlin/Int) -> kotlin/Unit|): R|kotlin/Unit| {
Int(1).R|kotlin/run|<R|@R|kotlin/ParameterName|(name = String(v)) kotlin/Int|, R|kotlin/Unit|>(R|<local>/t|) Int(1).R|kotlin/run|<R|kotlin/Int|, R|kotlin/Unit|>(R|<local>/t|)
} }
public final fun main(): R|kotlin/Unit| { public final fun main(): R|kotlin/Unit| {
R|/f|(<L> = f@fun <anonymous>(i: R|@R|kotlin/ParameterName|(name = String(v)) kotlin/Int|): R|kotlin/Unit| <inline=NoInline> { R|/f|(<L> = f@fun <anonymous>(i: R|@R|kotlin/ParameterName|(name = String(v)) kotlin/Int|): R|kotlin/Unit| <inline=NoInline> {
@@ -17477,6 +17477,28 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
} }
} }
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/integerLiterals")
@TestDataPath("$PROJECT_ROOT")
public class IntegerLiterals {
@Test
public void testAllFilesPresentInIntegerLiterals() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/integerLiterals"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("intToLongConversion.kt")
public void testIntToLongConversion() throws Exception {
runTest("compiler/testData/diagnostics/tests/integerLiterals/intToLongConversion.kt");
}
@Test
@TestMetadata("literalsInInference.kt")
public void testLiteralsInInference() throws Exception {
runTest("compiler/testData/diagnostics/tests/integerLiterals/literalsInInference.kt");
}
}
@Nested @Nested
@TestMetadata("compiler/testData/diagnostics/tests/j+k") @TestMetadata("compiler/testData/diagnostics/tests/j+k")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@@ -17477,6 +17477,28 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
} }
} }
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/integerLiterals")
@TestDataPath("$PROJECT_ROOT")
public class IntegerLiterals {
@Test
public void testAllFilesPresentInIntegerLiterals() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/integerLiterals"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("intToLongConversion.kt")
public void testIntToLongConversion() throws Exception {
runTest("compiler/testData/diagnostics/tests/integerLiterals/intToLongConversion.kt");
}
@Test
@TestMetadata("literalsInInference.kt")
public void testLiteralsInInference() throws Exception {
runTest("compiler/testData/diagnostics/tests/integerLiterals/literalsInInference.kt");
}
}
@Nested @Nested
@TestMetadata("compiler/testData/diagnostics/tests/j+k") @TestMetadata("compiler/testData/diagnostics/tests/j+k")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@@ -31,6 +31,7 @@ fun main(args: Array<String>) {
alias<FirQualifiedAccessExpression>("QualifiedAccessExpressionChecker") alias<FirQualifiedAccessExpression>("QualifiedAccessExpressionChecker")
alias<FirCall>("CallChecker") alias<FirCall>("CallChecker")
alias<FirFunctionCall>("FunctionCallChecker") alias<FirFunctionCall>("FunctionCallChecker")
alias<FirIntegerLiteralOperatorCall>("IntegerLiteralOperatorCallChecker")
alias<FirVariableAssignment>("VariableAssignmentChecker") alias<FirVariableAssignment>("VariableAssignmentChecker")
alias<FirTryExpression>("TryExpressionChecker") alias<FirTryExpression>("TryExpressionChecker")
alias<FirWhenExpression>("WhenExpressionChecker") alias<FirWhenExpression>("WhenExpressionChecker")
@@ -23,6 +23,8 @@ class ComposedExpressionCheckers : ExpressionCheckers() {
get() = _callCheckers get() = _callCheckers
override val functionCallCheckers: Set<FirFunctionCallChecker> override val functionCallCheckers: Set<FirFunctionCallChecker>
get() = _functionCallCheckers get() = _functionCallCheckers
override val integerLiteralOperatorCallCheckers: Set<FirIntegerLiteralOperatorCallChecker>
get() = _integerLiteralOperatorCallCheckers
override val variableAssignmentCheckers: Set<FirVariableAssignmentChecker> override val variableAssignmentCheckers: Set<FirVariableAssignmentChecker>
get() = _variableAssignmentCheckers get() = _variableAssignmentCheckers
override val tryExpressionCheckers: Set<FirTryExpressionChecker> override val tryExpressionCheckers: Set<FirTryExpressionChecker>
@@ -79,6 +81,7 @@ class ComposedExpressionCheckers : ExpressionCheckers() {
private val _qualifiedAccessExpressionCheckers: MutableSet<FirQualifiedAccessExpressionChecker> = mutableSetOf() private val _qualifiedAccessExpressionCheckers: MutableSet<FirQualifiedAccessExpressionChecker> = mutableSetOf()
private val _callCheckers: MutableSet<FirCallChecker> = mutableSetOf() private val _callCheckers: MutableSet<FirCallChecker> = mutableSetOf()
private val _functionCallCheckers: MutableSet<FirFunctionCallChecker> = mutableSetOf() private val _functionCallCheckers: MutableSet<FirFunctionCallChecker> = mutableSetOf()
private val _integerLiteralOperatorCallCheckers: MutableSet<FirIntegerLiteralOperatorCallChecker> = mutableSetOf()
private val _variableAssignmentCheckers: MutableSet<FirVariableAssignmentChecker> = mutableSetOf() private val _variableAssignmentCheckers: MutableSet<FirVariableAssignmentChecker> = mutableSetOf()
private val _tryExpressionCheckers: MutableSet<FirTryExpressionChecker> = mutableSetOf() private val _tryExpressionCheckers: MutableSet<FirTryExpressionChecker> = mutableSetOf()
private val _whenExpressionCheckers: MutableSet<FirWhenExpressionChecker> = mutableSetOf() private val _whenExpressionCheckers: MutableSet<FirWhenExpressionChecker> = mutableSetOf()
@@ -112,6 +115,7 @@ class ComposedExpressionCheckers : ExpressionCheckers() {
_qualifiedAccessExpressionCheckers += checkers.qualifiedAccessExpressionCheckers _qualifiedAccessExpressionCheckers += checkers.qualifiedAccessExpressionCheckers
_callCheckers += checkers.callCheckers _callCheckers += checkers.callCheckers
_functionCallCheckers += checkers.functionCallCheckers _functionCallCheckers += checkers.functionCallCheckers
_integerLiteralOperatorCallCheckers += checkers.integerLiteralOperatorCallCheckers
_variableAssignmentCheckers += checkers.variableAssignmentCheckers _variableAssignmentCheckers += checkers.variableAssignmentCheckers
_tryExpressionCheckers += checkers.tryExpressionCheckers _tryExpressionCheckers += checkers.tryExpressionCheckers
_whenExpressionCheckers += checkers.whenExpressionCheckers _whenExpressionCheckers += checkers.whenExpressionCheckers
@@ -22,6 +22,7 @@ abstract class ExpressionCheckers {
open val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker> = emptySet() open val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker> = emptySet()
open val callCheckers: Set<FirCallChecker> = emptySet() open val callCheckers: Set<FirCallChecker> = emptySet()
open val functionCallCheckers: Set<FirFunctionCallChecker> = emptySet() open val functionCallCheckers: Set<FirFunctionCallChecker> = emptySet()
open val integerLiteralOperatorCallCheckers: Set<FirIntegerLiteralOperatorCallChecker> = emptySet()
open val variableAssignmentCheckers: Set<FirVariableAssignmentChecker> = emptySet() open val variableAssignmentCheckers: Set<FirVariableAssignmentChecker> = emptySet()
open val tryExpressionCheckers: Set<FirTryExpressionChecker> = emptySet() open val tryExpressionCheckers: Set<FirTryExpressionChecker> = emptySet()
open val whenExpressionCheckers: Set<FirWhenExpressionChecker> = emptySet() open val whenExpressionCheckers: Set<FirWhenExpressionChecker> = emptySet()
@@ -53,6 +54,7 @@ abstract class ExpressionCheckers {
@CheckersComponentInternal internal val allQualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker> by lazy { qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers } @CheckersComponentInternal internal val allQualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker> by lazy { qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers }
@CheckersComponentInternal internal val allCallCheckers: Set<FirCallChecker> by lazy { callCheckers + basicExpressionCheckers } @CheckersComponentInternal internal val allCallCheckers: Set<FirCallChecker> by lazy { callCheckers + basicExpressionCheckers }
@CheckersComponentInternal internal val allFunctionCallCheckers: Set<FirFunctionCallChecker> by lazy { functionCallCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers + callCheckers } @CheckersComponentInternal internal val allFunctionCallCheckers: Set<FirFunctionCallChecker> by lazy { functionCallCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers + callCheckers }
@CheckersComponentInternal internal val allIntegerLiteralOperatorCallCheckers: Set<FirIntegerLiteralOperatorCallChecker> by lazy { integerLiteralOperatorCallCheckers + functionCallCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers + callCheckers }
@CheckersComponentInternal internal val allVariableAssignmentCheckers: Set<FirVariableAssignmentChecker> by lazy { variableAssignmentCheckers + qualifiedAccessCheckers + basicExpressionCheckers } @CheckersComponentInternal internal val allVariableAssignmentCheckers: Set<FirVariableAssignmentChecker> by lazy { variableAssignmentCheckers + qualifiedAccessCheckers + basicExpressionCheckers }
@CheckersComponentInternal internal val allTryExpressionCheckers: Set<FirTryExpressionChecker> by lazy { tryExpressionCheckers + basicExpressionCheckers } @CheckersComponentInternal internal val allTryExpressionCheckers: Set<FirTryExpressionChecker> by lazy { tryExpressionCheckers + basicExpressionCheckers }
@CheckersComponentInternal internal val allWhenExpressionCheckers: Set<FirWhenExpressionChecker> by lazy { whenExpressionCheckers + basicExpressionCheckers } @CheckersComponentInternal internal val allWhenExpressionCheckers: Set<FirWhenExpressionChecker> by lazy { whenExpressionCheckers + basicExpressionCheckers }
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.expressions.FirElvisExpression
import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirLoop import org.jetbrains.kotlin.fir.expressions.FirLoop
import org.jetbrains.kotlin.fir.expressions.FirLoopJump import org.jetbrains.kotlin.fir.expressions.FirLoopJump
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
@@ -46,6 +47,7 @@ typealias FirQualifiedAccessChecker = FirExpressionChecker<FirQualifiedAccess>
typealias FirQualifiedAccessExpressionChecker = FirExpressionChecker<FirQualifiedAccessExpression> typealias FirQualifiedAccessExpressionChecker = FirExpressionChecker<FirQualifiedAccessExpression>
typealias FirCallChecker = FirExpressionChecker<FirCall> typealias FirCallChecker = FirExpressionChecker<FirCall>
typealias FirFunctionCallChecker = FirExpressionChecker<FirFunctionCall> typealias FirFunctionCallChecker = FirExpressionChecker<FirFunctionCall>
typealias FirIntegerLiteralOperatorCallChecker = FirExpressionChecker<FirIntegerLiteralOperatorCall>
typealias FirVariableAssignmentChecker = FirExpressionChecker<FirVariableAssignment> typealias FirVariableAssignmentChecker = FirExpressionChecker<FirVariableAssignment>
typealias FirTryExpressionChecker = FirExpressionChecker<FirTryExpression> typealias FirTryExpressionChecker = FirExpressionChecker<FirTryExpression>
typealias FirWhenExpressionChecker = FirExpressionChecker<FirWhenExpression> typealias FirWhenExpressionChecker = FirExpressionChecker<FirWhenExpression>
@@ -48,6 +48,10 @@ class ExpressionCheckersDiagnosticComponent(
checkers.allFunctionCallCheckers.check(functionCall, data, reporter) checkers.allFunctionCallCheckers.check(functionCall, data, reporter)
} }
override fun visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall, data: CheckerContext) {
checkers.allIntegerLiteralOperatorCallCheckers.check(integerLiteralOperatorCall, data, reporter)
}
override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: CheckerContext) { override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: CheckerContext) {
checkers.allFunctionCallCheckers.check(implicitInvokeCall, data, reporter) checkers.allFunctionCallCheckers.check(implicitInvokeCall, data, reporter)
} }
@@ -19,6 +19,9 @@ val ConeKotlinType.isBooleanOrNullableBoolean: Boolean get() = isAnyOfBuiltinTyp
val ConeKotlinType.isEnum: Boolean get() = isBuiltinType(StandardClassIds.Enum, false) val ConeKotlinType.isEnum: Boolean get() = isBuiltinType(StandardClassIds.Enum, false)
val ConeKotlinType.isString: Boolean get() = isBuiltinType(StandardClassIds.String, false) val ConeKotlinType.isString: Boolean get() = isBuiltinType(StandardClassIds.String, false)
val ConeKotlinType.isInt: Boolean get() = isBuiltinType(StandardClassIds.Int, false) val ConeKotlinType.isInt: Boolean get() = isBuiltinType(StandardClassIds.Int, false)
val ConeKotlinType.isLong: Boolean get() = isBuiltinType(StandardClassIds.Long, false)
val ConeKotlinType.isUInt: Boolean get() = isBuiltinType(StandardClassIds.UInt, false)
val ConeKotlinType.isULong: Boolean get() = isBuiltinType(StandardClassIds.ULong, false)
val ConeKotlinType.isPrimitiveOrNullablePrimitive: Boolean get() = isAnyOfBuiltinType(StandardClassIds.primitiveTypes) val ConeKotlinType.isPrimitiveOrNullablePrimitive: Boolean get() = isAnyOfBuiltinType(StandardClassIds.primitiveTypes)
val ConeKotlinType.isPrimitive: Boolean get() = isPrimitiveOrNullablePrimitive && nullability == ConeNullability.NOT_NULL val ConeKotlinType.isPrimitive: Boolean get() = isPrimitiveOrNullablePrimitive && nullability == ConeNullability.NOT_NULL
val ConeKotlinType.isArrayType: Boolean val ConeKotlinType.isArrayType: Boolean
@@ -78,7 +78,8 @@ class Fir2IrTypeConverter(
object : TypeApproximatorConfiguration.AllFlexibleSameValue() { object : TypeApproximatorConfiguration.AllFlexibleSameValue() {
override val allFlexible: Boolean get() = true override val allFlexible: Boolean get() = true
override val errorType: Boolean get() = true override val errorType: Boolean get() = true
override val integerLiteralType: Boolean get() = true override val integerLiteralConstantType: Boolean get() = true
override val integerConstantOperatorType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true override val intersectionTypesInContravariantPositions: Boolean get() = true
} }
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.calls.jvm
import org.jetbrains.kotlin.fir.NoMutableState import org.jetbrains.kotlin.fir.NoMutableState
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
import org.jetbrains.kotlin.fir.resolve.calls.ConeCompositeConflictResolver import org.jetbrains.kotlin.fir.resolve.calls.ConeCompositeConflictResolver
import org.jetbrains.kotlin.fir.resolve.calls.ConeIntegerOperatorConflictResolver
import org.jetbrains.kotlin.fir.resolve.calls.ConeOverloadConflictResolver import org.jetbrains.kotlin.fir.resolve.calls.ConeOverloadConflictResolver
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
import org.jetbrains.kotlin.fir.types.typeContext import org.jetbrains.kotlin.fir.types.typeContext
@@ -24,7 +25,8 @@ object JvmCallConflictResolverFactory : ConeCallConflictResolverFactory() {
return ConeCompositeConflictResolver( return ConeCompositeConflictResolver(
ConeOverloadConflictResolver(specificityComparator, components), ConeOverloadConflictResolver(specificityComparator, components),
ConeEquivalentCallConflictResolver(specificityComparator, components), ConeEquivalentCallConflictResolver(specificityComparator, components),
JvmPlatformOverloadsConflictResolver(specificityComparator, components) JvmPlatformOverloadsConflictResolver(specificityComparator, components),
ConeIntegerOperatorConflictResolver(specificityComparator, components)
) )
} }
} }
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.scopes.FirUnstableSmartcastTypeScope
import org.jetbrains.kotlin.fir.scopes.impl.FirScopeWithFakeOverrideTypeCalculator import org.jetbrains.kotlin.fir.scopes.impl.FirScopeWithFakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.scopes.impl.FirStandardOverrideChecker import org.jetbrains.kotlin.fir.scopes.impl.FirStandardOverrideChecker
import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScope import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScope
import org.jetbrains.kotlin.fir.scopes.impl.getOrBuildScopeForIntegerConstantOperatorType
import org.jetbrains.kotlin.fir.scopes.scopeForClass import org.jetbrains.kotlin.fir.scopes.scopeForClass
import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
@@ -90,7 +91,8 @@ private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: Scope
this this
) )
is ConeDefinitelyNotNullType -> original.scope(useSiteSession, scopeSession, requiredPhase) is ConeDefinitelyNotNullType -> original.scope(useSiteSession, scopeSession, requiredPhase)
is ConeIntegerLiteralType -> error("ILT should not be in receiver position") is ConeIntegerConstantOperatorType -> scopeSession.getOrBuildScopeForIntegerConstantOperatorType(useSiteSession, this)
is ConeIntegerLiteralConstantType -> error("ILT should not be in receiver position")
else -> null else -> null
} }
} }
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2022 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.scopes.impl
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
object ConvertibleIntegerOperators {
val operatorsNames: Set<Name> = listOf(
"plus", "minus", "times", "div", "rem",
"and", "or", "xor",
"shl", "shr", "ushr"
).mapTo(mutableSetOf()) { Name.identifier(it) }
}
@@ -0,0 +1,158 @@
/*
* Copyright 2010-2022 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.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunctionCopy
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.scope
import org.jetbrains.kotlin.fir.resolve.scopeSessionKey
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.getFunctions
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.name.Name
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
class FirIntegerConstantOperatorScope(
val session: FirSession,
val scopeSession: ScopeSession,
val isUnsigned: Boolean
) : FirTypeScope() {
private val baseScope: FirTypeScope = run {
val baseType = when (isUnsigned) {
true -> session.builtinTypes.uIntType
false -> session.builtinTypes.intType
}.type
baseType.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing) ?: error("Scope for $baseType not found")
}
private val mappedFunctions = mutableMapOf<Name, FirNamedFunctionSymbol>()
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
if (name !in ConvertibleIntegerOperators.operatorsNames) {
return baseScope.processFunctionsByName(name, processor)
}
val wrappedSymbol = mappedFunctions.getOrPut(name) {
val allFunctions = baseScope.getFunctions(name)
val functionSymbol = allFunctions.first {
val coneType = it.fir.valueParameters.first().returnTypeRef.coneType
if (isUnsigned) {
coneType.isUInt
} else {
coneType.isInt
}
}
wrapIntOperator(functionSymbol)
}
processor(wrappedSymbol)
baseScope.processFunctionsByName(name, processor)
}
private fun wrapIntOperator(originalSymbol: FirNamedFunctionSymbol): FirNamedFunctionSymbol {
val originalFunction = originalSymbol.fir
val wrappedFunction = buildSimpleFunctionCopy(originalFunction) {
symbol = FirNamedFunctionSymbol(originalSymbol.callableId)
origin = FirDeclarationOrigin.WrappedIntegerOperator
returnTypeRef = buildResolvedTypeRef {
type = ConeIntegerConstantOperatorTypeImpl(isUnsigned, ConeNullability.NOT_NULL)
}
}.also {
it.originalForWrappedIntegerOperator = originalSymbol
it.isUnsignedWrappedIntegerOperator = isUnsigned
}
return wrappedFunction.symbol
}
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
baseScope.processPropertiesByName(name, processor)
}
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
baseScope.processDeclaredConstructors(processor)
}
override fun mayContainName(name: Name): Boolean {
return baseScope.mayContainName(name)
}
override fun getCallableNames(): Set<Name> {
return baseScope.getCallableNames()
}
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
// Int types don't have nested classifiers
}
override fun getClassifierNames(): Set<Name> {
return emptySet()
}
override fun processDirectOverriddenFunctionsWithBaseScope(
functionSymbol: FirNamedFunctionSymbol,
processor: (FirNamedFunctionSymbol, FirTypeScope) -> ProcessorAction
): ProcessorAction {
return ProcessorAction.NONE
}
override fun processDirectOverriddenPropertiesWithBaseScope(
propertySymbol: FirPropertySymbol,
processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction
): ProcessorAction {
return ProcessorAction.NONE
}
}
fun ScopeSession.getOrBuildScopeForIntegerConstantOperatorType(
session: FirSession,
type: ConeIntegerConstantOperatorType
): FirIntegerConstantOperatorScope {
return getOrBuild(type.isUnsigned, INTEGER_CONSTANT_OPERATOR_SCOPE) {
FirIntegerConstantOperatorScope(session, this, type.isUnsigned)
}
}
private val INTEGER_CONSTANT_OPERATOR_SCOPE = scopeSessionKey<Boolean, FirIntegerConstantOperatorScope>()
private object OriginalForWrappedIntegerOperator : FirDeclarationDataKey()
private object IsUnsignedForWrappedIntegerOperator : FirDeclarationDataKey()
var FirSimpleFunction.originalForWrappedIntegerOperator: FirNamedFunctionSymbol? by FirDeclarationDataRegistry.data(
OriginalForWrappedIntegerOperator
)
private var FirSimpleFunction.isUnsignedWrappedIntegerOperator: Boolean? by FirDeclarationDataRegistry.data(
IsUnsignedForWrappedIntegerOperator
)
@OptIn(ExperimentalContracts::class)
fun FirDeclaration.isWrappedIntegerOperator(): Boolean {
contract {
returns(true) implies (this@isWrappedIntegerOperator is FirSimpleFunction)
}
return (this as? FirSimpleFunction)?.originalForWrappedIntegerOperator != null
}
@OptIn(ExperimentalContracts::class)
fun FirBasedSymbol<*>.isWrappedIntegerOperator(): Boolean {
contract {
returns(true) implies (this@isWrappedIntegerOperator is FirNamedFunctionSymbol)
}
return fir.isWrappedIntegerOperator()
}
@OptIn(ExperimentalContracts::class)
fun FirBasedSymbol<*>.isWrappedIntegerOperatorForUnsignedType(): Boolean {
return (this as? FirNamedFunctionSymbol)?.fir?.isUnsignedWrappedIntegerOperator ?: false
}
@@ -43,6 +43,14 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
return this is ConeIntegerLiteralType return this is ConeIntegerLiteralType
} }
override fun TypeConstructorMarker.isIntegerLiteralConstantTypeConstructor(): Boolean {
return this is ConeIntegerLiteralConstantType
}
override fun TypeConstructorMarker.isIntegerConstantOperatorTypeConstructor(): Boolean {
return this is ConeIntegerConstantOperatorType
}
override fun TypeConstructorMarker.isLocalType(): Boolean { override fun TypeConstructorMarker.isLocalType(): Boolean {
if (this !is ConeClassLikeLookupTag) return false if (this !is ConeClassLikeLookupTag) return false
return classId.isLocal return classId.isLocal
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.resolve.dfa.FirDataFlowAnalyzer
import org.jetbrains.kotlin.fir.resolve.inference.FirCallCompleter import org.jetbrains.kotlin.fir.resolve.inference.FirCallCompleter
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.transformers.FirSyntheticCallGenerator import org.jetbrains.kotlin.fir.resolve.transformers.FirSyntheticCallGenerator
import org.jetbrains.kotlin.fir.resolve.transformers.IntegerLiteralAndOperatorApproximationTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
@@ -43,6 +44,7 @@ abstract class BodyResolveComponents : SessionHolder {
abstract val syntheticCallGenerator: FirSyntheticCallGenerator abstract val syntheticCallGenerator: FirSyntheticCallGenerator
abstract val dataFlowAnalyzer: FirDataFlowAnalyzer<*> abstract val dataFlowAnalyzer: FirDataFlowAnalyzer<*>
abstract val outerClassManager: FirOuterClassManager abstract val outerClassManager: FirOuterClassManager
abstract val integerLiteralAndOperatorApproximationTransformer: IntegerLiteralAndOperatorApproximationTransformer
} }
// --------------------------------------- Utils --------------------------------------- // --------------------------------------- Utils ---------------------------------------
@@ -47,8 +47,11 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
import org.jetbrains.kotlin.types.ConstantValueKind
import org.jetbrains.kotlin.types.SmartcastStability import org.jetbrains.kotlin.types.SmartcastStability
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
fun List<FirQualifierPart>.toTypeProjections(): Array<ConeTypeProjection> = fun List<FirQualifierPart>.toTypeProjections(): Array<ConeTypeProjection> =
asReversed().flatMap { it.typeArgumentList.typeArguments.map { typeArgument -> typeArgument.toConeTypeProjection() } }.toTypedArray() asReversed().flatMap { it.typeArgumentList.typeArguments.map { typeArgument -> typeArgument.toConeTypeProjection() } }.toTypedArray()
@@ -485,6 +488,7 @@ fun FirFunction.getAsForbiddenNamedArgumentsTarget(session: FirSession): Forbidd
} }
FirDeclarationOrigin.Synthetic -> null FirDeclarationOrigin.Synthetic -> null
FirDeclarationOrigin.RenamedForOverride -> null FirDeclarationOrigin.RenamedForOverride -> null
FirDeclarationOrigin.WrappedIntegerOperator -> null
is FirDeclarationOrigin.Plugin -> null // TODO: figure out what to do with plugin generated functions is FirDeclarationOrigin.Plugin -> null // TODO: figure out what to do with plugin generated functions
} }
} }
@@ -493,3 +497,15 @@ fun FirFunction.getAsForbiddenNamedArgumentsTarget(session: FirSession): Forbidd
// org.jetbrains.kotlin.fir.serialization.FirElementSerializer.functionProto // org.jetbrains.kotlin.fir.serialization.FirElementSerializer.functionProto
// org.jetbrains.kotlin.fir.serialization.FirElementSerializer.constructorProto // org.jetbrains.kotlin.fir.serialization.FirElementSerializer.constructorProto
fun FirFunction.getHasStableParameterNames(session: FirSession): Boolean = getAsForbiddenNamedArgumentsTarget(session) == null fun FirFunction.getHasStableParameterNames(session: FirSession): Boolean = getAsForbiddenNamedArgumentsTarget(session) == null
@OptIn(ExperimentalContracts::class)
fun FirExpression?.isIntegerLiteralOrOperatorCall(): Boolean {
contract {
returns(true) implies (this@isIntegerLiteralOrOperatorCall != null)
}
return when (this) {
is FirConstExpression<*> -> kind == ConstantValueKind.Int || kind == ConstantValueKind.IntegerLiteral
is FirIntegerLiteralOperatorCall -> true
else -> false
}
}
@@ -14,8 +14,10 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildErrorProperty
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.moduleData import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.resolve.isIntegerLiteralOrOperatorCall
import org.jetbrains.kotlin.fir.returnExpressions import org.jetbrains.kotlin.fir.returnExpressions
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.originalForWrappedIntegerOperator
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.classId
@@ -51,6 +53,9 @@ class CandidateFactory private constructor(
builtInExtensionFunctionReceiverValue: ReceiverValue? = null, builtInExtensionFunctionReceiverValue: ReceiverValue? = null,
objectsByName: Boolean = false objectsByName: Boolean = false
): Candidate { ): Candidate {
@Suppress("NAME_SHADOWING")
val symbol = symbol.unwrapIntegerOperatorSymbolIfNeeded(callInfo)
val result = Candidate( val result = Candidate(
symbol, dispatchReceiverValue, extensionReceiverValue, symbol, dispatchReceiverValue, extensionReceiverValue,
explicitReceiverKind, context.inferenceComponents.constraintSystemFactory, baseSystem, explicitReceiverKind, context.inferenceComponents.constraintSystemFactory, baseSystem,
@@ -87,6 +92,16 @@ class CandidateFactory private constructor(
return result return result
} }
private fun FirBasedSymbol<*>.unwrapIntegerOperatorSymbolIfNeeded(callInfo: CallInfo): FirBasedSymbol<*> {
if (this !is FirNamedFunctionSymbol) return this
val original = fir.originalForWrappedIntegerOperator ?: return this
return if (callInfo.arguments.first().isIntegerLiteralOrOperatorCall()) {
this
} else {
original
}
}
private fun ReceiverValue?.isCandidateFromCompanionObjectTypeScope(): Boolean { private fun ReceiverValue?.isCandidateFromCompanionObjectTypeScope(): Boolean {
val expressionReceiverValue = this as? ExpressionReceiverValue ?: return false val expressionReceiverValue = this as? ExpressionReceiverValue ?: return false
val resolvedQualifier = (expressionReceiverValue.explicitReceiver as? FirResolvedQualifier) ?: return false val resolvedQualifier = (expressionReceiverValue.explicitReceiver as? FirResolvedQualifier) ?: return false
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperator
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
class ConeIntegerOperatorConflictResolver(
specificityComparator: TypeSpecificityComparator,
inferenceComponents: InferenceComponents
) : AbstractConeCallConflictResolver(specificityComparator, inferenceComponents) {
override fun chooseMaximallySpecificCandidates(
candidates: Set<Candidate>,
discriminateGenerics: Boolean,
discriminateAbstracts: Boolean
): Set<Candidate> {
if (candidates.size <= 1) {
return candidates
}
val candidateWithWrappedIntegerOperator = candidates.firstOrNull { it.symbol.isWrappedIntegerOperator() }
return if (candidateWithWrappedIntegerOperator != null) {
setOf(candidateWithWrappedIntegerOperator)
} else {
candidates
}
}
}
@@ -29,7 +29,7 @@ fun Candidate.computeCompletionMode(
expectedType != null -> ConstraintSystemCompletionMode.FULL expectedType != null -> ConstraintSystemCompletionMode.FULL
// This is questionable as null return type can be only for error call // This is questionable as null return type can be only for error call
currentReturnType == null || currentReturnType is ConeIntegerLiteralType -> ConstraintSystemCompletionMode.PARTIAL currentReturnType == null -> ConstraintSystemCompletionMode.PARTIAL
// Full if return type for call has no type variables // Full if return type for call has no type variables
csBuilder.isProperType(currentReturnType) -> ConstraintSystemCompletionMode.FULL csBuilder.isProperType(currentReturnType) -> ConstraintSystemCompletionMode.FULL
@@ -123,9 +123,11 @@ class FirCallCompleter(
.buildAbstractResultingSubstitutor(session.typeContext) as ConeSubstitutor .buildAbstractResultingSubstitutor(session.typeContext) as ConeSubstitutor
val completedCall = call.transformSingle( val completedCall = call.transformSingle(
FirCallCompletionResultsWriterTransformer( FirCallCompletionResultsWriterTransformer(
session, finalSubstitutor, components.returnTypeCalculator, session, finalSubstitutor,
components.returnTypeCalculator,
session.typeApproximator, session.typeApproximator,
components.dataFlowAnalyzer, components.dataFlowAnalyzer,
components.integerLiteralAndOperatorApproximationTransformer
), ),
null null
) )
@@ -236,6 +238,7 @@ class FirCallCompleter(
session, substitutor, components.returnTypeCalculator, session, substitutor, components.returnTypeCalculator,
session.typeApproximator, session.typeApproximator,
components.dataFlowAnalyzer, components.dataFlowAnalyzer,
components.integerLiteralAndOperatorApproximationTransformer,
mode mode
) )
} }
@@ -41,6 +41,8 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirArrayOfCall
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.remapArgumentsWithVararg import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.remapArgumentsWithVararg
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.writeResultType import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.writeResultType
import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperator
import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperatorForUnsignedType
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
@@ -68,6 +70,7 @@ class FirCallCompletionResultsWriterTransformer(
private val typeCalculator: ReturnTypeCalculator, private val typeCalculator: ReturnTypeCalculator,
private val typeApproximator: ConeTypeApproximator, private val typeApproximator: ConeTypeApproximator,
private val dataFlowAnalyzer: FirDataFlowAnalyzer<*>, private val dataFlowAnalyzer: FirDataFlowAnalyzer<*>,
private val integerOperatorApproximator: IntegerLiteralAndOperatorApproximationTransformer,
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) {
@@ -126,14 +129,23 @@ class FirCallCompletionResultsWriterTransformer(
} }
} }
var dispatchReceiver = subCandidate.dispatchReceiverExpression()
var extensionReceiver = subCandidate.extensionReceiverExpression()
if (!declaration.isWrappedIntegerOperator()) {
val expectedDispatchReceiverType = (declaration as? FirCallableDeclaration)?.dispatchReceiverType
val expectedExtensionReceiverType = (declaration as? FirCallableDeclaration)?.receiverTypeRef?.coneType
dispatchReceiver = dispatchReceiver.transformSingle(integerOperatorApproximator, expectedDispatchReceiverType)
extensionReceiver = extensionReceiver.transformSingle(integerOperatorApproximator, expectedExtensionReceiverType)
}
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val result = qualifiedAccessExpression val result = qualifiedAccessExpression
.transformCalleeReference( .transformCalleeReference(
StoreCalleeReference, StoreCalleeReference,
calleeReference.toResolvedReference(), calleeReference.toResolvedReference(),
) )
.transformDispatchReceiver(StoreReceiver, subCandidate.dispatchReceiverExpression()) .transformDispatchReceiver(StoreReceiver, dispatchReceiver)
.transformExtensionReceiver(StoreReceiver, subCandidate.extensionReceiverExpression()) as T .transformExtensionReceiver(StoreReceiver, extensionReceiver) as T
if (result is FirPropertyAccessExpressionImpl && calleeReference.candidate.currentApplicability == CandidateApplicability.PROPERTY_AS_OPERATOR) { if (result is FirPropertyAccessExpressionImpl && calleeReference.candidate.currentApplicability == CandidateApplicability.PROPERTY_AS_OPERATOR) {
result.nonFatalDiagnostics.add(ConePropertyAsOperator(calleeReference.candidate.symbol as FirPropertySymbol)) result.nonFatalDiagnostics.add(ConePropertyAsOperator(calleeReference.candidate.symbol as FirPropertySymbol))
} }
@@ -199,8 +211,6 @@ class FirCallCompletionResultsWriterTransformer(
val subCandidate = calleeReference.candidate val subCandidate = calleeReference.candidate
val resultType: FirTypeRef val resultType: FirTypeRef
resultType = typeRef.substituteTypeRef(subCandidate) resultType = typeRef.substituteTypeRef(subCandidate)
val expectedArgumentsTypeMapping = runIf(!calleeReference.isError) { subCandidate.createArgumentsMapping() }
result.argumentList.transformArguments(this, expectedArgumentsTypeMapping)
if (calleeReference.isError) { if (calleeReference.isError) {
subCandidate.argumentMapping?.let { subCandidate.argumentMapping?.let {
result.replaceArgumentList(buildArgumentListForErrorCall(result.argumentList, it)) result.replaceArgumentList(buildArgumentListForErrorCall(result.argumentList, it))
@@ -225,6 +235,8 @@ class FirCallCompletionResultsWriterTransformer(
result.replaceArgumentList(newArgumentList) result.replaceArgumentList(newArgumentList)
} }
} }
val expectedArgumentsTypeMapping = runIf(!calleeReference.isError) { subCandidate.createArgumentsMapping() }
result.argumentList.transformArguments(this, expectedArgumentsTypeMapping)
result.replaceTypeRef(resultType) result.replaceTypeRef(resultType)
session.lookupTracker?.recordTypeResolveAsLookup(resultType, functionCall.source, null) session.lookupTracker?.recordTypeResolveAsLookup(resultType, functionCall.source, null)
@@ -445,12 +457,18 @@ class FirCallCompletionResultsWriterTransformer(
Pair(it.atom, finalSubstitutor.substituteOrSelf(substitutor.substituteOrSelf(it.returnType))) Pair(it.atom, finalSubstitutor.substituteOrSelf(substitutor.substituteOrSelf(it.returnType)))
} }
val isIntegerOperator = symbol.isWrappedIntegerOperator()
val arguments = argumentMapping?.map { (argument, valueParameter) -> val arguments = argumentMapping?.map { (argument, valueParameter) ->
val expectedType = if (valueParameter.isVararg) { val expectedType = when {
valueParameter.returnTypeRef.substitute(this).varargElementType() isIntegerOperator -> ConeIntegerConstantOperatorTypeImpl(
} else { isUnsigned = symbol.isWrappedIntegerOperatorForUnsignedType(),
valueParameter.returnTypeRef.substitute(this) ConeNullability.NOT_NULL
)
valueParameter.isVararg -> valueParameter.returnTypeRef.substitute(this).varargElementType()
else -> valueParameter.returnTypeRef.substitute(this)
} }
val unwrappedArgument: FirElement = when (val unwrappedArgument = argument.unwrapArgument()) { val unwrappedArgument: FirElement = when (val unwrappedArgument = argument.unwrapArgument()) {
is FirAnonymousFunctionExpression -> unwrappedArgument.anonymousFunction is FirAnonymousFunctionExpression -> unwrappedArgument.anonymousFunction
else -> unwrappedArgument else -> unwrappedArgument
@@ -781,7 +799,23 @@ class FirCallCompletionResultsWriterTransformer(
data: ExpectedArgumentType?, data: ExpectedArgumentType?,
): FirStatement { ): FirStatement {
if (data == ExpectedArgumentType.NoApproximation) return constExpression if (data == ExpectedArgumentType.NoApproximation) return constExpression
return constExpression.approximateIfIsIntegerConst(data?.getExpectedType(constExpression)) val expectedType = data?.getExpectedType(constExpression)
if (expectedType is ConeIntegerConstantOperatorType) {
return constExpression
}
return constExpression.transformSingle(integerOperatorApproximator, expectedType)
}
override fun transformIntegerLiteralOperatorCall(
integerLiteralOperatorCall: FirIntegerLiteralOperatorCall,
data: ExpectedArgumentType?
): FirStatement {
if (data == ExpectedArgumentType.NoApproximation) return integerLiteralOperatorCall
val expectedType = data?.getExpectedType(integerLiteralOperatorCall)
if (expectedType is ConeIntegerConstantOperatorType) {
return integerLiteralOperatorCall
}
return integerLiteralOperatorCall.transformSingle(integerOperatorApproximator, expectedType)
} }
override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ExpectedArgumentType?): FirStatement { override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ExpectedArgumentType?): FirStatement {
@@ -800,6 +834,15 @@ class FirCallCompletionResultsWriterTransformer(
return arrayOfCall return arrayOfCall
} }
override fun transformVarargArgumentsExpression(
varargArgumentsExpression: FirVarargArgumentsExpression,
data: ExpectedArgumentType?
): FirStatement {
val expectedType = data?.getExpectedType(varargArgumentsExpression)?.let { ExpectedArgumentType.ExpectedType(it) }
varargArgumentsExpression.transformChildren(this, expectedType)
return varargArgumentsExpression
}
private fun FirNamedReferenceWithCandidate.toResolvedReference(): FirNamedReference { private fun FirNamedReferenceWithCandidate.toResolvedReference(): FirNamedReference {
val errorDiagnostic = when { val errorDiagnostic = when {
this is FirErrorReferenceWithCandidate -> this.diagnostic this is FirErrorReferenceWithCandidate -> this.diagnostic
@@ -0,0 +1,126 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.scope
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
import org.jetbrains.kotlin.fir.resolvedSymbol
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.scopes.getFunctions
import org.jetbrains.kotlin.fir.scopes.impl.originalForWrappedIntegerOperator
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.ConstantValueKind
fun IntegerLiteralAndOperatorApproximationTransformer.approximateIfIsIntegerConst(expression: FirExpression, expectedType: ConeKotlinType? = null): FirExpression {
return expression.transformSingle(this, expectedType)
}
class IntegerLiteralAndOperatorApproximationTransformer(
val session: FirSession,
val scopeSession: ScopeSession
) : FirTransformer<ConeKotlinType?>() {
companion object {
private val TO_LONG = Name.identifier("toLong")
private val TO_U_LONG = Name.identifier("toULong")
}
private val toLongSymbol by lazy { findConversionFunction(session.builtinTypes.intType, TO_LONG)}
private val toULongSymbol by lazy { findConversionFunction(session.builtinTypes.uIntType, TO_U_LONG)}
private fun findConversionFunction(receiverType: FirImplicitBuiltinTypeRef, name: Name): FirNamedFunctionSymbol {
return receiverType.type.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing)!!.getFunctions(name).single()
}
override fun <E : FirElement> transformElement(element: E, data: ConeKotlinType?): E {
return element
}
override fun <T> transformConstExpression(
constExpression: FirConstExpression<T>,
data: ConeKotlinType?
): FirStatement {
val type = constExpression.resultType.coneTypeSafe<ConeIntegerLiteralType>() ?: return constExpression
val approximatedType = type.getApproximatedType(data)
constExpression.resultType = constExpression.resultType.resolvedTypeFromPrototype(approximatedType)
@Suppress("UNCHECKED_CAST")
val kind = approximatedType.toConstKind() as ConstantValueKind<T>
constExpression.replaceKind(kind)
return constExpression
}
override fun transformIntegerLiteralOperatorCall(
integerLiteralOperatorCall: FirIntegerLiteralOperatorCall,
data: ConeKotlinType?
): FirStatement {
@Suppress("UnnecessaryVariable")
val call = integerLiteralOperatorCall
val operatorType = call.resultType.coneTypeSafe<ConeIntegerLiteralType>() ?: return call
val approximatedType = operatorType.getApproximatedType(data)
call.transformDispatchReceiver(this, null)
call.transformExtensionReceiver(this, null)
call.argumentList.transformArguments(this, null)
call.resultType = call.resultType.resolvedTypeFromPrototype(approximatedType)
val calleeReference = call.calleeReference
// callee reference may also be an error reference and it's ok if wrapped operator function leaks throw it
if (calleeReference is FirResolvedNamedReference) {
val wrappedFunctionSymbol = calleeReference.resolvedSymbol as FirNamedFunctionSymbol
val originalFunctionSymbol = wrappedFunctionSymbol.fir.originalForWrappedIntegerOperator!!
call.replaceCalleeReference(
buildResolvedNamedReference {
name = calleeReference.name
source = calleeReference.source
resolvedSymbol = originalFunctionSymbol
}
)
}
if (approximatedType.isInt || approximatedType.isUInt) return call
val typeBeforeConversion = if (operatorType.isUnsigned) {
session.builtinTypes.uIntType
} else {
session.builtinTypes.intType
}
call.replaceTypeRef(typeBeforeConversion)
return buildFunctionCall {
source = call.source?.fakeElement(KtFakeSourceElementKind.IntToLongConversion)
typeRef = session.builtinTypes.longType
explicitReceiver = call
dispatchReceiver = call
this.calleeReference = buildResolvedNamedReference {
if (operatorType.isUnsigned) {
name = TO_U_LONG
resolvedSymbol = toULongSymbol
} else {
name = TO_LONG
resolvedSymbol = toLongSymbol
}
}
}
}
}
@@ -1,43 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.fir.types.toConstKind
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.types.ConstantValueKind
fun FirExpression.approximateIfIsIntegerConst(expectedType: ConeKotlinType? = null): FirExpression {
return transformSingle(IntegerLiteralTypeApproximationTransformer, expectedType)
}
private object IntegerLiteralTypeApproximationTransformer : FirTransformer<ConeKotlinType?>() {
override fun <E : FirElement> transformElement(element: E, data: ConeKotlinType?): E {
return element
}
override fun <T> transformConstExpression(
constExpression: FirConstExpression<T>,
data: ConeKotlinType?
): FirStatement {
val type = constExpression.resultType.coneTypeSafe<ConeIntegerLiteralType>() ?: return constExpression
val approximatedType = type.getApproximatedType(data)
constExpression.resultType = constExpression.resultType.resolvedTypeFromPrototype(approximatedType)
@Suppress("UNCHECKED_CAST")
val kind = approximatedType.toConstKind() as ConstantValueKind<T>
constExpression.replaceKind(kind)
return constExpression
}
}
@@ -18,10 +18,7 @@ import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.resolve.transformers.FirAbstractPhaseTransformer import org.jetbrains.kotlin.fir.resolve.transformers.*
import org.jetbrains.kotlin.fir.resolve.transformers.FirSpecificTypeResolverTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.FirSyntheticCallGenerator
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
@@ -112,5 +109,7 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
override val doubleColonExpressionResolver: FirDoubleColonExpressionResolver = FirDoubleColonExpressionResolver(session) override val doubleColonExpressionResolver: FirDoubleColonExpressionResolver = FirDoubleColonExpressionResolver(session)
override val outerClassManager: FirOuterClassManager = FirOuterClassManager(session, context.outerLocalClassForNested) override val outerClassManager: FirOuterClassManager = FirOuterClassManager(session, context.outerLocalClassForNested)
override val samResolver: FirSamResolver = FirSamResolverImpl(session, scopeSession, outerClassManager) override val samResolver: FirSamResolver = FirSamResolverImpl(session, scopeSession, outerClassManager)
override val integerLiteralAndOperatorApproximationTransformer: IntegerLiteralAndOperatorApproximationTransformer =
IntegerLiteralAndOperatorApproximationTransformer(session, scopeSession)
} }
} }
@@ -305,8 +305,8 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
): FirStatement { ): FirStatement {
dataFlowAnalyzer.enterDelegateExpression() dataFlowAnalyzer.enterDelegateExpression()
// First, resolve delegate expression in dependent context // First, resolve delegate expression in dependent context
val delegateExpression = val delegateExpression = wrappedDelegateExpression.expression.transformSingle(transformer, ResolutionMode.ContextDependent)
wrappedDelegateExpression.expression.transformSingle(transformer, ResolutionMode.ContextDependent) .transformSingle(components.integerLiteralAndOperatorApproximationTransformer, null)
// Second, replace result type of delegate expression with stub type if delegate not yet resolved // Second, replace result type of delegate expression with stub type if delegate not yet resolved
if (delegateExpression is FirQualifiedAccess) { if (delegateExpression is FirQualifiedAccess) {
@@ -355,7 +355,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
// Select delegate expression otherwise // Select delegate expression otherwise
return delegateExpression return delegateExpression
.approximateIfIsIntegerConst()
} }
private fun transformLocalVariable(variable: FirProperty): FirProperty { private fun transformLocalVariable(variable: FirProperty): FirProperty {
@@ -826,6 +825,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
components.returnTypeCalculator, components.returnTypeCalculator,
session.typeApproximator, session.typeApproximator,
dataFlowAnalyzer, dataFlowAnalyzer,
components.integerLiteralAndOperatorApproximationTransformer
) )
lambda.transformSingle(writer, expectedTypeRef.coneTypeSafe<ConeKotlinType>()?.toExpectedType()) lambda.transformSingle(writer, expectedTypeRef.coneTypeSafe<ConeKotlinType>()?.toExpectedType())
@@ -23,12 +23,15 @@ import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.resolve.dfa.coneType
import org.jetbrains.kotlin.fir.resolve.dfa.unwrapSmartcastExpression import org.jetbrains.kotlin.fir.resolve.dfa.unwrapSmartcastExpression
import org.jetbrains.kotlin.fir.resolve.diagnostics.* import org.jetbrains.kotlin.fir.resolve.diagnostics.*
import org.jetbrains.kotlin.fir.resolve.inference.FirStubInferenceSession import org.jetbrains.kotlin.fir.resolve.inference.FirStubInferenceSession
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver
import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperator
import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperatorForUnsignedType
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
@@ -373,14 +376,58 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
} catch (e: Throwable) { } catch (e: Throwable) {
throw RuntimeException("While resolving call ${functionCall.render()}", e) throw RuntimeException("While resolving call ${functionCall.render()}", e)
} }
val result = completeInference.transformToIntegerOperatorCallOrApproximateItIfNeeded(data)
dataFlowAnalyzer.exitFunctionCall(completeInference, callCompleted) dataFlowAnalyzer.exitFunctionCall(result, callCompleted)
if (callCompleted) { if (callCompleted) {
if (enableArrayOfCallTransformation) { if (enableArrayOfCallTransformation) {
return arrayOfCallTransformer.transformFunctionCall(completeInference, null) return arrayOfCallTransformer.transformFunctionCall(result, null)
} }
} }
return completeInference return result
}
private fun FirFunctionCall.transformToIntegerOperatorCallOrApproximateItIfNeeded(resolutionMode: ResolutionMode): FirFunctionCall {
if (!explicitReceiver.isIntegerLiteralOrOperatorCall()) return this
val resolvedSymbol = when (val reference = calleeReference) {
is FirResolvedNamedReference -> reference.resolvedSymbol
is FirErrorNamedReference -> reference.candidateSymbol
else -> null
} ?: return this
if (!resolvedSymbol.isWrappedIntegerOperator()) return this
val argument = this.argumentList.arguments.singleOrNull() ?: return this
assert(argument.isIntegerLiteralOrOperatorCall())
val originalCall = this
val integerOperatorType = ConeIntegerConstantOperatorTypeImpl(
isUnsigned = resolvedSymbol.isWrappedIntegerOperatorForUnsignedType(),
ConeNullability.NOT_NULL
)
val approximationIsNeeded = resolutionMode !is ResolutionMode.ReceiverResolution && resolutionMode !is ResolutionMode.ContextDependent
val integerOperatorCall = buildIntegerLiteralOperatorCall {
source = originalCall.source
typeRef = originalCall.typeRef.resolvedTypeFromPrototype(integerOperatorType)
annotations.addAll(originalCall.annotations)
typeArguments.addAll(originalCall.typeArguments)
calleeReference = originalCall.calleeReference
origin = originalCall.origin
argumentList = originalCall.argumentList
explicitReceiver = originalCall.explicitReceiver
dispatchReceiver = originalCall.dispatchReceiver
extensionReceiver = originalCall.extensionReceiver
}
return if (approximationIsNeeded) {
integerOperatorCall.transformSingle<FirFunctionCall, ConeKotlinType?>(
components.integerLiteralAndOperatorApproximationTransformer,
resolutionMode.expectedType?.coneTypeSafe()
)
} else {
integerOperatorCall
}
} }
override fun transformBlock(block: FirBlock, data: ResolutionMode): FirStatement { override fun transformBlock(block: FirBlock, data: ResolutionMode): FirStatement {
@@ -917,6 +964,10 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
constExpression.replaceKind(expressionType.toConstKind() as ConstantValueKind<T>) constExpression.replaceKind(expressionType.toConstKind() as ConstantValueKind<T>)
expressionType expressionType
} }
data is ResolutionMode.ReceiverResolution -> {
require(expressionType is ConeIntegerLiteralConstantTypeImpl)
ConeIntegerConstantOperatorTypeImpl(expressionType.isUnsigned, ConeNullability.NOT_NULL)
}
expectedTypeRef != null -> { expectedTypeRef != null -> {
require(expressionType is ConeIntegerLiteralConstantTypeImpl) require(expressionType is ConeIntegerLiteralConstantTypeImpl)
val coneType = expectedTypeRef.coneTypeSafe<ConeKotlinType>()?.fullyExpandedType(session) val coneType = expectedTypeRef.coneTypeSafe<ConeKotlinType>()?.fullyExpandedType(session)
@@ -0,0 +1,66 @@
/*
* Copyright 2010-2021 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.KtSourceElement
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.*
import org.jetbrains.kotlin.fir.FirImplementationDetail
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
abstract class FirIntegerLiteralOperatorCall : FirFunctionCall() {
abstract override val source: KtSourceElement?
abstract override val typeRef: FirTypeRef
abstract override val annotations: List<FirAnnotation>
abstract override val typeArguments: List<FirTypeProjection>
abstract override val explicitReceiver: FirExpression?
abstract override val dispatchReceiver: FirExpression
abstract override val extensionReceiver: FirExpression
abstract override val argumentList: FirArgumentList
abstract override val calleeReference: FirNamedReference
abstract override val origin: FirFunctionCallOrigin
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitIntegerLiteralOperatorCall(this, data)
@Suppress("UNCHECKED_CAST")
override fun <E: FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
transformer.transformIntegerLiteralOperatorCall(this, data) as E
@FirImplementationDetail
abstract override fun replaceSource(newSource: KtSourceElement?)
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
abstract override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>)
abstract override fun replaceExplicitReceiver(newExplicitReceiver: FirExpression?)
abstract override fun replaceArgumentList(newArgumentList: FirArgumentList)
abstract override fun replaceCalleeReference(newCalleeReference: FirNamedReference)
abstract override fun replaceCalleeReference(newCalleeReference: FirReference)
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirIntegerLiteralOperatorCall
abstract override fun <D> transformTypeArguments(transformer: FirTransformer<D>, data: D): FirIntegerLiteralOperatorCall
abstract override fun <D> transformExplicitReceiver(transformer: FirTransformer<D>, data: D): FirIntegerLiteralOperatorCall
abstract override fun <D> transformDispatchReceiver(transformer: FirTransformer<D>, data: D): FirIntegerLiteralOperatorCall
abstract override fun <D> transformExtensionReceiver(transformer: FirTransformer<D>, data: D): FirIntegerLiteralOperatorCall
abstract override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirIntegerLiteralOperatorCall
}
@@ -0,0 +1,70 @@
/*
* Copyright 2010-2021 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.builder
import kotlin.contracts.*
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirImplementationDetail
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirArgumentList
import org.jetbrains.kotlin.fir.expressions.FirEmptyArgumentList
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
import org.jetbrains.kotlin.fir.expressions.builder.FirAbstractFunctionCallBuilder
import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder
import org.jetbrains.kotlin.fir.expressions.impl.FirIntegerLiteralOperatorCallImpl
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.*
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
@FirBuilderDsl
open class FirIntegerLiteralOperatorCallBuilder : FirAbstractFunctionCallBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
override var source: KtSourceElement? = null
override lateinit var typeRef: FirTypeRef
override val annotations: MutableList<FirAnnotation> = mutableListOf()
override val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
override var explicitReceiver: FirExpression? = null
override var dispatchReceiver: FirExpression = FirNoReceiverExpression
override var extensionReceiver: FirExpression = FirNoReceiverExpression
override var argumentList: FirArgumentList = FirEmptyArgumentList
override lateinit var calleeReference: FirNamedReference
override lateinit var origin: FirFunctionCallOrigin
override fun build(): FirIntegerLiteralOperatorCall {
return FirIntegerLiteralOperatorCallImpl(
source,
typeRef,
annotations,
typeArguments,
explicitReceiver,
dispatchReceiver,
extensionReceiver,
argumentList,
calleeReference,
origin,
)
}
}
@OptIn(ExperimentalContracts::class)
inline fun buildIntegerLiteralOperatorCall(init: FirIntegerLiteralOperatorCallBuilder.() -> Unit): FirIntegerLiteralOperatorCall {
contract {
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
}
return FirIntegerLiteralOperatorCallBuilder().apply(init).build()
}
@@ -0,0 +1,129 @@
/*
* Copyright 2010-2021 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 org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirArgumentList
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.*
import org.jetbrains.kotlin.fir.FirImplementationDetail
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
internal class FirIntegerLiteralOperatorCallImpl(
override var source: KtSourceElement?,
override var typeRef: FirTypeRef,
override val annotations: MutableList<FirAnnotation>,
override val typeArguments: MutableList<FirTypeProjection>,
override var explicitReceiver: FirExpression?,
override var dispatchReceiver: FirExpression,
override var extensionReceiver: FirExpression,
override var argumentList: FirArgumentList,
override var calleeReference: FirNamedReference,
override val origin: FirFunctionCallOrigin,
) : FirIntegerLiteralOperatorCall() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
typeRef.accept(visitor, data)
annotations.forEach { it.accept(visitor, data) }
typeArguments.forEach { it.accept(visitor, data) }
explicitReceiver?.accept(visitor, data)
if (dispatchReceiver !== explicitReceiver) {
dispatchReceiver.accept(visitor, data)
}
if (extensionReceiver !== explicitReceiver && extensionReceiver !== dispatchReceiver) {
extensionReceiver.accept(visitor, data)
}
argumentList.accept(visitor, data)
calleeReference.accept(visitor, data)
}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirIntegerLiteralOperatorCallImpl {
typeRef = typeRef.transform(transformer, data)
transformAnnotations(transformer, data)
transformTypeArguments(transformer, data)
explicitReceiver = explicitReceiver?.transform(transformer, data)
if (dispatchReceiver !== explicitReceiver) {
dispatchReceiver = dispatchReceiver.transform(transformer, data)
}
if (extensionReceiver !== explicitReceiver && extensionReceiver !== dispatchReceiver) {
extensionReceiver = extensionReceiver.transform(transformer, data)
}
argumentList = argumentList.transform(transformer, data)
transformCalleeReference(transformer, data)
return this
}
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirIntegerLiteralOperatorCallImpl {
annotations.transformInplace(transformer, data)
return this
}
override fun <D> transformTypeArguments(transformer: FirTransformer<D>, data: D): FirIntegerLiteralOperatorCallImpl {
typeArguments.transformInplace(transformer, data)
return this
}
override fun <D> transformExplicitReceiver(transformer: FirTransformer<D>, data: D): FirIntegerLiteralOperatorCallImpl {
explicitReceiver = explicitReceiver?.transform(transformer, data)
return this
}
override fun <D> transformDispatchReceiver(transformer: FirTransformer<D>, data: D): FirIntegerLiteralOperatorCallImpl {
dispatchReceiver = dispatchReceiver.transform(transformer, data)
return this
}
override fun <D> transformExtensionReceiver(transformer: FirTransformer<D>, data: D): FirIntegerLiteralOperatorCallImpl {
extensionReceiver = extensionReceiver.transform(transformer, data)
return this
}
override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirIntegerLiteralOperatorCallImpl {
calleeReference = calleeReference.transform(transformer, data)
return this
}
@FirImplementationDetail
override fun replaceSource(newSource: KtSourceElement?) {
source = newSource
}
override fun replaceTypeRef(newTypeRef: FirTypeRef) {
typeRef = newTypeRef
}
override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>) {
typeArguments.clear()
typeArguments.addAll(newTypeArguments)
}
override fun replaceExplicitReceiver(newExplicitReceiver: FirExpression?) {
explicitReceiver = newExplicitReceiver
}
override fun replaceArgumentList(newArgumentList: FirArgumentList) {
argumentList = newArgumentList
}
override fun replaceCalleeReference(newCalleeReference: FirNamedReference) {
calleeReference = newCalleeReference
}
override fun replaceCalleeReference(newCalleeReference: FirReference) {
require(newCalleeReference is FirNamedReference)
replaceCalleeReference(newCalleeReference)
}
}
@@ -91,6 +91,7 @@ import org.jetbrains.kotlin.fir.declarations.FirErrorProperty
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirComponentCall import org.jetbrains.kotlin.fir.expressions.FirComponentCall
@@ -213,6 +214,8 @@ abstract class FirDefaultVisitor<out R, in D> : FirVisitor<R, D>() {
override fun visitPropertyAccessExpression(propertyAccessExpression: FirPropertyAccessExpression, data: D): R = visitQualifiedAccessExpression(propertyAccessExpression, data) override fun visitPropertyAccessExpression(propertyAccessExpression: FirPropertyAccessExpression, data: D): R = visitQualifiedAccessExpression(propertyAccessExpression, data)
override fun visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall, data: D): R = visitFunctionCall(integerLiteralOperatorCall, data)
override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: D): R = visitFunctionCall(implicitInvokeCall, data) override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: D): R = visitFunctionCall(implicitInvokeCall, data)
override fun visitComponentCall(componentCall: FirComponentCall, data: D): R = visitFunctionCall(componentCall, data) override fun visitComponentCall(componentCall: FirComponentCall, data: D): R = visitFunctionCall(componentCall, data)
@@ -91,6 +91,7 @@ import org.jetbrains.kotlin.fir.declarations.FirErrorProperty
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirComponentCall import org.jetbrains.kotlin.fir.expressions.FirComponentCall
@@ -213,6 +214,8 @@ abstract class FirDefaultVisitorVoid : FirVisitorVoid() {
override fun visitPropertyAccessExpression(propertyAccessExpression: FirPropertyAccessExpression) = visitQualifiedAccessExpression(propertyAccessExpression) override fun visitPropertyAccessExpression(propertyAccessExpression: FirPropertyAccessExpression) = visitQualifiedAccessExpression(propertyAccessExpression)
override fun visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall) = visitFunctionCall(integerLiteralOperatorCall)
override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall) = visitFunctionCall(implicitInvokeCall) override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall) = visitFunctionCall(implicitInvokeCall)
override fun visitComponentCall(componentCall: FirComponentCall) = visitFunctionCall(componentCall) override fun visitComponentCall(componentCall: FirComponentCall) = visitFunctionCall(componentCall)
@@ -91,6 +91,7 @@ import org.jetbrains.kotlin.fir.declarations.FirErrorProperty
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirComponentCall import org.jetbrains.kotlin.fir.expressions.FirComponentCall
@@ -492,6 +493,10 @@ abstract class FirTransformer<in D> : FirVisitor<FirElement, D>() {
return transformElement(functionCall, data) return transformElement(functionCall, data)
} }
open fun transformIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall, data: D): FirStatement {
return transformElement(integerLiteralOperatorCall, data)
}
open fun transformImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: D): FirStatement { open fun transformImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: D): FirStatement {
return transformElement(implicitInvokeCall, data) return transformElement(implicitInvokeCall, data)
} }
@@ -1040,6 +1045,10 @@ abstract class FirTransformer<in D> : FirVisitor<FirElement, D>() {
return transformFunctionCall(functionCall, data) return transformFunctionCall(functionCall, data)
} }
final override fun visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall, data: D): FirStatement {
return transformIntegerLiteralOperatorCall(integerLiteralOperatorCall, data)
}
final override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: D): FirStatement { final override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: D): FirStatement {
return transformImplicitInvokeCall(implicitInvokeCall, data) return transformImplicitInvokeCall(implicitInvokeCall, data)
} }
@@ -91,6 +91,7 @@ import org.jetbrains.kotlin.fir.declarations.FirErrorProperty
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirComponentCall import org.jetbrains.kotlin.fir.expressions.FirComponentCall
@@ -321,6 +322,8 @@ abstract class FirVisitor<out R, in D> {
open fun visitFunctionCall(functionCall: FirFunctionCall, data: D): R = visitElement(functionCall, data) open fun visitFunctionCall(functionCall: FirFunctionCall, data: D): R = visitElement(functionCall, data)
open fun visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall, data: D): R = visitElement(integerLiteralOperatorCall, data)
open fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: D): R = visitElement(implicitInvokeCall, data) open fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: D): R = visitElement(implicitInvokeCall, data)
open fun visitDelegatedConstructorCall(delegatedConstructorCall: FirDelegatedConstructorCall, data: D): R = visitElement(delegatedConstructorCall, data) open fun visitDelegatedConstructorCall(delegatedConstructorCall: FirDelegatedConstructorCall, data: D): R = visitElement(delegatedConstructorCall, data)
@@ -91,6 +91,7 @@ import org.jetbrains.kotlin.fir.declarations.FirErrorProperty
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirComponentCall import org.jetbrains.kotlin.fir.expressions.FirComponentCall
@@ -491,6 +492,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitElement(functionCall) visitElement(functionCall)
} }
open fun visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall) {
visitElement(integerLiteralOperatorCall)
}
open fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall) { open fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall) {
visitElement(implicitInvokeCall) visitElement(implicitInvokeCall)
} }
@@ -1039,6 +1044,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitFunctionCall(functionCall) visitFunctionCall(functionCall)
} }
final override fun visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall, data: Nothing?) {
visitIntegerLiteralOperatorCall(integerLiteralOperatorCall)
}
final override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: Nothing?) { final override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: Nothing?) {
visitImplicitInvokeCall(implicitInvokeCall) visitImplicitInvokeCall(implicitInvokeCall)
} }
@@ -1321,6 +1321,10 @@ open class FirRenderer(builder: StringBuilder, protected val mode: RenderMode =
visitCall(functionCall) visitCall(functionCall)
} }
override fun visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall) {
visitFunctionCall(integerLiteralOperatorCall)
}
override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall) { override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall) {
visitFunctionCall(implicitInvokeCall) visitFunctionCall(implicitInvokeCall)
} }
@@ -65,6 +65,10 @@ class BuiltinTypes {
val longType: FirImplicitBuiltinTypeRef = FirImplicitLongTypeRef(null) val longType: FirImplicitBuiltinTypeRef = FirImplicitLongTypeRef(null)
val doubleType: FirImplicitBuiltinTypeRef = FirImplicitDoubleTypeRef(null) val doubleType: FirImplicitBuiltinTypeRef = FirImplicitDoubleTypeRef(null)
val floatType: FirImplicitBuiltinTypeRef = FirImplicitFloatTypeRef(null) val floatType: FirImplicitBuiltinTypeRef = FirImplicitFloatTypeRef(null)
val uIntType: FirImplicitUIntTypeRef = FirImplicitUIntTypeRef(null)
val uLongType: FirImplicitULongTypeRef = FirImplicitULongTypeRef(null)
val nothingType: FirImplicitBuiltinTypeRef = FirImplicitNothingTypeRef(null) val nothingType: FirImplicitBuiltinTypeRef = FirImplicitNothingTypeRef(null)
val nullableNothingType: FirImplicitBuiltinTypeRef = FirImplicitNullableNothingTypeRef(null) val nullableNothingType: FirImplicitBuiltinTypeRef = FirImplicitNullableNothingTypeRef(null)
val charType: FirImplicitBuiltinTypeRef = FirImplicitCharTypeRef(null) val charType: FirImplicitBuiltinTypeRef = FirImplicitCharTypeRef(null)
@@ -19,6 +19,7 @@ sealed class FirDeclarationOrigin(private val displayName: String? = null, val f
object IntersectionOverride : FirDeclarationOrigin(fromSupertypes = true) object IntersectionOverride : FirDeclarationOrigin(fromSupertypes = true)
object Delegated : FirDeclarationOrigin() object Delegated : FirDeclarationOrigin()
object RenamedForOverride : FirDeclarationOrigin() object RenamedForOverride : FirDeclarationOrigin()
object WrappedIntegerOperator : FirDeclarationOrigin()
class Plugin(val key: FirPluginKey) : FirDeclarationOrigin(displayName = "Plugin[$key]", generated = true) class Plugin(val key: FirPluginKey) : FirDeclarationOrigin(displayName = "Plugin[$key]", generated = true)
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeExtensions.approxima
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeExtensions.createClassLikeType import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeExtensions.createClassLikeType
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeExtensions.createSupertypeList import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeExtensions.createSupertypeList
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeExtensions.getApproximatedTypeImpl import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeExtensions.getApproximatedTypeImpl
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeExtensions.withNullability import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeExtensions.withNullabilityAndAttributes
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
@@ -68,7 +68,7 @@ class ConeIntegerLiteralConstantTypeImpl(
addSignedPossibleTypes() addSignedPossibleTypes()
} }
return if (possibleTypes.size == 1) { return if (possibleTypes.size == 1) {
possibleTypes.single().withNullability(nullability).also { possibleTypes.single().withNullabilityAndAttributes(nullability, ConeAttributes.Empty).also {
if (AbstractTypeChecker.RUN_SLOW_ASSERTIONS) { if (AbstractTypeChecker.RUN_SLOW_ASSERTIONS) {
assert(it.isLong() || it.isULong()) assert(it.isLong() || it.isULong())
} }
@@ -149,12 +149,12 @@ private object ConeIntegerLiteralTypeExtensions {
fun ConeIntegerLiteralType.getApproximatedTypeImpl(expectedType: ConeKotlinType?): ConeClassLikeType { fun ConeIntegerLiteralType.getApproximatedTypeImpl(expectedType: ConeKotlinType?): ConeClassLikeType {
val expectedTypeForApproximation = (expectedType?.lowerBoundIfFlexible() as? ConeClassLikeType) val expectedTypeForApproximation = (expectedType?.lowerBoundIfFlexible() as? ConeClassLikeType)
?.withNullability(ConeNullability.NOT_NULL) ?.withNullabilityAndAttributes(ConeNullability.NOT_NULL, ConeAttributes.Empty)
val approximatedType = when (expectedTypeForApproximation) { val approximatedType = when (expectedTypeForApproximation) {
null, !in possibleTypes -> possibleTypes.first() null, !in possibleTypes -> possibleTypes.first()
else -> expectedTypeForApproximation else -> expectedTypeForApproximation
} }
return approximatedType.withNullability(nullability) return approximatedType.withNullabilityAndAttributes(nullability, attributes)
} }
@@ -218,12 +218,12 @@ private object ConeIntegerLiteralTypeExtensions {
return this return this
} }
fun ConeClassLikeType.withNullability(nullability: ConeNullability): ConeClassLikeType { fun ConeClassLikeType.withNullabilityAndAttributes(nullability: ConeNullability, attributes: ConeAttributes): ConeClassLikeType {
if (nullability == this.nullability) return this if (nullability == this.nullability && attributes == this.attributes) return this
return when (this) { return when (this) {
is ConeErrorType -> this is ConeErrorType -> this
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, typeArguments, nullability.isNullable) is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, typeArguments, nullability.isNullable, attributes)
else -> error("sealed") else -> error("sealed")
} }
} }
@@ -93,6 +93,14 @@ class FirImplicitFloatTypeRef(
source: KtSourceElement? source: KtSourceElement?
) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Float) ) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Float)
class FirImplicitUIntTypeRef(
source: KtSourceElement?
) : FirImplicitBuiltinTypeRef(source, StandardClassIds.UInt)
class FirImplicitULongTypeRef(
source: KtSourceElement?
) : FirImplicitBuiltinTypeRef(source, StandardClassIds.ULong)
class FirImplicitNothingTypeRef( class FirImplicitNothingTypeRef(
source: KtSourceElement? source: KtSourceElement?
) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Nothing) ) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Nothing)
@@ -177,6 +185,8 @@ fun FirImplicitBuiltinTypeRef.withFakeSource(kind: KtFakeSourceElementKind): Fir
is FirImplicitLongTypeRef -> FirImplicitLongTypeRef(newSource) is FirImplicitLongTypeRef -> FirImplicitLongTypeRef(newSource)
is FirImplicitDoubleTypeRef -> FirImplicitDoubleTypeRef(newSource) is FirImplicitDoubleTypeRef -> FirImplicitDoubleTypeRef(newSource)
is FirImplicitFloatTypeRef -> FirImplicitFloatTypeRef(newSource) is FirImplicitFloatTypeRef -> FirImplicitFloatTypeRef(newSource)
is FirImplicitUIntTypeRef -> FirImplicitUIntTypeRef(newSource)
is FirImplicitULongTypeRef -> FirImplicitULongTypeRef(newSource)
is FirImplicitNothingTypeRef -> FirImplicitNothingTypeRef(newSource) is FirImplicitNothingTypeRef -> FirImplicitNothingTypeRef(newSource)
is FirImplicitNullableNothingTypeRef -> FirImplicitNullableNothingTypeRef(newSource) is FirImplicitNullableNothingTypeRef -> FirImplicitNullableNothingTypeRef(newSource)
is FirImplicitCharTypeRef -> FirImplicitCharTypeRef(newSource) is FirImplicitCharTypeRef -> FirImplicitCharTypeRef(newSource)
@@ -192,6 +192,7 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
value = "FirFunctionCallOrigin.Regular" value = "FirFunctionCallOrigin.Regular"
} }
} }
builder(integerLiteralOperatorCall, init = configurationForFunctionCallBuilder)
builder(implicitInvokeCall, init = configurationForFunctionCallBuilder) builder(implicitInvokeCall, init = configurationForFunctionCallBuilder)
builder(getClassCall) { builder(getClassCall) {
@@ -111,6 +111,7 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
val qualifiedAccessExpression by element(Expression, expression, qualifiedAccess) val qualifiedAccessExpression by element(Expression, expression, qualifiedAccess)
val propertyAccessExpression by element(Expression, qualifiedAccessExpression) val propertyAccessExpression by element(Expression, qualifiedAccessExpression)
val functionCall by element(Expression, qualifiedAccessExpression, call) val functionCall by element(Expression, qualifiedAccessExpression, call)
val integerLiteralOperatorCall by element(Expression, functionCall)
val implicitInvokeCall by element(Expression, functionCall) val implicitInvokeCall by element(Expression, functionCall)
val delegatedConstructorCall by element(Expression, resolvable, call) val delegatedConstructorCall by element(Expression, resolvable, call)
val componentCall by element(Expression, functionCall) val componentCall by element(Expression, functionCall)
@@ -560,6 +560,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
"FirSafeCallExpressionImpl", "FirSafeCallExpressionImpl",
"FirCheckedSafeCallSubjectImpl", "FirCheckedSafeCallSubjectImpl",
"FirArrayOfCallImpl", "FirArrayOfCallImpl",
"FirIntegerLiteralOperatorCallImpl"
) )
configureFieldInAllImplementations( configureFieldInAllImplementations(
field = "typeRef", field = "typeRef",
@@ -188,6 +188,10 @@ sealed class KtFakeSourceElementKind : KtSourceElementKind() {
// with a fake source that refers to the value parameter in the function type notation // with a fake source that refers to the value parameter in the function type notation
// e.g., `(x: Int) -> Unit` becomes `Function1<@ParameterName("x") Int, Unit>` // e.g., `(x: Int) -> Unit` becomes `Function1<@ParameterName("x") Int, Unit>`
object ParameterNameAnnotationCall : KtFakeSourceElementKind() object ParameterNameAnnotationCall : KtFakeSourceElementKind()
// for implicit conversion from int to long with `.toLong` function
// e.g. val x: Long = 1 + 1 becomes val x: Long = (1 + 1).toLong()
object IntToLongConversion : KtFakeSourceElementKind()
} }
sealed class AbstractKtSourceElement { sealed class AbstractKtSourceElement {
@@ -31,7 +31,7 @@ open class TypeTranslatorImpl(
object : TypeApproximatorConfiguration.AllFlexibleSameValue() { object : TypeApproximatorConfiguration.AllFlexibleSameValue() {
override val allFlexible: Boolean get() = true override val allFlexible: Boolean get() = true
override val errorType: Boolean get() = true override val errorType: Boolean get() = true
override val integerLiteralType: Boolean get() = true override val integerLiteralConstantType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true override val intersectionTypesInContravariantPositions: Boolean get() = true
} }
@@ -306,7 +306,9 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
setOf(byteType, shortType, intType, longType) setOf(byteType, shortType, intType, longType)
} }
override fun TypeConstructorMarker.isIntegerLiteralTypeConstructor() = false override fun TypeConstructorMarker.isIntegerLiteralTypeConstructor(): Boolean = false
override fun TypeConstructorMarker.isIntegerLiteralConstantTypeConstructor(): Boolean = false
override fun TypeConstructorMarker.isIntegerConstantOperatorTypeConstructor(): Boolean = false
override fun TypeConstructorMarker.isLocalType(): Boolean { override fun TypeConstructorMarker.isLocalType(): Boolean {
if (this !is IrClassSymbol) return false if (this !is IrClassSymbol) return false
@@ -113,4 +113,4 @@ class IrCapturedType(
override fun hashCode(): Int { override fun hashCode(): Int {
return (captureStatus.hashCode() * 31 + (lowerType?.hashCode() ?: 0)) * 31 + constructor.hashCode() return (captureStatus.hashCode() * 31 + (lowerType?.hashCode() ?: 0)) * 31 + constructor.hashCode()
} }
} }
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator.commonSuperType import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator.commonSuperType
import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.*
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
abstract class AbstractTypeApproximator( abstract class AbstractTypeApproximator(
@@ -340,11 +341,16 @@ abstract class AbstractTypeApproximator(
return if (conf.typeVariable(typeConstructor)) null else type.defaultResult(toSuper) return if (conf.typeVariable(typeConstructor)) null else type.defaultResult(toSuper)
} }
if (typeConstructor.isIntegerLiteralTypeConstructor()) { if (typeConstructor.isIntegerLiteralConstantTypeConstructor()) {
return if (conf.integerLiteralType) return runIf(conf.integerLiteralConstantType) {
typeConstructor.getApproximatedIntegerLiteralType().withNullability(type.isMarkedNullable()) typeConstructor.getApproximatedIntegerLiteralType().withNullability(type.isMarkedNullable())
else }
null }
if (typeConstructor.isIntegerConstantOperatorTypeConstructor()) {
return runIf(conf.integerConstantOperatorType) {
typeConstructor.getApproximatedIntegerLiteralType().withNullability(type.isMarkedNullable())
}
} }
return approximateLocalTypes(type, conf, toSuper) // simple classifier type return approximateLocalTypes(type, conf, toSuper) // simple classifier type
@@ -19,7 +19,8 @@ open class TypeApproximatorConfiguration {
open val dynamic: Boolean get() = false // DynamicType open val dynamic: Boolean get() = false // DynamicType
open val rawType: Boolean get() = false // RawTypeImpl open val rawType: Boolean get() = false // RawTypeImpl
open val errorType: Boolean get() = false open val errorType: Boolean get() = false
open val integerLiteralType: Boolean = false // IntegerLiteralTypeConstructor open val integerLiteralConstantType: Boolean get() = false // IntegerLiteralTypeConstructor
open val integerConstantOperatorType: Boolean get() = false
open val definitelyNotNullType: Boolean get() = true open val definitelyNotNullType: Boolean get() = true
open val intersection: IntersectionStrategy = IntersectionStrategy.TO_COMMON_SUPERTYPE open val intersection: IntersectionStrategy = IntersectionStrategy.TO_COMMON_SUPERTYPE
open val intersectionTypesInContravariantPositions = false open val intersectionTypesInContravariantPositions = false
@@ -47,7 +48,7 @@ open class TypeApproximatorConfiguration {
override val allFlexible: Boolean get() = true override val allFlexible: Boolean get() = true
override val intersection: IntersectionStrategy get() = IntersectionStrategy.ALLOWED override val intersection: IntersectionStrategy get() = IntersectionStrategy.ALLOWED
override val errorType: Boolean get() = true override val errorType: Boolean get() = true
override val integerLiteralType: Boolean get() = true override val integerLiteralConstantType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true override val intersectionTypesInContravariantPositions: Boolean get() = true
} }
@@ -55,7 +56,7 @@ open class TypeApproximatorConfiguration {
override val allFlexible: Boolean get() = true override val allFlexible: Boolean get() = true
override val errorType: Boolean get() = true override val errorType: Boolean get() = true
override val definitelyNotNullType: Boolean get() = false override val definitelyNotNullType: Boolean get() = false
override val integerLiteralType: Boolean get() = true override val integerLiteralConstantType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true override val intersectionTypesInContravariantPositions: Boolean get() = true
} }
@@ -75,23 +76,25 @@ open class TypeApproximatorConfiguration {
object IncorporationConfiguration : AbstractCapturedTypesApproximation(CaptureStatus.FOR_INCORPORATION) object IncorporationConfiguration : AbstractCapturedTypesApproximation(CaptureStatus.FOR_INCORPORATION)
object SubtypeCapturedTypesApproximation : AbstractCapturedTypesApproximation(CaptureStatus.FOR_SUBTYPING) object SubtypeCapturedTypesApproximation : AbstractCapturedTypesApproximation(CaptureStatus.FOR_SUBTYPING)
object InternalTypesApproximation : AbstractCapturedTypesApproximation(CaptureStatus.FROM_EXPRESSION) { object InternalTypesApproximation : AbstractCapturedTypesApproximation(CaptureStatus.FROM_EXPRESSION) {
override val integerLiteralType: Boolean get() = true override val integerLiteralConstantType: Boolean get() = true
override val integerConstantOperatorType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true override val intersectionTypesInContravariantPositions: Boolean get() = true
} }
object FinalApproximationAfterResolutionAndInference : object FinalApproximationAfterResolutionAndInference :
AbstractCapturedTypesApproximation(CaptureStatus.FROM_EXPRESSION) { AbstractCapturedTypesApproximation(CaptureStatus.FROM_EXPRESSION) {
override val integerLiteralType: Boolean get() = true override val integerLiteralConstantType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true override val intersectionTypesInContravariantPositions: Boolean get() = true
} }
object TypeArgumentApproximation : AbstractCapturedTypesApproximation(null) { object TypeArgumentApproximation : AbstractCapturedTypesApproximation(null) {
override val integerLiteralType: Boolean get() = true override val integerLiteralConstantType: Boolean get() = true
override val integerConstantOperatorType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true override val intersectionTypesInContravariantPositions: Boolean get() = true
} }
object IntegerLiteralsTypesApproximation : AllFlexibleSameValue() { object IntegerLiteralsTypesApproximation : AllFlexibleSameValue() {
override val integerLiteralType: Boolean get() = true override val integerLiteralConstantType: Boolean get() = true
override val allFlexible: Boolean get() = true override val allFlexible: Boolean get() = true
override val intersection: IntersectionStrategy get() = IntersectionStrategy.ALLOWED override val intersection: IntersectionStrategy get() = IntersectionStrategy.ALLOWED
override val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean get() = { true } override val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean get() = { true }
@@ -1,6 +1,4 @@
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition // LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_BACKEND_FIR: JVM_IR
// FIR status: don't support legacy feature; for reasons this test is ignored, go to KT-46419
fun box(): String { fun box(): String {
val a: Long = 2147483647 + 1 val a: Long = 2147483647 + 1
+2 -1
View File
@@ -1,5 +1,6 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition // !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_FIR_DIAGNOSTICS // IGNORE_BACKEND_FIR: JVM_IR
// FIR status: don't support legacy feature
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_STDLIB // WITH_STDLIB
-1
View File
@@ -1,5 +1,4 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition // !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_FIR_DIAGNOSTICS
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_STDLIB // WITH_STDLIB
+1 -1
View File
@@ -1,5 +1,5 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition // !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_FIR_DIAGNOSTICS // IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_STDLIB // WITH_STDLIB
+1 -1
View File
@@ -1,5 +1,5 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition // !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_FIR_DIAGNOSTICS // IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_STDLIB // WITH_STDLIB
+1 -1
View File
@@ -1,5 +1,5 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition // !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_FIR_DIAGNOSTICS // IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_STDLIB // WITH_STDLIB
+1 -1
View File
@@ -1,5 +1,5 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition // !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_FIR_DIAGNOSTICS // IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_STDLIB // WITH_STDLIB
+1 -1
View File
@@ -1,5 +1,5 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition // !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_FIR_DIAGNOSTICS // IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_STDLIB // WITH_STDLIB
@@ -8,6 +8,6 @@ annotation class Ann(
val l: Long val l: Long
) )
@Ann(<!ARGUMENT_TYPE_MISMATCH!>1 / 1<!>, <!ARGUMENT_TYPE_MISMATCH!>1 / 1<!>, 1 / 1, <!ARGUMENT_TYPE_MISMATCH!>1 / 1<!>) class MyClass @Ann(<!ARGUMENT_TYPE_MISMATCH!>1 / 1<!>, <!ARGUMENT_TYPE_MISMATCH!>1 / 1<!>, 1 / 1, 1 / 1) class MyClass
// EXPECTED: @Ann(b = 1.toByte(), i = 1, l = 1.toLong(), s = 1.toShort()) // EXPECTED: @Ann(b = 1.toByte(), i = 1, l = 1.toLong(), s = 1.toShort())
@@ -7,6 +7,6 @@ annotation class Ann(
val l3: Long val l3: Long
) )
@Ann(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>, java.lang.Long.MAX_VALUE + 1 - 1, java.lang.Long.MAX_VALUE - 1) class MyClass @Ann(1 + 1, java.lang.Long.MAX_VALUE + 1 - 1, java.lang.Long.MAX_VALUE - 1) class MyClass
// EXPECTED: @Ann(l1 = 2.toLong(), l2 = 9223372036854775807.toLong(), l3 = 9223372036854775806.toLong()) // EXPECTED: @Ann(l1 = 2.toLong(), l2 = 9223372036854775807.toLong(), l3 = 9223372036854775806.toLong())
@@ -8,6 +8,6 @@ annotation class Ann(
val l: Long val l: Long
) )
@Ann(<!ARGUMENT_TYPE_MISMATCH!>1 * 1<!>, <!ARGUMENT_TYPE_MISMATCH!>1 * 1<!>, 1 * 1, <!ARGUMENT_TYPE_MISMATCH!>1 * 1<!>) class MyClass @Ann(<!ARGUMENT_TYPE_MISMATCH!>1 * 1<!>, <!ARGUMENT_TYPE_MISMATCH!>1 * 1<!>, 1 * 1, 1 * 1) class MyClass
// EXPECTED: @Ann(b = 1.toByte(), i = 1, l = 1.toLong(), s = 1.toShort()) // EXPECTED: @Ann(b = 1.toByte(), i = 1, l = 1.toLong(), s = 1.toShort())
@@ -8,6 +8,6 @@ annotation class Ann(
val l: Long val l: Long
) )
@Ann(<!ARGUMENT_TYPE_MISMATCH!>1 - 1<!>, <!ARGUMENT_TYPE_MISMATCH!>1 - 1<!>, 1 - 1, <!ARGUMENT_TYPE_MISMATCH!>1 - 1<!>) class MyClass @Ann(<!ARGUMENT_TYPE_MISMATCH!>1 - 1<!>, <!ARGUMENT_TYPE_MISMATCH!>1 - 1<!>, 1 - 1, 1 - 1) class MyClass
// EXPECTED: @Ann(b = 0.toByte(), i = 0, l = 0.toLong(), s = 0.toShort()) // EXPECTED: @Ann(b = 0.toByte(), i = 0, l = 0.toLong(), s = 0.toShort())
@@ -8,6 +8,6 @@ annotation class Ann(
val l: Long val l: Long
) )
@Ann(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>, <!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>, 1 % 1, <!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>) class MyClass @Ann(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>, <!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>, 1 % 1, 1 % 1) class MyClass
// EXPECTED: @Ann(b = 0.toByte(), i = 0, l = 0.toLong(), s = 0.toShort()) // EXPECTED: @Ann(b = 0.toByte(), i = 0, l = 0.toLong(), s = 0.toShort())
@@ -8,6 +8,6 @@ annotation class Ann(
val l: Long val l: Long
) )
@Ann(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>, <!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>, 1 + 1, <!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>) class MyClass @Ann(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>, <!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>, 1 + 1, 1 + 1) class MyClass
// EXPECTED: @Ann(b = 2.toByte(), i = 2, l = 2.toLong(), s = 2.toShort()) // EXPECTED: @Ann(b = 2.toByte(), i = 2, l = 2.toLong(), s = 2.toShort())
@@ -17,7 +17,7 @@ fun test() {
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 - 1.toLong()<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 - 1.toLong()<!>)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 - 1.toShort()<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 - 1.toShort()<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 - 1<!>) fooLong(1 - 1)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 - 1.toInt()<!>) fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 - 1.toInt()<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 - 1.toByte()<!>) fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 - 1.toByte()<!>)
fooLong(1 - 1.toLong()) fooLong(1 - 1.toLong())
@@ -1,5 +1,5 @@
val p1: Int = 1 - 1 val p1: Int = 1 - 1
val p2: Long = <!TYPE_MISMATCH!>1 - 1<!> val p2: Long = 1 - 1
val p3: Byte = <!TYPE_MISMATCH!>1 - 1<!> val p3: Byte = <!TYPE_MISMATCH!>1 - 1<!>
val p4: Short = <!TYPE_MISMATCH!>1 - 1<!> val p4: Short = <!TYPE_MISMATCH!>1 - 1<!>
@@ -7,21 +7,21 @@ fun fooShort(p: Short) = p
fun test() { fun test() {
fooInt(1 + 1) fooInt(1 + 1)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>) fooLong(1 + 1)
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>) fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>)
fooInt(1 * 1) fooInt(1 * 1)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 * 1<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 * 1<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 * 1<!>) fooLong(1 * 1)
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 * 1<!>) fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 * 1<!>)
fooInt(1 / 1) fooInt(1 / 1)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 / 1<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 / 1<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 / 1<!>) fooLong(1 / 1)
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 / 1<!>) fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 / 1<!>)
fooInt(1 % 1) fooInt(1 % 1)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>) fooLong(1 % 1)
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>) fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>)
} }
@@ -7,21 +7,21 @@ fun fooShort(p: Short) = p
fun test() { fun test() {
fooInt(1.plus(1)) fooInt(1.plus(1))
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1.plus(1)<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1.plus(1)<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1.plus(1)<!>) fooLong(1.plus(1))
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1.plus(1)<!>) fooShort(<!ARGUMENT_TYPE_MISMATCH!>1.plus(1)<!>)
fooInt(1.times(1)) fooInt(1.times(1))
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1.times(1)<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1.times(1)<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1.times(1)<!>) fooLong(1.times(1))
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1.times(1)<!>) fooShort(<!ARGUMENT_TYPE_MISMATCH!>1.times(1)<!>)
fooInt(1.div(1)) fooInt(1.div(1))
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1.div(1)<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1.div(1)<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1.div(1)<!>) fooLong(1.div(1))
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1.div(1)<!>) fooShort(<!ARGUMENT_TYPE_MISMATCH!>1.div(1)<!>)
fooInt(1.rem(1)) fooInt(1.rem(1))
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1.rem(1)<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1.rem(1)<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1.rem(1)<!>) fooLong(1.rem(1))
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1.rem(1)<!>) fooShort(<!ARGUMENT_TYPE_MISMATCH!>1.rem(1)<!>)
} }
@@ -7,21 +7,21 @@ fun fooShort(p: Short) = p
fun test() { fun test() {
fooInt(1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1) fooInt(1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1<!>) fooLong(1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1)
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1<!>) fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1<!>)
fooInt(1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1) fooInt(1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1<!>) fooLong(1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1)
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1<!>) fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1<!>)
fooInt(1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1) fooInt(1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1<!>) fooLong(1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1)
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1<!>) fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1<!>)
fooInt(1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1) fooInt(1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1<!>) fooLong(1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1)
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1<!>) fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1<!>)
} }
@@ -0,0 +1,13 @@
// LANGUAGE: +ApproximateIntegerLiteralTypesInReceiverPosition
val p1: Byte = <!TYPE_MISMATCH!>(1 + 2) * 2<!>
val p2: Short = <!TYPE_MISMATCH!>(1 + 2) * 2<!>
val p3: Int = (1 + 2) * 2
val p4: Long = (1 + 2) * 2
val b1: Byte = <!TYPE_MISMATCH!>(1.toByte() + 2) * 2<!>
val b2: Short = <!TYPE_MISMATCH!>(1.toShort() + 2) * 2<!>
val b3: Int = (1.toInt() + 2) * 2
val b4: Long = (1.toLong() + 2) * 2
val i1: Int = (1.toByte() + 2) * 2
val i2: Int = (1.toShort() + 2) * 2
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// LANGUAGE: +ApproximateIntegerLiteralTypesInReceiverPosition // LANGUAGE: +ApproximateIntegerLiteralTypesInReceiverPosition
val p1: Byte = <!TYPE_MISMATCH!>(1 + 2) * 2<!> val p1: Byte = <!TYPE_MISMATCH!>(1 + 2) * 2<!>
val p2: Short = <!TYPE_MISMATCH!>(1 + 2) * 2<!> val p2: Short = <!TYPE_MISMATCH!>(1 + 2) * 2<!>
@@ -0,0 +1,65 @@
// SKIP_TXT
// FIR_DUMP
// ISSUE: KT-38895, KT-50996, KT-51000
interface A
interface B
fun takeByte(x: Byte) {}
fun takeInt(x: Int) {}
fun takeNullableInt(x: Int) {}
fun takeLong(x: Long) {}
fun takeNullableLong(x: Long) {}
fun takeOverloaded(x: Int): A = null!! // (1)
fun takeOverloaded(x: Long): B = null!! // (2)
fun takeA(a: A) {}
fun takeB(b: B) {}
fun test_constants() {
takeByte(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>) // error
takeInt(1 + 1 + 1) // OK
takeNullableInt(1 + 1 + 1) // OK
takeLong(1 + 1 + 1) // will be OK with implicit widening conversion
takeNullableLong(1 + 1 + 1) // will be OK with implicit widening conversion
val x = takeOverloaded(2147483648 - 1 + 1) // now resolved to (1), will be resolved to (2)
takeA(<!ARGUMENT_TYPE_MISMATCH!>x<!>)
takeB(x)
}
val topLevelIntProperty: Int = 1 + 1 + 1
val topLevelLongProperty: Long = 1 + 1 + 1
val topLevelImplicitIntProperty = 1 + 1 + 1
val topLevelImplicitLongProperty = 3000000000 * 2 + 1
fun testTopLevelProperties() {
// OK
takeInt(topLevelIntProperty)
takeLong(topLevelLongProperty)
takeInt(topLevelImplicitIntProperty)
takeLong(topLevelImplicitLongProperty)
// no conversion for properties
takeLong(<!ARGUMENT_TYPE_MISMATCH!>topLevelIntProperty<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>topLevelImplicitIntProperty<!>)
}
fun testLocalProperties() {
val localIntProperty: Int = 1 + 1
val localLongProperty: Long = 1 + 1
val localImplicitIntProperty = 1 + 1
val localImplicitLongProperty = 3000000000 * 2
// OK
takeInt(localIntProperty)
takeLong(localLongProperty)
takeInt(localImplicitIntProperty)
takeLong(localImplicitLongProperty)
// no conversion for properties
takeLong(<!ARGUMENT_TYPE_MISMATCH!>localIntProperty<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>localImplicitIntProperty<!>)
}
@@ -0,0 +1,63 @@
FILE: intToLongConversion.fir.kt
public abstract interface A : R|kotlin/Any| {
}
public abstract interface B : R|kotlin/Any| {
}
public final fun takeByte(x: R|kotlin/Byte|): R|kotlin/Unit| {
}
public final fun takeInt(x: R|kotlin/Int|): R|kotlin/Unit| {
}
public final fun takeNullableInt(x: R|kotlin/Int|): R|kotlin/Unit| {
}
public final fun takeLong(x: R|kotlin/Long|): R|kotlin/Unit| {
}
public final fun takeNullableLong(x: R|kotlin/Long|): R|kotlin/Unit| {
}
public final fun takeOverloaded(x: R|kotlin/Int|): R|A| {
^takeOverloaded Null(null)!!
}
public final fun takeOverloaded(x: R|kotlin/Long|): R|B| {
^takeOverloaded Null(null)!!
}
public final fun takeA(a: R|A|): R|kotlin/Unit| {
}
public final fun takeB(b: R|B|): R|kotlin/Unit| {
}
public final fun test_constants(): R|kotlin/Unit| {
<Inapplicable(INAPPLICABLE): /takeByte>#(Int(1).R|kotlin/Int.plus|(Int(1)))
R|/takeInt|(Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.plus|(Int(1)))
R|/takeNullableInt|(Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.plus|(Int(1)))
R|/takeLong|(Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.toLong|())
R|/takeNullableLong|(Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.toLong|())
lval x: R|B| = R|/takeOverloaded|(Long(2147483648).R|kotlin/Long.minus|(Int(1)).R|kotlin/Long.plus|(Int(1)))
<Inapplicable(INAPPLICABLE): /takeA>#(R|<local>/x|)
R|/takeB|(R|<local>/x|)
}
public final val topLevelIntProperty: R|kotlin/Int| = Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.plus|(Int(1))
public get(): R|kotlin/Int|
public final val topLevelLongProperty: R|kotlin/Long| = Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.toLong|()
public get(): R|kotlin/Long|
public final val topLevelImplicitIntProperty: R|kotlin/Int| = Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.plus|(Int(1))
public get(): R|kotlin/Int|
public final val topLevelImplicitLongProperty: R|kotlin/Long| = Long(3000000000).R|kotlin/Long.times|(Int(2)).R|kotlin/Long.plus|(Int(1))
public get(): R|kotlin/Long|
public final fun testTopLevelProperties(): R|kotlin/Unit| {
R|/takeInt|(R|/topLevelIntProperty|)
R|/takeLong|(R|/topLevelLongProperty|)
R|/takeInt|(R|/topLevelImplicitIntProperty|)
R|/takeLong|(R|/topLevelImplicitLongProperty|)
<Inapplicable(INAPPLICABLE): /takeLong>#(R|/topLevelIntProperty|)
<Inapplicable(INAPPLICABLE): /takeLong>#(R|/topLevelImplicitIntProperty|)
}
public final fun testLocalProperties(): R|kotlin/Unit| {
lval localIntProperty: R|kotlin/Int| = Int(1).R|kotlin/Int.plus|(Int(1))
lval localLongProperty: R|kotlin/Long| = Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.toLong|()
lval localImplicitIntProperty: R|kotlin/Int| = Int(1).R|kotlin/Int.plus|(Int(1))
lval localImplicitLongProperty: R|kotlin/Long| = Long(3000000000).R|kotlin/Long.times|(Int(2))
R|/takeInt|(R|<local>/localIntProperty|)
R|/takeLong|(R|<local>/localLongProperty|)
R|/takeInt|(R|<local>/localImplicitIntProperty|)
R|/takeLong|(R|<local>/localImplicitLongProperty|)
<Inapplicable(INAPPLICABLE): /takeLong>#(R|<local>/localIntProperty|)
<Inapplicable(INAPPLICABLE): /takeLong>#(R|<local>/localImplicitIntProperty|)
}
@@ -0,0 +1,65 @@
// SKIP_TXT
// FIR_DUMP
// ISSUE: KT-38895, KT-50996, KT-51000
interface A
interface B
fun takeByte(x: Byte) {}
fun takeInt(x: Int) {}
fun takeNullableInt(x: Int) {}
fun takeLong(x: Long) {}
fun takeNullableLong(x: Long) {}
fun takeOverloaded(x: Int): A = null!! // (1)
fun takeOverloaded(x: Long): B = null!! // (2)
fun takeA(a: A) {}
fun takeB(b: B) {}
fun test_constants() {
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 + 1<!>) // error
takeInt(1 + 1 + 1) // OK
takeNullableInt(1 + 1 + 1) // OK
takeLong(1 + 1 + 1) // will be OK with implicit widening conversion
takeNullableLong(1 + 1 + 1) // will be OK with implicit widening conversion
val x = takeOverloaded(<!INTEGER_OVERFLOW!>2147483648 - 1 + 1<!>) // now resolved to (1), will be resolved to (2)
takeA(x)
takeB(<!TYPE_MISMATCH!>x<!>)
}
val topLevelIntProperty: Int = 1 + 1 + 1
val topLevelLongProperty: Long = 1 + 1 + 1
val topLevelImplicitIntProperty = 1 + 1 + 1
val topLevelImplicitLongProperty = 3000000000 * 2 + 1
fun testTopLevelProperties() {
// OK
takeInt(topLevelIntProperty)
takeLong(topLevelLongProperty)
takeInt(topLevelImplicitIntProperty)
takeLong(topLevelImplicitLongProperty)
// no conversion for properties
takeLong(<!TYPE_MISMATCH!>topLevelIntProperty<!>)
takeLong(<!TYPE_MISMATCH!>topLevelImplicitIntProperty<!>)
}
fun testLocalProperties() {
val localIntProperty: Int = 1 + 1
val localLongProperty: Long = 1 + 1
val localImplicitIntProperty = 1 + 1
val localImplicitLongProperty = 3000000000 * 2
// OK
takeInt(localIntProperty)
takeLong(localLongProperty)
takeInt(localImplicitIntProperty)
takeLong(localImplicitLongProperty)
// no conversion for properties
takeLong(<!TYPE_MISMATCH!>localIntProperty<!>)
takeLong(<!TYPE_MISMATCH!>localImplicitIntProperty<!>)
}
@@ -0,0 +1,24 @@
// FIR_IDENTICAL
// ISSUE: KT-51003
interface Assert<T>
fun <T> createAssert(value: T): Assert<T> = null!!
fun <A, B : Comparable<A>> Assert<B>.isGreaterThanOrEqualTo(other: A) {}
fun test_1(long: Long) {
// FE 1.0: OK
// FIR: ARGUMENT_TYPE_MISMATCH
createAssert(long).isGreaterThanOrEqualTo(10 * 10)
}
fun getNullableLong(): Long? = null
fun takeLong(x: Long) {}
fun test_2() {
val x = getNullableLong() ?: 10 * 60
takeLong(x)
// FE 1.0 infers type of `x` to `Long`
// FIR infers it to `Number` as `CST(Long, Int)`
}
@@ -0,0 +1,14 @@
package
public fun </*0*/ T> createAssert(/*0*/ value: T): Assert<T>
public fun getNullableLong(): kotlin.Long?
public fun takeLong(/*0*/ x: kotlin.Long): kotlin.Unit
public fun test_1(/*0*/ long: kotlin.Long): kotlin.Unit
public fun test_2(): kotlin.Unit
public fun </*0*/ A, /*1*/ B : kotlin.Comparable<A>> Assert<B>.isGreaterThanOrEqualTo(/*0*/ other: A): kotlin.Unit
public interface Assert</*0*/ T> {
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
}
@@ -1,22 +0,0 @@
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// ISSUE: Kt-47447, KT-47729
fun takeLong(value : Long) {}
fun takeInt(value : Int) {}
fun takeAny(value : Any) {}
fun takeLongX(value : Long?) {}
fun takeIntX(value : Int?) {}
fun takeAnyX(value : Any?) {}
fun <A> takeGeneric(value : A) {}
fun <A> takeGenericX(value : A?) {}
fun test_1() {
takeLong(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>) // ok
takeInt(1 + 1) // ok
takeAny(1 + 1) // ok
takeLongX(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>) // ok
takeIntX(1 + 1) // ok
takeAnyX(1 + 1) // ok
takeGeneric(1 + 1) // ok
takeGenericX(1 + 1) // ok
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition // LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// ISSUE: Kt-47447, KT-47729 // ISSUE: Kt-47447, KT-47729
@@ -1,20 +0,0 @@
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// ISSUE: Kt-47447, KT-47729
fun takeLong(x: Long) {}
object Foo {
var longProperty: Long = 0
infix fun infixOperator(x: Long) {}
}
// Should be ok in all places
fun test() {
takeLong(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>)
takeLong((<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>))
Foo.longProperty = 1 + 1
Foo.longProperty = (1 + 1)
Foo infixOperator <!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>
Foo infixOperator (<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition // LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// ISSUE: Kt-47447, KT-47729 // ISSUE: Kt-47447, KT-47729
@@ -1,5 +0,0 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
fun foo(ttlMillis: Long = <!TYPE_MISMATCH!>5 * 60 * 1000<!>) {}
const val cacheSize: Long = <!TYPE_MISMATCH!>4096 * 4<!>
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition // !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
fun foo(ttlMillis: Long = 5 * 60 * 1000) {} fun foo(ttlMillis: Long = 5 * 60 * 1000) {}
@@ -0,0 +1,6 @@
// LANGUAGE: +ApproximateIntegerLiteralTypesInReceiverPosition
fun foo(ttlMillis: Long = 5 * 60 * 1000) {}
const val cacheSize: Long = 4096 * 4
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// LANGUAGE: +ApproximateIntegerLiteralTypesInReceiverPosition // LANGUAGE: +ApproximateIntegerLiteralTypesInReceiverPosition
fun foo(ttlMillis: Long = <!TYPE_MISMATCH!>5 * 60 * 1000<!>) {} fun foo(ttlMillis: Long = <!TYPE_MISMATCH!>5 * 60 * 1000<!>) {}
@@ -7,21 +7,21 @@ abstract class C<L> {
} }
fun testLongDotCall(c1: C<Long>) { fun testLongDotCall(c1: C<Long>) {
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.plus(2)<!>) c1.takeT(1.plus(2))
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.minus(2)<!>) c1.takeT(1.minus(2))
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.times(2)<!>) c1.takeT(1.times(2))
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.div(2)<!>) c1.takeT(1.div(2))
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.rem(2)<!>) c1.takeT(1.rem(2))
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.inc()<!>) c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.inc()<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.dec()<!>) c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.dec()<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.unaryPlus()<!>) c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.unaryPlus()<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.unaryMinus()<!>) c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.unaryMinus()<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.shl(2)<!>) c1.takeT(1.shl(2))
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.shr(2)<!>) c1.takeT(1.shr(2))
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.ushr(2)<!>) c1.takeT(1.ushr(2))
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.and(2)<!>) c1.takeT(1.and(2))
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.or(2)<!>) c1.takeT(1.or(2))
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.xor(2)<!>) c1.takeT(1.xor(2))
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.inv()<!>) c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.inv()<!>)
} }
@@ -42,19 +42,19 @@ fun testByteDotCall(c3: C<Byte>) {
} }
fun testLongOperatorInfixCall(c4: C<Long>) { fun testLongOperatorInfixCall(c4: C<Long>) {
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 + 2<!>) c4.takeT(1 + 2)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 - 2<!>) c4.takeT(1 - 2)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 * 2<!>) c4.takeT(1 * 2)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 / 2<!>) c4.takeT(1 / 2)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 % 2<!>) c4.takeT(1 % 2)
c4.takeT(+1) c4.takeT(+1)
c4.takeT(-1) c4.takeT(-1)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 shl 2<!>) c4.takeT(1 shl 2)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 shr 2<!>) c4.takeT(1 shr 2)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 ushr 2<!>) c4.takeT(1 ushr 2)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 and 2<!>) c4.takeT(1 and 2)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 or 2<!>) c4.takeT(1 or 2)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 xor 2<!>) c4.takeT(1 xor 2)
} }
fun testShortOperatorInfixCall(c5: C<Short>) { fun testShortOperatorInfixCall(c5: C<Short>) {
@@ -41,24 +41,24 @@ fun testByteUnaryOperators() {
} }
fun testLongBinaryOperators() { fun testLongBinaryOperators() {
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 + 1<!>) takeLong(2 + 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 - 1<!>) takeLong(2 - 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 * 1<!>) takeLong(2 * 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 / 1<!>) takeLong(2 / 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 % 1<!>) takeLong(2 % 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.plus(1)<!>) takeLong(2.plus(1))
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.minus(1)<!>) takeLong(2.minus(1))
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.times(1)<!>) takeLong(2.times(1))
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.div(1)<!>) takeLong(2.div(1))
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.rem(1)<!>) takeLong(2.rem(1))
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 shl 1<!>) takeLong(2 shl 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 shr 1<!>) takeLong(2 shr 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 ushr 1<!>) takeLong(2 ushr 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 and 1<!>) takeLong(2 and 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 or 1<!>) takeLong(2 or 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 xor 1<!>) takeLong(2 xor 1)
// positive // positive
takeLong(2 * 100000000000) takeLong(2 * 100000000000)
@@ -42,24 +42,24 @@ fun testByteUnaryOperators() {
// all positive // all positive
fun testLongBinaryOperators() { fun testLongBinaryOperators() {
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 + 1<!>) takeLong(2 + 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 - 1<!>) takeLong(2 - 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 * 1<!>) takeLong(2 * 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 / 1<!>) takeLong(2 / 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 % 1<!>) takeLong(2 % 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.plus(1)<!>) takeLong(2.plus(1))
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.minus(1)<!>) takeLong(2.minus(1))
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.times(1)<!>) takeLong(2.times(1))
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.div(1)<!>) takeLong(2.div(1))
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.rem(1)<!>) takeLong(2.rem(1))
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 shl 1<!>) takeLong(2 shl 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 shr 1<!>) takeLong(2 shr 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 ushr 1<!>) takeLong(2 ushr 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 and 1<!>) takeLong(2 and 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 or 1<!>) takeLong(2 or 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 xor 1<!>) takeLong(2 xor 1)
takeLong(2 * 100000000000) takeLong(2 * 100000000000)
} }
@@ -8,7 +8,7 @@ fun fooShort(p: Short) = p
fun test() { fun test() {
fooInt(1 % 1) fooInt(1 % 1)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>) fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>) fooLong(1 % 1)
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>) fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>)
} }
@@ -13,8 +13,8 @@ val u3: UInt? = u1
val i0: Int = <!INITIALIZER_TYPE_MISMATCH!>1u<!> val i0: Int = <!INITIALIZER_TYPE_MISMATCH!>1u<!>
val m0 = <!UNRESOLVED_REFERENCE!>-<!>1u val m0 = <!NONE_APPLICABLE!>-<!>1u
val m1: UInt = <!UNRESOLVED_REFERENCE!>-<!>1u val m1: UInt = <!NONE_APPLICABLE!>-<!>1u
val h1 = 0xFFu val h1 = 0xFFu
val h2: UShort = 0xFFu val h2: UShort = 0xFFu
@@ -17483,6 +17483,28 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
} }
} }
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/integerLiterals")
@TestDataPath("$PROJECT_ROOT")
public class IntegerLiterals {
@Test
public void testAllFilesPresentInIntegerLiterals() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/integerLiterals"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("intToLongConversion.kt")
public void testIntToLongConversion() throws Exception {
runTest("compiler/testData/diagnostics/tests/integerLiterals/intToLongConversion.kt");
}
@Test
@TestMetadata("literalsInInference.kt")
public void testLiteralsInInference() throws Exception {
runTest("compiler/testData/diagnostics/tests/integerLiterals/literalsInInference.kt");
}
}
@Nested @Nested
@TestMetadata("compiler/testData/diagnostics/tests/j+k") @TestMetadata("compiler/testData/diagnostics/tests/j+k")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@@ -381,6 +381,8 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
fun TypeConstructorMarker.isClassTypeConstructor(): Boolean fun TypeConstructorMarker.isClassTypeConstructor(): Boolean
fun TypeConstructorMarker.isInterface(): Boolean fun TypeConstructorMarker.isInterface(): Boolean
fun TypeConstructorMarker.isIntegerLiteralTypeConstructor(): Boolean fun TypeConstructorMarker.isIntegerLiteralTypeConstructor(): Boolean
fun TypeConstructorMarker.isIntegerLiteralConstantTypeConstructor(): Boolean
fun TypeConstructorMarker.isIntegerConstantOperatorTypeConstructor(): Boolean
fun TypeConstructorMarker.isLocalType(): Boolean fun TypeConstructorMarker.isLocalType(): Boolean
fun TypeConstructorMarker.isAnonymous(): Boolean fun TypeConstructorMarker.isAnonymous(): Boolean
fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker? fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker?
@@ -45,6 +45,14 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
return this is IntegerLiteralTypeConstructor return this is IntegerLiteralTypeConstructor
} }
override fun TypeConstructorMarker.isIntegerLiteralConstantTypeConstructor(): Boolean {
return isIntegerLiteralTypeConstructor()
}
override fun TypeConstructorMarker.isIntegerConstantOperatorTypeConstructor(): Boolean {
return false
}
override fun TypeConstructorMarker.isLocalType(): Boolean { override fun TypeConstructorMarker.isLocalType(): Boolean {
require(this is TypeConstructor, this::errorMessage) require(this is TypeConstructor, this::errorMessage)
return declarationDescriptor?.classId?.isLocal == true return declarationDescriptor?.classId?.isLocal == true