[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 errorType: Boolean get() = true
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 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.FirDeclaration
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.originalIfFakeOverride
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData
import org.jetbrains.kotlin.fir.scopes.impl.originalForWrappedIntegerOperator
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
internal interface KtFirSymbol<out S : FirBasedSymbol<*>> : KtSymbol, ValidityTokenOwner {
@@ -64,6 +66,12 @@ internal tailrec fun FirDeclaration.ktSymbolOrigin(): KtSymbolOrigin = when (ori
importedFromObjectData.original.ktSymbolOrigin()
}
FirDeclarationOrigin.WrappedIntegerOperator -> {
val original = (this as FirSimpleFunction).originalForWrappedIntegerOperator?.fir
?: error("Declaration has WrappedIntegerOperator origin, but no originalForWrappedIntegerOperator present")
original.ktSymbolOrigin()
}
else -> {
val overridden = (this as? FirCallableDeclaration)?.originalIfFakeOverride()
?: throw InvalidFirDeclarationOriginForSymbol(this)
@@ -26,7 +26,7 @@ internal object PublicTypeApproximator {
override val allFlexible: Boolean get() = false
override val errorType: Boolean get() = true
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 anonymous: Boolean get() = true
}
@@ -1,5 +1,5 @@
KT element: KtBinaryExpression
FIR element: FirFunctionCallImpl
FIR element: FirIntegerLiteralOperatorCallImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
@@ -1,5 +1,5 @@
KT element: KtParenthesizedExpression
FIR element: FirFunctionCallImpl
FIR element: FirIntegerLiteralOperatorCallImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
@@ -1,6 +1,6 @@
KT element: KtBlockStringTemplateEntry
FIR element: FirFunctionCallImpl
FIR element: FirIntegerLiteralOperatorCallImpl
FIR source kind: KtRealSourceElementKind
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
@TestMetadata("compiler/testData/diagnostics/tests/j+k")
@TestDataPath("$PROJECT_ROOT")
@@ -1,6 +1,6 @@
FILE: lambda.kt
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| {
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
@TestMetadata("compiler/testData/diagnostics/tests/j+k")
@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
@TestMetadata("compiler/testData/diagnostics/tests/j+k")
@TestDataPath("$PROJECT_ROOT")
@@ -31,6 +31,7 @@ fun main(args: Array<String>) {
alias<FirQualifiedAccessExpression>("QualifiedAccessExpressionChecker")
alias<FirCall>("CallChecker")
alias<FirFunctionCall>("FunctionCallChecker")
alias<FirIntegerLiteralOperatorCall>("IntegerLiteralOperatorCallChecker")
alias<FirVariableAssignment>("VariableAssignmentChecker")
alias<FirTryExpression>("TryExpressionChecker")
alias<FirWhenExpression>("WhenExpressionChecker")
@@ -23,6 +23,8 @@ class ComposedExpressionCheckers : ExpressionCheckers() {
get() = _callCheckers
override val functionCallCheckers: Set<FirFunctionCallChecker>
get() = _functionCallCheckers
override val integerLiteralOperatorCallCheckers: Set<FirIntegerLiteralOperatorCallChecker>
get() = _integerLiteralOperatorCallCheckers
override val variableAssignmentCheckers: Set<FirVariableAssignmentChecker>
get() = _variableAssignmentCheckers
override val tryExpressionCheckers: Set<FirTryExpressionChecker>
@@ -79,6 +81,7 @@ class ComposedExpressionCheckers : ExpressionCheckers() {
private val _qualifiedAccessExpressionCheckers: MutableSet<FirQualifiedAccessExpressionChecker> = mutableSetOf()
private val _callCheckers: MutableSet<FirCallChecker> = mutableSetOf()
private val _functionCallCheckers: MutableSet<FirFunctionCallChecker> = mutableSetOf()
private val _integerLiteralOperatorCallCheckers: MutableSet<FirIntegerLiteralOperatorCallChecker> = mutableSetOf()
private val _variableAssignmentCheckers: MutableSet<FirVariableAssignmentChecker> = mutableSetOf()
private val _tryExpressionCheckers: MutableSet<FirTryExpressionChecker> = mutableSetOf()
private val _whenExpressionCheckers: MutableSet<FirWhenExpressionChecker> = mutableSetOf()
@@ -112,6 +115,7 @@ class ComposedExpressionCheckers : ExpressionCheckers() {
_qualifiedAccessExpressionCheckers += checkers.qualifiedAccessExpressionCheckers
_callCheckers += checkers.callCheckers
_functionCallCheckers += checkers.functionCallCheckers
_integerLiteralOperatorCallCheckers += checkers.integerLiteralOperatorCallCheckers
_variableAssignmentCheckers += checkers.variableAssignmentCheckers
_tryExpressionCheckers += checkers.tryExpressionCheckers
_whenExpressionCheckers += checkers.whenExpressionCheckers
@@ -22,6 +22,7 @@ abstract class ExpressionCheckers {
open val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker> = emptySet()
open val callCheckers: Set<FirCallChecker> = emptySet()
open val functionCallCheckers: Set<FirFunctionCallChecker> = emptySet()
open val integerLiteralOperatorCallCheckers: Set<FirIntegerLiteralOperatorCallChecker> = emptySet()
open val variableAssignmentCheckers: Set<FirVariableAssignmentChecker> = emptySet()
open val tryExpressionCheckers: Set<FirTryExpressionChecker> = 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 allCallCheckers: Set<FirCallChecker> by lazy { callCheckers + basicExpressionCheckers }
@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 allTryExpressionCheckers: Set<FirTryExpressionChecker> by lazy { tryExpressionCheckers + 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.FirFunctionCall
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.FirLoopJump
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
@@ -46,6 +47,7 @@ typealias FirQualifiedAccessChecker = FirExpressionChecker<FirQualifiedAccess>
typealias FirQualifiedAccessExpressionChecker = FirExpressionChecker<FirQualifiedAccessExpression>
typealias FirCallChecker = FirExpressionChecker<FirCall>
typealias FirFunctionCallChecker = FirExpressionChecker<FirFunctionCall>
typealias FirIntegerLiteralOperatorCallChecker = FirExpressionChecker<FirIntegerLiteralOperatorCall>
typealias FirVariableAssignmentChecker = FirExpressionChecker<FirVariableAssignment>
typealias FirTryExpressionChecker = FirExpressionChecker<FirTryExpression>
typealias FirWhenExpressionChecker = FirExpressionChecker<FirWhenExpression>
@@ -48,6 +48,10 @@ class ExpressionCheckersDiagnosticComponent(
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) {
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.isString: Boolean get() = isBuiltinType(StandardClassIds.String, 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.isPrimitive: Boolean get() = isPrimitiveOrNullablePrimitive && nullability == ConeNullability.NOT_NULL
val ConeKotlinType.isArrayType: Boolean
@@ -78,7 +78,8 @@ class Fir2IrTypeConverter(
object : TypeApproximatorConfiguration.AllFlexibleSameValue() {
override val allFlexible: 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
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.calls.jvm
import org.jetbrains.kotlin.fir.NoMutableState
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
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.inference.InferenceComponents
import org.jetbrains.kotlin.fir.types.typeContext
@@ -24,7 +25,8 @@ object JvmCallConflictResolverFactory : ConeCallConflictResolverFactory() {
return ConeCompositeConflictResolver(
ConeOverloadConflictResolver(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.FirStandardOverrideChecker
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.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
@@ -90,7 +91,8 @@ private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: Scope
this
)
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
}
}
@@ -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
}
override fun TypeConstructorMarker.isIntegerLiteralConstantTypeConstructor(): Boolean {
return this is ConeIntegerLiteralConstantType
}
override fun TypeConstructorMarker.isIntegerConstantOperatorTypeConstructor(): Boolean {
return this is ConeIntegerConstantOperatorType
}
override fun TypeConstructorMarker.isLocalType(): Boolean {
if (this !is ConeClassLikeLookupTag) return false
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.providers.FirSymbolProvider
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.scopes.FirScope
import org.jetbrains.kotlin.fir.types.FirTypeRef
@@ -43,6 +44,7 @@ abstract class BodyResolveComponents : SessionHolder {
abstract val syntheticCallGenerator: FirSyntheticCallGenerator
abstract val dataFlowAnalyzer: FirDataFlowAnalyzer<*>
abstract val outerClassManager: FirOuterClassManager
abstract val integerLiteralAndOperatorApproximationTransformer: IntegerLiteralAndOperatorApproximationTransformer
}
// --------------------------------------- Utils ---------------------------------------
@@ -47,8 +47,11 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
import org.jetbrains.kotlin.types.ConstantValueKind
import org.jetbrains.kotlin.types.SmartcastStability
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
fun List<FirQualifierPart>.toTypeProjections(): Array<ConeTypeProjection> =
asReversed().flatMap { it.typeArgumentList.typeArguments.map { typeArgument -> typeArgument.toConeTypeProjection() } }.toTypedArray()
@@ -485,6 +488,7 @@ fun FirFunction.getAsForbiddenNamedArgumentsTarget(session: FirSession): Forbidd
}
FirDeclarationOrigin.Synthetic -> null
FirDeclarationOrigin.RenamedForOverride -> null
FirDeclarationOrigin.WrappedIntegerOperator -> null
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.constructorProto
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.expressions.*
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.resolve.isIntegerLiteralOrOperatorCall
import org.jetbrains.kotlin.fir.returnExpressions
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.impl.*
import org.jetbrains.kotlin.fir.types.classId
@@ -51,6 +53,9 @@ class CandidateFactory private constructor(
builtInExtensionFunctionReceiverValue: ReceiverValue? = null,
objectsByName: Boolean = false
): Candidate {
@Suppress("NAME_SHADOWING")
val symbol = symbol.unwrapIntegerOperatorSymbolIfNeeded(callInfo)
val result = Candidate(
symbol, dispatchReceiverValue, extensionReceiverValue,
explicitReceiverKind, context.inferenceComponents.constraintSystemFactory, baseSystem,
@@ -87,6 +92,16 @@ class CandidateFactory private constructor(
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 {
val expressionReceiverValue = this as? ExpressionReceiverValue ?: 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
// 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
csBuilder.isProperType(currentReturnType) -> ConstraintSystemCompletionMode.FULL
@@ -123,9 +123,11 @@ class FirCallCompleter(
.buildAbstractResultingSubstitutor(session.typeContext) as ConeSubstitutor
val completedCall = call.transformSingle(
FirCallCompletionResultsWriterTransformer(
session, finalSubstitutor, components.returnTypeCalculator,
session, finalSubstitutor,
components.returnTypeCalculator,
session.typeApproximator,
components.dataFlowAnalyzer,
components.integerLiteralAndOperatorApproximationTransformer
),
null
)
@@ -236,6 +238,7 @@ class FirCallCompleter(
session, substitutor, components.returnTypeCalculator,
session.typeApproximator,
components.dataFlowAnalyzer,
components.integerLiteralAndOperatorApproximationTransformer,
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.resultType
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.impl.FirConstructorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
@@ -68,6 +70,7 @@ class FirCallCompletionResultsWriterTransformer(
private val typeCalculator: ReturnTypeCalculator,
private val typeApproximator: ConeTypeApproximator,
private val dataFlowAnalyzer: FirDataFlowAnalyzer<*>,
private val integerOperatorApproximator: IntegerLiteralAndOperatorApproximationTransformer,
private val mode: Mode = Mode.Normal
) : 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")
val result = qualifiedAccessExpression
.transformCalleeReference(
StoreCalleeReference,
calleeReference.toResolvedReference(),
)
.transformDispatchReceiver(StoreReceiver, subCandidate.dispatchReceiverExpression())
.transformExtensionReceiver(StoreReceiver, subCandidate.extensionReceiverExpression()) as T
.transformDispatchReceiver(StoreReceiver, dispatchReceiver)
.transformExtensionReceiver(StoreReceiver, extensionReceiver) as T
if (result is FirPropertyAccessExpressionImpl && calleeReference.candidate.currentApplicability == CandidateApplicability.PROPERTY_AS_OPERATOR) {
result.nonFatalDiagnostics.add(ConePropertyAsOperator(calleeReference.candidate.symbol as FirPropertySymbol))
}
@@ -199,8 +211,6 @@ class FirCallCompletionResultsWriterTransformer(
val subCandidate = calleeReference.candidate
val resultType: FirTypeRef
resultType = typeRef.substituteTypeRef(subCandidate)
val expectedArgumentsTypeMapping = runIf(!calleeReference.isError) { subCandidate.createArgumentsMapping() }
result.argumentList.transformArguments(this, expectedArgumentsTypeMapping)
if (calleeReference.isError) {
subCandidate.argumentMapping?.let {
result.replaceArgumentList(buildArgumentListForErrorCall(result.argumentList, it))
@@ -225,6 +235,8 @@ class FirCallCompletionResultsWriterTransformer(
result.replaceArgumentList(newArgumentList)
}
}
val expectedArgumentsTypeMapping = runIf(!calleeReference.isError) { subCandidate.createArgumentsMapping() }
result.argumentList.transformArguments(this, expectedArgumentsTypeMapping)
result.replaceTypeRef(resultType)
session.lookupTracker?.recordTypeResolveAsLookup(resultType, functionCall.source, null)
@@ -445,12 +457,18 @@ class FirCallCompletionResultsWriterTransformer(
Pair(it.atom, finalSubstitutor.substituteOrSelf(substitutor.substituteOrSelf(it.returnType)))
}
val isIntegerOperator = symbol.isWrappedIntegerOperator()
val arguments = argumentMapping?.map { (argument, valueParameter) ->
val expectedType = if (valueParameter.isVararg) {
valueParameter.returnTypeRef.substitute(this).varargElementType()
} else {
valueParameter.returnTypeRef.substitute(this)
val expectedType = when {
isIntegerOperator -> ConeIntegerConstantOperatorTypeImpl(
isUnsigned = symbol.isWrappedIntegerOperatorForUnsignedType(),
ConeNullability.NOT_NULL
)
valueParameter.isVararg -> valueParameter.returnTypeRef.substitute(this).varargElementType()
else -> valueParameter.returnTypeRef.substitute(this)
}
val unwrappedArgument: FirElement = when (val unwrappedArgument = argument.unwrapArgument()) {
is FirAnonymousFunctionExpression -> unwrappedArgument.anonymousFunction
else -> unwrappedArgument
@@ -781,7 +799,23 @@ class FirCallCompletionResultsWriterTransformer(
data: ExpectedArgumentType?,
): FirStatement {
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 {
@@ -800,6 +834,15 @@ class FirCallCompletionResultsWriterTransformer(
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 {
val errorDiagnostic = when {
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.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.resolve.transformers.FirAbstractPhaseTransformer
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.resolve.transformers.*
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
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 outerClassManager: FirOuterClassManager = FirOuterClassManager(session, context.outerLocalClassForNested)
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 {
dataFlowAnalyzer.enterDelegateExpression()
// First, resolve delegate expression in dependent context
val delegateExpression =
wrappedDelegateExpression.expression.transformSingle(transformer, ResolutionMode.ContextDependent)
val delegateExpression = 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
if (delegateExpression is FirQualifiedAccess) {
@@ -355,7 +355,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
// Select delegate expression otherwise
return delegateExpression
.approximateIfIsIntegerConst()
}
private fun transformLocalVariable(variable: FirProperty): FirProperty {
@@ -826,6 +825,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
components.returnTypeCalculator,
session.typeApproximator,
dataFlowAnalyzer,
components.integerLiteralAndOperatorApproximationTransformer
)
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.resolve.*
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.diagnostics.*
import org.jetbrains.kotlin.fir.resolve.inference.FirStubInferenceSession
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer
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.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
@@ -373,14 +376,58 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
} catch (e: Throwable) {
throw RuntimeException("While resolving call ${functionCall.render()}", e)
}
dataFlowAnalyzer.exitFunctionCall(completeInference, callCompleted)
val result = completeInference.transformToIntegerOperatorCallOrApproximateItIfNeeded(data)
dataFlowAnalyzer.exitFunctionCall(result, callCompleted)
if (callCompleted) {
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 {
@@ -917,6 +964,10 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
constExpression.replaceKind(expressionType.toConstKind() as ConstantValueKind<T>)
expressionType
}
data is ResolutionMode.ReceiverResolution -> {
require(expressionType is ConeIntegerLiteralConstantTypeImpl)
ConeIntegerConstantOperatorTypeImpl(expressionType.isUnsigned, ConeNullability.NOT_NULL)
}
expectedTypeRef != null -> {
require(expressionType is ConeIntegerLiteralConstantTypeImpl)
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.FirPropertyAccessExpression
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.FirDelegatedConstructorCall
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 visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall, data: D): R = visitFunctionCall(integerLiteralOperatorCall, data)
override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: D): R = visitFunctionCall(implicitInvokeCall, 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.FirPropertyAccessExpression
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.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirComponentCall
@@ -213,6 +214,8 @@ abstract class FirDefaultVisitorVoid : FirVisitorVoid() {
override fun visitPropertyAccessExpression(propertyAccessExpression: FirPropertyAccessExpression) = visitQualifiedAccessExpression(propertyAccessExpression)
override fun visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall) = visitFunctionCall(integerLiteralOperatorCall)
override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall) = visitFunctionCall(implicitInvokeCall)
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.FirPropertyAccessExpression
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.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirComponentCall
@@ -492,6 +493,10 @@ abstract class FirTransformer<in D> : FirVisitor<FirElement, D>() {
return transformElement(functionCall, data)
}
open fun transformIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall, data: D): FirStatement {
return transformElement(integerLiteralOperatorCall, data)
}
open fun transformImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: D): FirStatement {
return transformElement(implicitInvokeCall, data)
}
@@ -1040,6 +1045,10 @@ abstract class FirTransformer<in D> : FirVisitor<FirElement, D>() {
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 {
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.FirPropertyAccessExpression
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.FirDelegatedConstructorCall
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 visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall, data: D): R = visitElement(integerLiteralOperatorCall, data)
open fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: D): R = visitElement(implicitInvokeCall, 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.FirPropertyAccessExpression
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.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirComponentCall
@@ -491,6 +492,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitElement(functionCall)
}
open fun visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall) {
visitElement(integerLiteralOperatorCall)
}
open fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall) {
visitElement(implicitInvokeCall)
}
@@ -1039,6 +1044,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitFunctionCall(functionCall)
}
final override fun visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall, data: Nothing?) {
visitIntegerLiteralOperatorCall(integerLiteralOperatorCall)
}
final override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: Nothing?) {
visitImplicitInvokeCall(implicitInvokeCall)
}
@@ -1321,6 +1321,10 @@ open class FirRenderer(builder: StringBuilder, protected val mode: RenderMode =
visitCall(functionCall)
}
override fun visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall) {
visitFunctionCall(integerLiteralOperatorCall)
}
override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall) {
visitFunctionCall(implicitInvokeCall)
}
@@ -65,6 +65,10 @@ class BuiltinTypes {
val longType: FirImplicitBuiltinTypeRef = FirImplicitLongTypeRef(null)
val doubleType: FirImplicitBuiltinTypeRef = FirImplicitDoubleTypeRef(null)
val floatType: FirImplicitBuiltinTypeRef = FirImplicitFloatTypeRef(null)
val uIntType: FirImplicitUIntTypeRef = FirImplicitUIntTypeRef(null)
val uLongType: FirImplicitULongTypeRef = FirImplicitULongTypeRef(null)
val nothingType: FirImplicitBuiltinTypeRef = FirImplicitNothingTypeRef(null)
val nullableNothingType: FirImplicitBuiltinTypeRef = FirImplicitNullableNothingTypeRef(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 Delegated : FirDeclarationOrigin()
object RenamedForOverride : FirDeclarationOrigin()
object WrappedIntegerOperator : FirDeclarationOrigin()
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.createSupertypeList
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.name.ClassId
import org.jetbrains.kotlin.types.AbstractTypeChecker
@@ -68,7 +68,7 @@ class ConeIntegerLiteralConstantTypeImpl(
addSignedPossibleTypes()
}
return if (possibleTypes.size == 1) {
possibleTypes.single().withNullability(nullability).also {
possibleTypes.single().withNullabilityAndAttributes(nullability, ConeAttributes.Empty).also {
if (AbstractTypeChecker.RUN_SLOW_ASSERTIONS) {
assert(it.isLong() || it.isULong())
}
@@ -149,12 +149,12 @@ private object ConeIntegerLiteralTypeExtensions {
fun ConeIntegerLiteralType.getApproximatedTypeImpl(expectedType: ConeKotlinType?): ConeClassLikeType {
val expectedTypeForApproximation = (expectedType?.lowerBoundIfFlexible() as? ConeClassLikeType)
?.withNullability(ConeNullability.NOT_NULL)
?.withNullabilityAndAttributes(ConeNullability.NOT_NULL, ConeAttributes.Empty)
val approximatedType = when (expectedTypeForApproximation) {
null, !in possibleTypes -> possibleTypes.first()
else -> expectedTypeForApproximation
}
return approximatedType.withNullability(nullability)
return approximatedType.withNullabilityAndAttributes(nullability, attributes)
}
@@ -218,12 +218,12 @@ private object ConeIntegerLiteralTypeExtensions {
return this
}
fun ConeClassLikeType.withNullability(nullability: ConeNullability): ConeClassLikeType {
if (nullability == this.nullability) return this
fun ConeClassLikeType.withNullabilityAndAttributes(nullability: ConeNullability, attributes: ConeAttributes): ConeClassLikeType {
if (nullability == this.nullability && attributes == this.attributes) return this
return when (this) {
is ConeErrorType -> this
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, typeArguments, nullability.isNullable)
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, typeArguments, nullability.isNullable, attributes)
else -> error("sealed")
}
}
@@ -93,6 +93,14 @@ class FirImplicitFloatTypeRef(
source: KtSourceElement?
) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Float)
class FirImplicitUIntTypeRef(
source: KtSourceElement?
) : FirImplicitBuiltinTypeRef(source, StandardClassIds.UInt)
class FirImplicitULongTypeRef(
source: KtSourceElement?
) : FirImplicitBuiltinTypeRef(source, StandardClassIds.ULong)
class FirImplicitNothingTypeRef(
source: KtSourceElement?
) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Nothing)
@@ -177,6 +185,8 @@ fun FirImplicitBuiltinTypeRef.withFakeSource(kind: KtFakeSourceElementKind): Fir
is FirImplicitLongTypeRef -> FirImplicitLongTypeRef(newSource)
is FirImplicitDoubleTypeRef -> FirImplicitDoubleTypeRef(newSource)
is FirImplicitFloatTypeRef -> FirImplicitFloatTypeRef(newSource)
is FirImplicitUIntTypeRef -> FirImplicitUIntTypeRef(newSource)
is FirImplicitULongTypeRef -> FirImplicitULongTypeRef(newSource)
is FirImplicitNothingTypeRef -> FirImplicitNothingTypeRef(newSource)
is FirImplicitNullableNothingTypeRef -> FirImplicitNullableNothingTypeRef(newSource)
is FirImplicitCharTypeRef -> FirImplicitCharTypeRef(newSource)
@@ -192,6 +192,7 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
value = "FirFunctionCallOrigin.Regular"
}
}
builder(integerLiteralOperatorCall, init = configurationForFunctionCallBuilder)
builder(implicitInvokeCall, init = configurationForFunctionCallBuilder)
builder(getClassCall) {
@@ -111,6 +111,7 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
val qualifiedAccessExpression by element(Expression, expression, qualifiedAccess)
val propertyAccessExpression by element(Expression, qualifiedAccessExpression)
val functionCall by element(Expression, qualifiedAccessExpression, call)
val integerLiteralOperatorCall by element(Expression, functionCall)
val implicitInvokeCall by element(Expression, functionCall)
val delegatedConstructorCall by element(Expression, resolvable, call)
val componentCall by element(Expression, functionCall)
@@ -560,6 +560,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
"FirSafeCallExpressionImpl",
"FirCheckedSafeCallSubjectImpl",
"FirArrayOfCallImpl",
"FirIntegerLiteralOperatorCallImpl"
)
configureFieldInAllImplementations(
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
// e.g., `(x: Int) -> Unit` becomes `Function1<@ParameterName("x") Int, Unit>`
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 {
@@ -31,7 +31,7 @@ open class TypeTranslatorImpl(
object : TypeApproximatorConfiguration.AllFlexibleSameValue() {
override val allFlexible: 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
}
@@ -306,7 +306,9 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
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 {
if (this !is IrClassSymbol) return false
@@ -113,4 +113,4 @@ class IrCapturedType(
override fun hashCode(): Int {
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.resolve.calls.NewCommonSuperTypeCalculator.commonSuperType
import org.jetbrains.kotlin.types.model.*
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import java.util.concurrent.ConcurrentHashMap
abstract class AbstractTypeApproximator(
@@ -340,11 +341,16 @@ abstract class AbstractTypeApproximator(
return if (conf.typeVariable(typeConstructor)) null else type.defaultResult(toSuper)
}
if (typeConstructor.isIntegerLiteralTypeConstructor()) {
return if (conf.integerLiteralType)
if (typeConstructor.isIntegerLiteralConstantTypeConstructor()) {
return runIf(conf.integerLiteralConstantType) {
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
@@ -19,7 +19,8 @@ open class TypeApproximatorConfiguration {
open val dynamic: Boolean get() = false // DynamicType
open val rawType: Boolean get() = false // RawTypeImpl
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 intersection: IntersectionStrategy = IntersectionStrategy.TO_COMMON_SUPERTYPE
open val intersectionTypesInContravariantPositions = false
@@ -47,7 +48,7 @@ open class TypeApproximatorConfiguration {
override val allFlexible: Boolean get() = true
override val intersection: IntersectionStrategy get() = IntersectionStrategy.ALLOWED
override val errorType: Boolean get() = true
override val integerLiteralType: Boolean get() = true
override val integerLiteralConstantType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true
}
@@ -55,7 +56,7 @@ open class TypeApproximatorConfiguration {
override val allFlexible: Boolean get() = true
override val errorType: Boolean get() = true
override val definitelyNotNullType: Boolean get() = false
override val integerLiteralType: Boolean get() = true
override val integerLiteralConstantType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true
}
@@ -75,23 +76,25 @@ open class TypeApproximatorConfiguration {
object IncorporationConfiguration : AbstractCapturedTypesApproximation(CaptureStatus.FOR_INCORPORATION)
object SubtypeCapturedTypesApproximation : AbstractCapturedTypesApproximation(CaptureStatus.FOR_SUBTYPING)
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
}
object FinalApproximationAfterResolutionAndInference :
AbstractCapturedTypesApproximation(CaptureStatus.FROM_EXPRESSION) {
override val integerLiteralType: Boolean get() = true
override val integerLiteralConstantType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true
}
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
}
object IntegerLiteralsTypesApproximation : AllFlexibleSameValue() {
override val integerLiteralType: Boolean get() = true
override val integerLiteralConstantType: Boolean get() = true
override val allFlexible: Boolean get() = true
override val intersection: IntersectionStrategy get() = IntersectionStrategy.ALLOWED
override val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean get() = { true }
@@ -1,6 +1,4 @@
// 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 {
val a: Long = 2147483647 + 1
+2 -1
View File
@@ -1,5 +1,6 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_FIR_DIAGNOSTICS
// IGNORE_BACKEND_FIR: JVM_IR
// FIR status: don't support legacy feature
// TARGET_BACKEND: JVM
// WITH_STDLIB
-1
View File
@@ -1,5 +1,4 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_FIR_DIAGNOSTICS
// TARGET_BACKEND: JVM
// WITH_STDLIB
+1 -1
View File
@@ -1,5 +1,5 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_FIR_DIAGNOSTICS
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_STDLIB
+1 -1
View File
@@ -1,5 +1,5 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_FIR_DIAGNOSTICS
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_STDLIB
+1 -1
View File
@@ -1,5 +1,5 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_FIR_DIAGNOSTICS
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_STDLIB
+1 -1
View File
@@ -1,5 +1,5 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_FIR_DIAGNOSTICS
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_STDLIB
+1 -1
View File
@@ -1,5 +1,5 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_FIR_DIAGNOSTICS
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_STDLIB
@@ -8,6 +8,6 @@ annotation class Ann(
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())
@@ -7,6 +7,6 @@ annotation class Ann(
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())
@@ -8,6 +8,6 @@ annotation class Ann(
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())
@@ -8,6 +8,6 @@ annotation class Ann(
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())
@@ -8,6 +8,6 @@ annotation class Ann(
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())
@@ -8,6 +8,6 @@ annotation class Ann(
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())
@@ -17,7 +17,7 @@ fun test() {
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 - 1.toLong()<!>)
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.toByte()<!>)
fooLong(1 - 1.toLong())
@@ -1,5 +1,5 @@
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 p4: Short = <!TYPE_MISMATCH!>1 - 1<!>
@@ -7,21 +7,21 @@ fun fooShort(p: Short) = p
fun test() {
fooInt(1 + 1)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>)
fooLong(1 + 1)
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>)
fooInt(1 * 1)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 * 1<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 * 1<!>)
fooLong(1 * 1)
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 * 1<!>)
fooInt(1 / 1)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 / 1<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 / 1<!>)
fooLong(1 / 1)
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 / 1<!>)
fooInt(1 % 1)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>)
fooLong(1 % 1)
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>)
}
@@ -7,21 +7,21 @@ fun fooShort(p: Short) = p
fun test() {
fooInt(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)<!>)
fooInt(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)<!>)
fooInt(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)<!>)
fooInt(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)<!>)
}
@@ -7,21 +7,21 @@ fun fooShort(p: Short) = p
fun test() {
fooInt(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<!>)
fooInt(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<!>)
fooInt(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<!>)
fooInt(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<!>)
}
@@ -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
val p1: Byte = <!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
// 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
// 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
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
fun foo(ttlMillis: Long = <!TYPE_MISMATCH!>5 * 60 * 1000<!>) {}
@@ -7,21 +7,21 @@ abstract class C<L> {
}
fun testLongDotCall(c1: C<Long>) {
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.plus(2)<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.minus(2)<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.times(2)<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.div(2)<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.rem(2)<!>)
c1.takeT(1.plus(2))
c1.takeT(1.minus(2))
c1.takeT(1.times(2))
c1.takeT(1.div(2))
c1.takeT(1.rem(2))
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.inc()<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.dec()<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.unaryPlus()<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.unaryMinus()<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.shl(2)<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.shr(2)<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.ushr(2)<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.and(2)<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.or(2)<!>)
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.xor(2)<!>)
c1.takeT(1.shl(2))
c1.takeT(1.shr(2))
c1.takeT(1.ushr(2))
c1.takeT(1.and(2))
c1.takeT(1.or(2))
c1.takeT(1.xor(2))
c1.takeT(<!ARGUMENT_TYPE_MISMATCH!>1.inv()<!>)
}
@@ -42,19 +42,19 @@ fun testByteDotCall(c3: C<Byte>) {
}
fun testLongOperatorInfixCall(c4: C<Long>) {
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 + 2<!>)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 - 2<!>)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 * 2<!>)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 / 2<!>)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 % 2<!>)
c4.takeT(1 + 2)
c4.takeT(1 - 2)
c4.takeT(1 * 2)
c4.takeT(1 / 2)
c4.takeT(1 % 2)
c4.takeT(+1)
c4.takeT(-1)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 shl 2<!>)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 shr 2<!>)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 ushr 2<!>)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 and 2<!>)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 or 2<!>)
c4.takeT(<!ARGUMENT_TYPE_MISMATCH!>1 xor 2<!>)
c4.takeT(1 shl 2)
c4.takeT(1 shr 2)
c4.takeT(1 ushr 2)
c4.takeT(1 and 2)
c4.takeT(1 or 2)
c4.takeT(1 xor 2)
}
fun testShortOperatorInfixCall(c5: C<Short>) {
@@ -41,24 +41,24 @@ fun testByteUnaryOperators() {
}
fun testLongBinaryOperators() {
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 + 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 - 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 * 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 / 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 % 1<!>)
takeLong(2 + 1)
takeLong(2 - 1)
takeLong(2 * 1)
takeLong(2 / 1)
takeLong(2 % 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.plus(1)<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.minus(1)<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.times(1)<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.div(1)<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.rem(1)<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 shl 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 shr 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 ushr 1<!>)
takeLong(2.plus(1))
takeLong(2.minus(1))
takeLong(2.times(1))
takeLong(2.div(1))
takeLong(2.rem(1))
takeLong(2 shl 1)
takeLong(2 shr 1)
takeLong(2 ushr 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 and 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 or 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 xor 1<!>)
takeLong(2 and 1)
takeLong(2 or 1)
takeLong(2 xor 1)
// positive
takeLong(2 * 100000000000)
@@ -42,24 +42,24 @@ fun testByteUnaryOperators() {
// all positive
fun testLongBinaryOperators() {
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 + 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 - 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 * 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 / 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 % 1<!>)
takeLong(2 + 1)
takeLong(2 - 1)
takeLong(2 * 1)
takeLong(2 / 1)
takeLong(2 % 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.plus(1)<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.minus(1)<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.times(1)<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.div(1)<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.rem(1)<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 shl 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 shr 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 ushr 1<!>)
takeLong(2.plus(1))
takeLong(2.minus(1))
takeLong(2.times(1))
takeLong(2.div(1))
takeLong(2.rem(1))
takeLong(2 shl 1)
takeLong(2 shr 1)
takeLong(2 ushr 1)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 and 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 or 1<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 xor 1<!>)
takeLong(2 and 1)
takeLong(2 or 1)
takeLong(2 xor 1)
takeLong(2 * 100000000000)
}
@@ -8,7 +8,7 @@ fun fooShort(p: Short) = p
fun test() {
fooInt(1 % 1)
fooByte(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>)
fooLong(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>)
fooLong(1 % 1)
fooShort(<!ARGUMENT_TYPE_MISMATCH!>1 % 1<!>)
}
@@ -13,8 +13,8 @@ val u3: UInt? = u1
val i0: Int = <!INITIALIZER_TYPE_MISMATCH!>1u<!>
val m0 = <!UNRESOLVED_REFERENCE!>-<!>1u
val m1: UInt = <!UNRESOLVED_REFERENCE!>-<!>1u
val m0 = <!NONE_APPLICABLE!>-<!>1u
val m1: UInt = <!NONE_APPLICABLE!>-<!>1u
val h1 = 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
@TestMetadata("compiler/testData/diagnostics/tests/j+k")
@TestDataPath("$PROJECT_ROOT")
@@ -381,6 +381,8 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
fun TypeConstructorMarker.isClassTypeConstructor(): Boolean
fun TypeConstructorMarker.isInterface(): Boolean
fun TypeConstructorMarker.isIntegerLiteralTypeConstructor(): Boolean
fun TypeConstructorMarker.isIntegerLiteralConstantTypeConstructor(): Boolean
fun TypeConstructorMarker.isIntegerConstantOperatorTypeConstructor(): Boolean
fun TypeConstructorMarker.isLocalType(): Boolean
fun TypeConstructorMarker.isAnonymous(): Boolean
fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker?
@@ -45,6 +45,14 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
return this is IntegerLiteralTypeConstructor
}
override fun TypeConstructorMarker.isIntegerLiteralConstantTypeConstructor(): Boolean {
return isIntegerLiteralTypeConstructor()
}
override fun TypeConstructorMarker.isIntegerConstantOperatorTypeConstructor(): Boolean {
return false
}
override fun TypeConstructorMarker.isLocalType(): Boolean {
require(this is TypeConstructor, this::errorMessage)
return declarationDescriptor?.classId?.isLocal == true