mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-16 00:21:28 +00:00
Compare commits
28 Commits
document-c
...
ssa/native
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99b395b0fa | ||
|
|
0c5bf63844 | ||
|
|
fd7c4c0c2d | ||
|
|
4a62466671 | ||
|
|
47d0211370 | ||
|
|
5819959cce | ||
|
|
1cd321a90f | ||
|
|
16f41bd80c | ||
|
|
8ab546ba51 | ||
|
|
a5e59e09ee | ||
|
|
6d7eb2bd21 | ||
|
|
21f7e16ee6 | ||
|
|
fb1eac0985 | ||
|
|
0a6e51e47f | ||
|
|
f37d880964 | ||
|
|
301f446433 | ||
|
|
a8077aebb0 | ||
|
|
753ba99b04 | ||
|
|
a0553f4dfd | ||
|
|
c3a327e118 | ||
|
|
1a5552bef8 | ||
|
|
6660c9b26b | ||
|
|
ab158a53c3 | ||
|
|
1cdbbad367 | ||
|
|
5e87d753b7 | ||
|
|
a7cc275c7d | ||
|
|
12d694de46 | ||
|
|
16f0ba8e46 |
@@ -12,7 +12,7 @@ fun test() {
|
||||
|
||||
bar(1, z = true, y = *arrayOf("my", "yours"))
|
||||
|
||||
bar(0, z = false, y = "", <!ARGUMENT_PASSED_TWICE!>y<!> = "other")
|
||||
bar(0, z = false, y = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>""<!>, <!ARGUMENT_PASSED_TWICE!>y<!> = "other")
|
||||
bar(0, "", true<!NO_VALUE_FOR_PARAMETER!>)<!>
|
||||
bar(0, z = false, y = "", <!ARGUMENT_PASSED_TWICE!>y<!> = "other", <!ARGUMENT_PASSED_TWICE!>y<!> = "yet other")
|
||||
bar(0, z = false, y = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>""<!>, <!ARGUMENT_PASSED_TWICE!>y<!> = "other", <!ARGUMENT_PASSED_TWICE!>y<!> = "yet other")
|
||||
}
|
||||
|
||||
@@ -13,13 +13,13 @@ interface B {
|
||||
}
|
||||
|
||||
interface C {
|
||||
<!METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE!>override operator fun toString(): String = "Rest"<!>
|
||||
<!METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE!>override <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun toString(): String = "Rest"<!>
|
||||
<!METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE!>override operator fun equals(other: Any?): Boolean = false<!>
|
||||
<!METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE!>override operator fun hashCode(): Int = 2<!>
|
||||
<!METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE!>override <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hashCode(): Int = 2<!>
|
||||
}
|
||||
|
||||
interface D {
|
||||
override operator fun toString(): String
|
||||
override <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun toString(): String
|
||||
override operator fun equals(other: Any?): Boolean
|
||||
override operator fun hashCode(): Int
|
||||
override <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hashCode(): Int
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ FILE: test.kt
|
||||
private final val DERIVED_FACTORY: R|DiagnosticFactory0<ft<DerivedElement, DerivedElement?>>| = R|/DiagnosticFactory0.DiagnosticFactory0|<R|ft<DerivedElement, DerivedElement?>|>()
|
||||
private get(): R|DiagnosticFactory0<ft<DerivedElement, DerivedElement?>>|
|
||||
public final fun createViaFactory(d: R|EmptyDiagnostic|): R|kotlin/Unit| {
|
||||
lval casted: R|Diagnostic<ft<DerivedElement, DerivedElement?>>| = R|/DERIVED_FACTORY|.R|SubstitutionOverride</DiagnosticFactory0.cast: R|Diagnostic<ft<DerivedElement, DerivedElement?>>|>|(R|<local>/d|)
|
||||
lval casted: R|Diagnostic<ft<DerivedElement, DerivedElement?>>| = R|/DERIVED_FACTORY|.R|SubstitutionOverride</DiagnosticFactory0.cast: R|@EnhancedNullability Diagnostic<ft<DerivedElement, DerivedElement?>>|>|(R|<local>/d|)
|
||||
lval element: R|DerivedElement| = R|<local>/casted|.R|/Diagnostic.element|
|
||||
R|/Fix.Fix|(R|<local>/element|)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ abstract class NotRange4() {
|
||||
}
|
||||
|
||||
abstract class ImproperIterator3 {
|
||||
abstract operator fun hasNext() : Int
|
||||
abstract <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hasNext() : Int
|
||||
abstract operator fun next() : Int
|
||||
}
|
||||
|
||||
|
||||
@@ -16855,6 +16855,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/innerNestedClassFromJava.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("integerNotNullable.kt")
|
||||
public void testIntegerNotNullable() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/integerNotNullable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("invisiblePackagePrivateInheritedMember.kt")
|
||||
public void testInvisiblePackagePrivateInheritedMember() throws Exception {
|
||||
@@ -28052,6 +28058,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/smartCasts/publicVals/otherModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("otherModuleInheritance.kt")
|
||||
public void testOtherModuleInheritance() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/smartCasts/publicVals/otherModuleInheritance.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("protected.kt")
|
||||
public void testProtected() throws Exception {
|
||||
|
||||
@@ -16855,6 +16855,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/innerNestedClassFromJava.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("integerNotNullable.kt")
|
||||
public void testIntegerNotNullable() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/integerNotNullable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("invisiblePackagePrivateInheritedMember.kt")
|
||||
public void testInvisiblePackagePrivateInheritedMember() throws Exception {
|
||||
@@ -28052,6 +28058,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/smartCasts/publicVals/otherModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("otherModuleInheritance.kt")
|
||||
public void testOtherModuleInheritance() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/smartCasts/publicVals/otherModuleInheritance.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("protected.kt")
|
||||
public void testProtected() throws Exception {
|
||||
|
||||
@@ -29,6 +29,7 @@ fun main(args: Array<String>) {
|
||||
alias<FirStatement>("BasicExpressionChecker")
|
||||
alias<FirQualifiedAccess>("QualifiedAccessChecker")
|
||||
alias<FirQualifiedAccessExpression>("QualifiedAccessExpressionChecker")
|
||||
alias<FirCall>("CallChecker")
|
||||
alias<FirFunctionCall>("FunctionCallChecker")
|
||||
alias<FirVariableAssignment>("VariableAssignmentChecker")
|
||||
alias<FirTryExpression>("TryExpressionChecker")
|
||||
|
||||
@@ -301,35 +301,35 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val MODIFIERS by object : DiagnosticGroup("Modifiers") {
|
||||
val INAPPLICABLE_INFIX_MODIFIER by error<PsiElement>()
|
||||
val REPEATED_MODIFIER by error<PsiElement> {
|
||||
parameter<String>("modifier")
|
||||
parameter<KtModifierKeywordToken>("modifier")
|
||||
}
|
||||
val REDUNDANT_MODIFIER by error<PsiElement> {
|
||||
parameter<String>("redundantModifier")
|
||||
parameter<String>("conflictingModifier")
|
||||
parameter<KtModifierKeywordToken>("redundantModifier")
|
||||
parameter<KtModifierKeywordToken>("conflictingModifier")
|
||||
}
|
||||
val DEPRECATED_MODIFIER by warning<PsiElement> {
|
||||
parameter<String>("deprecatedModifier")
|
||||
parameter<String>("actualModifier")
|
||||
parameter<KtModifierKeywordToken>("deprecatedModifier")
|
||||
parameter<KtModifierKeywordToken>("actualModifier")
|
||||
}
|
||||
val DEPRECATED_MODIFIER_PAIR by error<PsiElement> {
|
||||
parameter<String>("deprecatedModifier")
|
||||
parameter<String>("conflictingModifier")
|
||||
parameter<KtModifierKeywordToken>("deprecatedModifier")
|
||||
parameter<KtModifierKeywordToken>("conflictingModifier")
|
||||
}
|
||||
val DEPRECATED_MODIFIER_FOR_TARGET by warning<PsiElement> {
|
||||
parameter<String>("deprecatedModifier")
|
||||
parameter<KtModifierKeywordToken>("deprecatedModifier")
|
||||
parameter<String>("target")
|
||||
}
|
||||
val REDUNDANT_MODIFIER_FOR_TARGET by warning<PsiElement> {
|
||||
parameter<String>("redundantModifier")
|
||||
parameter<KtModifierKeywordToken>("redundantModifier")
|
||||
parameter<String>("target")
|
||||
}
|
||||
val INCOMPATIBLE_MODIFIERS by error<PsiElement> {
|
||||
parameter<String>("modifier1")
|
||||
parameter<String>("modifier2")
|
||||
parameter<KtModifierKeywordToken>("modifier1")
|
||||
parameter<KtModifierKeywordToken>("modifier2")
|
||||
}
|
||||
val REDUNDANT_OPEN_IN_INTERFACE by warning<KtModifierListOwner>(PositioningStrategy.OPEN_MODIFIER)
|
||||
val WRONG_MODIFIER_TARGET by error<PsiElement> {
|
||||
parameter<String>("modifier")
|
||||
parameter<KtModifierKeywordToken>("modifier")
|
||||
parameter<String>("target")
|
||||
}
|
||||
val OPERATOR_MODIFIER_REQUIRED by error<PsiElement> {
|
||||
@@ -340,13 +340,16 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
parameter<FirNamedFunctionSymbol>("functionSymbol")
|
||||
}
|
||||
val WRONG_MODIFIER_CONTAINING_DECLARATION by error<PsiElement> {
|
||||
parameter<String>("modifier")
|
||||
parameter<KtModifierKeywordToken>("modifier")
|
||||
parameter<String>("target")
|
||||
}
|
||||
val DEPRECATED_MODIFIER_CONTAINING_DECLARATION by warning<PsiElement> {
|
||||
parameter<String>("modifier")
|
||||
parameter<KtModifierKeywordToken>("modifier")
|
||||
parameter<String>("target")
|
||||
}
|
||||
val INAPPLICABLE_OPERATOR_MODIFIER by error<PsiElement>(PositioningStrategy.OPERATOR_MODIFIER) {
|
||||
parameter<String>("message")
|
||||
}
|
||||
}
|
||||
|
||||
val INLINE_CLASSES by object : DiagnosticGroup("Inline classes") {
|
||||
@@ -442,6 +445,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
}
|
||||
|
||||
val SPREAD_OF_NULLABLE by error<PsiElement>(PositioningStrategy.SPREAD_OPERATOR)
|
||||
|
||||
val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION by deprecationError<KtExpression>(LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm)
|
||||
val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION by deprecationError<KtExpression>(LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm)
|
||||
}
|
||||
|
||||
val AMBIGUITY by object : DiagnosticGroup("Ambiguity") {
|
||||
|
||||
@@ -103,6 +103,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
|
||||
ABSTRACT_MODIFIER,
|
||||
LABEL,
|
||||
COMMAS,
|
||||
OPERATOR_MODIFIER,
|
||||
|
||||
;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ object FirJvmExternalDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
val externalModifier = declaration.getModifier(KtTokens.EXTERNAL_KEYWORD)
|
||||
externalModifier?.let {
|
||||
reporter.reportOn(it.source, FirErrors.WRONG_MODIFIER_TARGET, it.token.toString(), target, context)
|
||||
reporter.reportOn(it.source, FirErrors.WRONG_MODIFIER_TARGET, it.token, target, context)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ object FirJavaGenericVarianceViolationTypeChecker : FirFunctionCallChecker() {
|
||||
// actually created because of type projection from `get`. Hence, to workaround this problem, we simply remove all the out
|
||||
// projection and type capturing and compare the types after such erasure. This way, we won't incorrectly reject any valid code
|
||||
// though we may accept some invalid code. But in presence of the unsound flexible types, we are allowing invalid code already.
|
||||
val argTypeWithoutOutProjection = argType.removeOutProjection(true)
|
||||
val argTypeWithoutOutProjection = argType.removeOutProjection(isCovariant = true)
|
||||
val lowerBoundWithoutCapturing = context.session.inferenceComponents.approximator.approximateToSuperType(
|
||||
lowerBound,
|
||||
TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
|
||||
@@ -127,31 +127,34 @@ object FirJavaGenericVarianceViolationTypeChecker : FirFunctionCallChecker() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.removeOutProjection(positive: Boolean): ConeKotlinType {
|
||||
private fun ConeKotlinType.removeOutProjection(isCovariant: Boolean): ConeKotlinType {
|
||||
return when (this) {
|
||||
is ConeFlexibleType -> ConeFlexibleType(lowerBound.removeOutProjection(positive), upperBound.removeOutProjection(positive))
|
||||
is ConeFlexibleType -> ConeFlexibleType(
|
||||
lowerBound.removeOutProjection(isCovariant),
|
||||
upperBound.removeOutProjection(isCovariant)
|
||||
)
|
||||
is ConeCapturedType -> ConeCapturedType(
|
||||
captureStatus,
|
||||
lowerType?.removeOutProjection(positive),
|
||||
lowerType?.removeOutProjection(isCovariant),
|
||||
nullability,
|
||||
constructor.apply {
|
||||
ConeCapturedTypeConstructor(
|
||||
projection.removeOutProjection(positive),
|
||||
supertypes?.map { it.removeOutProjection(positive) },
|
||||
projection.removeOutProjection(isCovariant),
|
||||
supertypes?.map { it.removeOutProjection(isCovariant) },
|
||||
typeParameterMarker
|
||||
)
|
||||
},
|
||||
attributes,
|
||||
isProjectionNotNull
|
||||
)
|
||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType(original.removeOutProjection(positive))
|
||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType(original.removeOutProjection(isCovariant))
|
||||
is ConeIntersectionType -> ConeIntersectionType(
|
||||
intersectedTypes.map { it.removeOutProjection(positive) },
|
||||
alternativeType?.removeOutProjection(positive)
|
||||
intersectedTypes.map { it.removeOutProjection(isCovariant) },
|
||||
alternativeType?.removeOutProjection(isCovariant)
|
||||
)
|
||||
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(
|
||||
lookupTag,
|
||||
typeArguments.map { it.removeOutProjection(positive) }.toTypedArray(),
|
||||
typeArguments.map { it.removeOutProjection(isCovariant) }.toTypedArray(),
|
||||
isNullable,
|
||||
attributes
|
||||
)
|
||||
@@ -159,11 +162,17 @@ object FirJavaGenericVarianceViolationTypeChecker : FirFunctionCallChecker() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeTypeProjection.removeOutProjection(positive: Boolean): ConeTypeProjection {
|
||||
/**
|
||||
* @param isCovariant true if the current context is covariant and false if contravariant.
|
||||
*
|
||||
* This function only remove out projections in covariant context.
|
||||
* 'in' projections are never removed, nor would an out projection in a contravariant context.
|
||||
*/
|
||||
private fun ConeTypeProjection.removeOutProjection(isCovariant: Boolean): ConeTypeProjection {
|
||||
return when (this) {
|
||||
is ConeKotlinTypeProjectionOut -> if (positive) type else this
|
||||
is ConeKotlinTypeProjectionIn -> ConeKotlinTypeProjectionIn(type.removeOutProjection(!positive))
|
||||
is ConeStarProjection -> if (positive) StandardTypes.Any else this
|
||||
is ConeKotlinTypeProjectionOut -> if (isCovariant) type else this
|
||||
is ConeKotlinTypeProjectionIn -> ConeKotlinTypeProjectionIn(type.removeOutProjection(!isCovariant))
|
||||
is ConeStarProjection -> if (isCovariant) StandardTypes.Any else this
|
||||
// Don't remove nested projections for types at invariant position.
|
||||
is ConeKotlinTypeConflictingProjection,
|
||||
is ConeKotlinType -> this
|
||||
@@ -182,7 +191,10 @@ object FirJavaGenericVarianceViolationTypeChecker : FirFunctionCallChecker() {
|
||||
for (immediateSuperType in subTypeConstructor.supertypes()) {
|
||||
val immediateSuperTypeConstructor = immediateSuperType.typeConstructor()
|
||||
if (superTypeConstructor == immediateSuperTypeConstructor) return true
|
||||
if (this@isTypeConstructorEqualOrSubClassOf.isTypeConstructorEqualOrSubClassOf(immediateSuperTypeConstructor, superTypeConstructor)) return true
|
||||
if (this@isTypeConstructorEqualOrSubClassOf.isTypeConstructorEqualOrSubClassOf(
|
||||
immediateSuperTypeConstructor, superTypeConstructor
|
||||
)
|
||||
) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ class ComposedExpressionCheckers : ExpressionCheckers() {
|
||||
get() = _qualifiedAccessCheckers
|
||||
override val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker>
|
||||
get() = _qualifiedAccessExpressionCheckers
|
||||
override val callCheckers: Set<FirCallChecker>
|
||||
get() = _callCheckers
|
||||
override val functionCallCheckers: Set<FirFunctionCallChecker>
|
||||
get() = _functionCallCheckers
|
||||
override val variableAssignmentCheckers: Set<FirVariableAssignmentChecker>
|
||||
@@ -73,6 +75,7 @@ class ComposedExpressionCheckers : ExpressionCheckers() {
|
||||
private val _basicExpressionCheckers: MutableSet<FirBasicExpressionChecker> = mutableSetOf()
|
||||
private val _qualifiedAccessCheckers: MutableSet<FirQualifiedAccessChecker> = mutableSetOf()
|
||||
private val _qualifiedAccessExpressionCheckers: MutableSet<FirQualifiedAccessExpressionChecker> = mutableSetOf()
|
||||
private val _callCheckers: MutableSet<FirCallChecker> = mutableSetOf()
|
||||
private val _functionCallCheckers: MutableSet<FirFunctionCallChecker> = mutableSetOf()
|
||||
private val _variableAssignmentCheckers: MutableSet<FirVariableAssignmentChecker> = mutableSetOf()
|
||||
private val _tryExpressionCheckers: MutableSet<FirTryExpressionChecker> = mutableSetOf()
|
||||
@@ -104,6 +107,7 @@ class ComposedExpressionCheckers : ExpressionCheckers() {
|
||||
_basicExpressionCheckers += checkers.basicExpressionCheckers
|
||||
_qualifiedAccessCheckers += checkers.qualifiedAccessCheckers
|
||||
_qualifiedAccessExpressionCheckers += checkers.qualifiedAccessExpressionCheckers
|
||||
_callCheckers += checkers.callCheckers
|
||||
_functionCallCheckers += checkers.functionCallCheckers
|
||||
_variableAssignmentCheckers += checkers.variableAssignmentCheckers
|
||||
_tryExpressionCheckers += checkers.tryExpressionCheckers
|
||||
|
||||
@@ -20,6 +20,7 @@ abstract class ExpressionCheckers {
|
||||
open val basicExpressionCheckers: Set<FirBasicExpressionChecker> = emptySet()
|
||||
open val qualifiedAccessCheckers: Set<FirQualifiedAccessChecker> = emptySet()
|
||||
open val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker> = emptySet()
|
||||
open val callCheckers: Set<FirCallChecker> = emptySet()
|
||||
open val functionCallCheckers: Set<FirFunctionCallChecker> = emptySet()
|
||||
open val variableAssignmentCheckers: Set<FirVariableAssignmentChecker> = emptySet()
|
||||
open val tryExpressionCheckers: Set<FirTryExpressionChecker> = emptySet()
|
||||
@@ -49,7 +50,8 @@ abstract class ExpressionCheckers {
|
||||
@CheckersComponentInternal internal val allBasicExpressionCheckers: Set<FirBasicExpressionChecker> by lazy { basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allQualifiedAccessCheckers: Set<FirQualifiedAccessChecker> by lazy { qualifiedAccessCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allQualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker> by lazy { qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers }
|
||||
@CheckersComponentInternal internal val allFunctionCallCheckers: Set<FirFunctionCallChecker> by lazy { functionCallCheckers + 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 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 }
|
||||
@@ -58,20 +60,20 @@ abstract class ExpressionCheckers {
|
||||
@CheckersComponentInternal internal val allLogicExpressionCheckers: Set<FirLogicExpressionChecker> by lazy { logicExpressionCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allReturnExpressionCheckers: Set<FirReturnExpressionChecker> by lazy { returnExpressionCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allBlockCheckers: Set<FirBlockChecker> by lazy { blockCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allAnnotationCallCheckers: Set<FirAnnotationCallChecker> by lazy { annotationCallCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allCheckNotNullCallCheckers: Set<FirCheckNotNullCallChecker> by lazy { checkNotNullCallCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allAnnotationCallCheckers: Set<FirAnnotationCallChecker> by lazy { annotationCallCheckers + basicExpressionCheckers + callCheckers }
|
||||
@CheckersComponentInternal internal val allCheckNotNullCallCheckers: Set<FirCheckNotNullCallChecker> by lazy { checkNotNullCallCheckers + basicExpressionCheckers + callCheckers }
|
||||
@CheckersComponentInternal internal val allElvisExpressionCheckers: Set<FirElvisExpressionChecker> by lazy { elvisExpressionCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allGetClassCallCheckers: Set<FirGetClassCallChecker> by lazy { getClassCallCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allGetClassCallCheckers: Set<FirGetClassCallChecker> by lazy { getClassCallCheckers + basicExpressionCheckers + callCheckers }
|
||||
@CheckersComponentInternal internal val allSafeCallExpressionCheckers: Set<FirSafeCallExpressionChecker> by lazy { safeCallExpressionCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allEqualityOperatorCallCheckers: Set<FirEqualityOperatorCallChecker> by lazy { equalityOperatorCallCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allStringConcatenationCallCheckers: Set<FirStringConcatenationCallChecker> by lazy { stringConcatenationCallCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allTypeOperatorCallCheckers: Set<FirTypeOperatorCallChecker> by lazy { typeOperatorCallCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allEqualityOperatorCallCheckers: Set<FirEqualityOperatorCallChecker> by lazy { equalityOperatorCallCheckers + basicExpressionCheckers + callCheckers }
|
||||
@CheckersComponentInternal internal val allStringConcatenationCallCheckers: Set<FirStringConcatenationCallChecker> by lazy { stringConcatenationCallCheckers + callCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allTypeOperatorCallCheckers: Set<FirTypeOperatorCallChecker> by lazy { typeOperatorCallCheckers + basicExpressionCheckers + callCheckers }
|
||||
@CheckersComponentInternal internal val allResolvedQualifierCheckers: Set<FirResolvedQualifierChecker> by lazy { resolvedQualifierCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allConstExpressionCheckers: Set<FirConstExpressionChecker> by lazy { constExpressionCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allCallableReferenceAccessCheckers: Set<FirCallableReferenceAccessChecker> by lazy { callableReferenceAccessCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers }
|
||||
@CheckersComponentInternal internal val allThisReceiverExpressionCheckers: Set<FirThisReceiverExpressionChecker> by lazy { thisReceiverExpressionCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers }
|
||||
@CheckersComponentInternal internal val allWhileLoopCheckers: Set<FirWhileLoopChecker> by lazy { whileLoopCheckers + loopExpressionCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allDoWhileLoopCheckers: Set<FirDoWhileLoopChecker> by lazy { doWhileLoopCheckers + loopExpressionCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allArrayOfCallCheckers: Set<FirArrayOfCallChecker> by lazy { arrayOfCallCheckers + basicExpressionCheckers }
|
||||
@CheckersComponentInternal internal val allArrayOfCallCheckers: Set<FirArrayOfCallChecker> by lazy { arrayOfCallCheckers + basicExpressionCheckers + callCheckers }
|
||||
@CheckersComponentInternal internal val allClassReferenceExpressionCheckers: Set<FirClassReferenceExpressionChecker> by lazy { classReferenceExpressionCheckers + basicExpressionCheckers }
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirBinaryLogicExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
||||
import org.jetbrains.kotlin.fir.expressions.FirCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
|
||||
import org.jetbrains.kotlin.fir.expressions.FirCheckNotNullCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression
|
||||
@@ -42,6 +43,7 @@ import org.jetbrains.kotlin.fir.expressions.FirWhileLoop
|
||||
typealias FirBasicExpressionChecker = FirExpressionChecker<FirStatement>
|
||||
typealias FirQualifiedAccessChecker = FirExpressionChecker<FirQualifiedAccess>
|
||||
typealias FirQualifiedAccessExpressionChecker = FirExpressionChecker<FirQualifiedAccessExpression>
|
||||
typealias FirCallChecker = FirExpressionChecker<FirCall>
|
||||
typealias FirFunctionCallChecker = FirExpressionChecker<FirFunctionCall>
|
||||
typealias FirVariableAssignmentChecker = FirExpressionChecker<FirVariableAssignment>
|
||||
typealias FirTryExpressionChecker = FirExpressionChecker<FirTryExpression>
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitInvisibleAbstractMethodsInSuperclasses
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitNonReifiedArraysAsReifiedTypeArguments
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitUseSiteTargetAnnotationsOnSuperTypes
|
||||
@@ -37,6 +38,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
@@ -253,19 +255,20 @@ object FirErrors {
|
||||
|
||||
// Modifiers
|
||||
val INAPPLICABLE_INFIX_MODIFIER by error0<PsiElement>()
|
||||
val REPEATED_MODIFIER by error1<PsiElement, String>()
|
||||
val REDUNDANT_MODIFIER by error2<PsiElement, String, String>()
|
||||
val DEPRECATED_MODIFIER by warning2<PsiElement, String, String>()
|
||||
val DEPRECATED_MODIFIER_PAIR by error2<PsiElement, String, String>()
|
||||
val DEPRECATED_MODIFIER_FOR_TARGET by warning2<PsiElement, String, String>()
|
||||
val REDUNDANT_MODIFIER_FOR_TARGET by warning2<PsiElement, String, String>()
|
||||
val INCOMPATIBLE_MODIFIERS by error2<PsiElement, String, String>()
|
||||
val REPEATED_MODIFIER by error1<PsiElement, KtModifierKeywordToken>()
|
||||
val REDUNDANT_MODIFIER by error2<PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
|
||||
val DEPRECATED_MODIFIER by warning2<PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
|
||||
val DEPRECATED_MODIFIER_PAIR by error2<PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
|
||||
val DEPRECATED_MODIFIER_FOR_TARGET by warning2<PsiElement, KtModifierKeywordToken, String>()
|
||||
val REDUNDANT_MODIFIER_FOR_TARGET by warning2<PsiElement, KtModifierKeywordToken, String>()
|
||||
val INCOMPATIBLE_MODIFIERS by error2<PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
|
||||
val REDUNDANT_OPEN_IN_INTERFACE by warning0<KtModifierListOwner>(SourceElementPositioningStrategies.OPEN_MODIFIER)
|
||||
val WRONG_MODIFIER_TARGET by error2<PsiElement, String, String>()
|
||||
val WRONG_MODIFIER_TARGET by error2<PsiElement, KtModifierKeywordToken, String>()
|
||||
val OPERATOR_MODIFIER_REQUIRED by error2<PsiElement, FirNamedFunctionSymbol, String>()
|
||||
val INFIX_MODIFIER_REQUIRED by error1<PsiElement, FirNamedFunctionSymbol>()
|
||||
val WRONG_MODIFIER_CONTAINING_DECLARATION by error2<PsiElement, String, String>()
|
||||
val DEPRECATED_MODIFIER_CONTAINING_DECLARATION by warning2<PsiElement, String, String>()
|
||||
val WRONG_MODIFIER_CONTAINING_DECLARATION by error2<PsiElement, KtModifierKeywordToken, String>()
|
||||
val DEPRECATED_MODIFIER_CONTAINING_DECLARATION by warning2<PsiElement, KtModifierKeywordToken, String>()
|
||||
val INAPPLICABLE_OPERATOR_MODIFIER by error1<PsiElement, String>(SourceElementPositioningStrategies.OPERATOR_MODIFIER)
|
||||
|
||||
// Inline classes
|
||||
val INLINE_CLASS_NOT_TOP_LEVEL by error0<KtDeclaration>(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER)
|
||||
@@ -305,6 +308,8 @@ object FirErrors {
|
||||
val MANY_LAMBDA_EXPRESSION_ARGUMENTS by error0<KtValueArgument>()
|
||||
val NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER by error1<KtElement, String>()
|
||||
val SPREAD_OF_NULLABLE by error0<PsiElement>(SourceElementPositioningStrategies.SPREAD_OPERATOR)
|
||||
val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION by deprecationError0<KtExpression>(ProhibitAssigningSingleElementsToVarargsInNamedForm)
|
||||
val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION by deprecationError0<KtExpression>(ProhibitAssigningSingleElementsToVarargsInNamedForm)
|
||||
|
||||
// Ambiguity
|
||||
val OVERLOAD_RESOLUTION_AMBIGUITY by error1<PsiElement, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
|
||||
@@ -45,6 +45,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
get() = setOf(
|
||||
FirFunctionNameChecker,
|
||||
FirFunctionTypeParametersSyntaxChecker,
|
||||
FirOperatorModifierChecker,
|
||||
)
|
||||
|
||||
override val propertyCheckers: Set<FirPropertyChecker>
|
||||
|
||||
@@ -45,6 +45,11 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
||||
FirSuspendCallChecker,
|
||||
)
|
||||
|
||||
override val callCheckers: Set<FirCallChecker>
|
||||
get() = setOf(
|
||||
FirNamedVarargChecker,
|
||||
)
|
||||
|
||||
override val functionCallCheckers: Set<FirFunctionCallChecker>
|
||||
get() = setOf(
|
||||
FirConventionFunctionCallChecker,
|
||||
@@ -52,6 +57,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
||||
FirConstructorCallChecker,
|
||||
FirSpreadOfNullableChecker,
|
||||
FirAssignmentOperatorCallChecker,
|
||||
FirNamedVarargChecker,
|
||||
)
|
||||
|
||||
override val tryExpressionCheckers: Set<FirTryExpressionChecker>
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* 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 licensedot/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers
|
||||
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
import org.jetbrains.kotlin.resolve.KeywordType
|
||||
|
||||
fun getKeywordType(modifier: FirModifier<*>): KeywordType {
|
||||
return ktKeywordToKeywordTypeMap[modifier.token]!!
|
||||
}
|
||||
|
||||
private val ktKeywordToKeywordTypeMap: Map<KtKeywordToken, KeywordType> = mapOf(
|
||||
INNER_KEYWORD to KeywordType.Inner,
|
||||
OVERRIDE_KEYWORD to KeywordType.Override,
|
||||
PUBLIC_KEYWORD to KeywordType.Public,
|
||||
PROTECTED_KEYWORD to KeywordType.Protected,
|
||||
INTERNAL_KEYWORD to KeywordType.Internal,
|
||||
PRIVATE_KEYWORD to KeywordType.Private,
|
||||
COMPANION_KEYWORD to KeywordType.Companion,
|
||||
FINAL_KEYWORD to KeywordType.Final,
|
||||
VARARG_KEYWORD to KeywordType.Vararg,
|
||||
ENUM_KEYWORD to KeywordType.Enum,
|
||||
ABSTRACT_KEYWORD to KeywordType.Abstract,
|
||||
OPEN_KEYWORD to KeywordType.Open,
|
||||
SEALED_KEYWORD to KeywordType.Sealed,
|
||||
IN_KEYWORD to KeywordType.In,
|
||||
OUT_KEYWORD to KeywordType.Out,
|
||||
REIFIED_KEYWORD to KeywordType.Reified,
|
||||
LATEINIT_KEYWORD to KeywordType.Lateinit,
|
||||
DATA_KEYWORD to KeywordType.Data,
|
||||
INLINE_KEYWORD to KeywordType.Inline,
|
||||
NOINLINE_KEYWORD to KeywordType.Noinline,
|
||||
TAILREC_KEYWORD to KeywordType.Tailrec,
|
||||
SUSPEND_KEYWORD to KeywordType.Suspend,
|
||||
EXTERNAL_KEYWORD to KeywordType.External,
|
||||
ANNOTATION_KEYWORD to KeywordType.Annotation,
|
||||
CROSSINLINE_KEYWORD to KeywordType.Crossinline,
|
||||
CONST_KEYWORD to KeywordType.Const,
|
||||
OPERATOR_KEYWORD to KeywordType.Operator,
|
||||
INFIX_KEYWORD to KeywordType.Infix,
|
||||
HEADER_KEYWORD to KeywordType.Header,
|
||||
IMPL_KEYWORD to KeywordType.Impl,
|
||||
EXPECT_KEYWORD to KeywordType.Expect,
|
||||
ACTUAL_KEYWORD to KeywordType.Actual,
|
||||
FUN_KEYWORD to KeywordType.Fun,
|
||||
VALUE_KEYWORD to KeywordType.Value
|
||||
)
|
||||
@@ -29,7 +29,7 @@ object FirConstPropertyChecker : FirPropertyChecker() {
|
||||
if (declaration.isVar) {
|
||||
val constModifier = declaration.getModifier(KtTokens.CONST_KEYWORD)
|
||||
constModifier?.let {
|
||||
reporter.reportOn(it.source, FirErrors.WRONG_MODIFIER_TARGET, it.token.toString(), "vars", context)
|
||||
reporter.reportOn(it.source, FirErrors.WRONG_MODIFIER_TARGET, it.token, "vars", context)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInner
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
|
||||
object FirModifierChecker : FirBasicDeclarationChecker() {
|
||||
@@ -87,10 +89,10 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
if (secondModifier !in reportedNodes) {
|
||||
val modifierSource = secondModifier.source
|
||||
val modifierType = getKeywordType(secondModifier)
|
||||
val modifier = secondModifier.token
|
||||
when {
|
||||
!checkTarget(modifierSource, modifierType, actualTargets, parent, context, reporter) -> reportedNodes += secondModifier
|
||||
!checkParent(modifierSource, modifierType, actualParents, context, reporter) -> reportedNodes += secondModifier
|
||||
!checkTarget(modifierSource, modifier, actualTargets, parent, context, reporter) -> reportedNodes += secondModifier
|
||||
!checkParent(modifierSource, modifier, actualParents, context, reporter) -> reportedNodes += secondModifier
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,21 +106,21 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
||||
owner: FirDeclaration?,
|
||||
context: CheckerContext
|
||||
) {
|
||||
val firstModifierType = getKeywordType(firstModifier)
|
||||
val secondModifierType = getKeywordType(secondModifier)
|
||||
when (val compatibilityType = compatibility(firstModifierType, secondModifierType)) {
|
||||
val firstModifierToken = firstModifier.token
|
||||
val secondModifierToken = secondModifier.token
|
||||
when (val compatibilityType = compatibility(firstModifierToken, secondModifierToken)) {
|
||||
Compatibility.COMPATIBLE -> {
|
||||
}
|
||||
Compatibility.REPEATED ->
|
||||
if (reportedNodes.add(secondModifier)) {
|
||||
reporter.reportOn(secondModifier.source, FirErrors.REPEATED_MODIFIER, secondModifierType.render(), context)
|
||||
reporter.reportOn(secondModifier.source, FirErrors.REPEATED_MODIFIER, secondModifierToken, context)
|
||||
}
|
||||
Compatibility.REDUNDANT -> {
|
||||
reporter.reportOn(
|
||||
secondModifier.source,
|
||||
FirErrors.REDUNDANT_MODIFIER,
|
||||
secondModifierType.render(),
|
||||
firstModifierType.render(),
|
||||
secondModifierToken,
|
||||
firstModifierToken,
|
||||
context
|
||||
)
|
||||
}
|
||||
@@ -126,8 +128,8 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
||||
reporter.reportOn(
|
||||
firstModifier.source,
|
||||
FirErrors.REDUNDANT_MODIFIER,
|
||||
firstModifierType.render(),
|
||||
secondModifierType.render(),
|
||||
firstModifierToken,
|
||||
secondModifierToken,
|
||||
context
|
||||
)
|
||||
}
|
||||
@@ -135,15 +137,15 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
||||
reporter.reportOn(
|
||||
firstModifier.source,
|
||||
FirErrors.DEPRECATED_MODIFIER_PAIR,
|
||||
firstModifierType.render(),
|
||||
secondModifierType.render(),
|
||||
firstModifierToken,
|
||||
secondModifierToken,
|
||||
context
|
||||
)
|
||||
reporter.reportOn(
|
||||
secondModifier.source,
|
||||
FirErrors.DEPRECATED_MODIFIER_PAIR,
|
||||
secondModifierType.render(),
|
||||
firstModifierType.render(),
|
||||
secondModifierToken,
|
||||
firstModifierToken,
|
||||
context
|
||||
)
|
||||
}
|
||||
@@ -155,8 +157,8 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
||||
reporter.reportOn(
|
||||
firstModifier.source,
|
||||
FirErrors.INCOMPATIBLE_MODIFIERS,
|
||||
firstModifierType.render(),
|
||||
secondModifierType.render(),
|
||||
firstModifierToken,
|
||||
secondModifierToken,
|
||||
context
|
||||
)
|
||||
}
|
||||
@@ -164,8 +166,8 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
||||
reporter.reportOn(
|
||||
secondModifier.source,
|
||||
FirErrors.INCOMPATIBLE_MODIFIERS,
|
||||
secondModifierType.render(),
|
||||
firstModifierType.render(),
|
||||
secondModifierToken,
|
||||
firstModifierToken,
|
||||
context
|
||||
)
|
||||
}
|
||||
@@ -175,19 +177,19 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
||||
|
||||
private fun checkTarget(
|
||||
modifierSource: FirSourceElement,
|
||||
modifierType: KeywordType,
|
||||
modifierToken: KtModifierKeywordToken,
|
||||
actualTargets: List<KotlinTarget>,
|
||||
parent: FirDeclaration?,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
): Boolean {
|
||||
fun checkModifier(factory: FirDiagnosticFactory2<String, String>): Boolean {
|
||||
fun checkModifier(factory: FirDiagnosticFactory2<KtModifierKeywordToken, String>): Boolean {
|
||||
val map = when (factory) {
|
||||
FirErrors.WRONG_MODIFIER_TARGET -> possibleTargetMap
|
||||
FirErrors.DEPRECATED_MODIFIER_FOR_TARGET -> deprecatedTargetMap
|
||||
else -> redundantTargetMap
|
||||
}
|
||||
val set = map[modifierType] ?: emptySet()
|
||||
val set = map[modifierToken] ?: emptySet()
|
||||
val checkResult = if (factory == FirErrors.WRONG_MODIFIER_TARGET) {
|
||||
actualTargets.none { it in set }
|
||||
} else {
|
||||
@@ -197,7 +199,7 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
||||
reporter.reportOn(
|
||||
modifierSource,
|
||||
factory,
|
||||
modifierType.render(),
|
||||
modifierToken,
|
||||
actualTargets.firstOrThis(),
|
||||
context
|
||||
)
|
||||
@@ -211,19 +213,19 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
|
||||
if (parent is FirRegularClass) {
|
||||
if (modifierType == KeywordType.Expect || modifierType == KeywordType.Header) {
|
||||
reporter.reportOn(modifierSource, FirErrors.WRONG_MODIFIER_TARGET, modifierType.render(), "nested class", context)
|
||||
if (modifierToken == KtTokens.EXPECT_KEYWORD || modifierToken == KtTokens.HEADER_KEYWORD) {
|
||||
reporter.reportOn(modifierSource, FirErrors.WRONG_MODIFIER_TARGET, modifierToken, "nested class", context)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
val deprecatedModifierReplacement = deprecatedModifierMap[modifierType]
|
||||
val deprecatedModifierReplacement = deprecatedModifierMap[modifierToken]
|
||||
if (deprecatedModifierReplacement != null) {
|
||||
reporter.reportOn(
|
||||
modifierSource,
|
||||
FirErrors.DEPRECATED_MODIFIER,
|
||||
modifierType.render(),
|
||||
deprecatedModifierReplacement.render(),
|
||||
modifierToken,
|
||||
deprecatedModifierReplacement,
|
||||
context
|
||||
)
|
||||
} else if (checkModifier(FirErrors.DEPRECATED_MODIFIER_FOR_TARGET)) {
|
||||
@@ -235,30 +237,30 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
||||
|
||||
private fun checkParent(
|
||||
modifierSource: FirSourceElement,
|
||||
modifierType: KeywordType,
|
||||
modifierToken: KtModifierKeywordToken,
|
||||
actualParents: List<KotlinTarget>,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
): Boolean {
|
||||
val deprecatedParents = deprecatedParentTargetMap[modifierType]
|
||||
val deprecatedParents = deprecatedParentTargetMap[modifierToken]
|
||||
if (deprecatedParents != null && actualParents.any { it in deprecatedParents }) {
|
||||
reporter.reportOn(
|
||||
modifierSource,
|
||||
FirErrors.DEPRECATED_MODIFIER_CONTAINING_DECLARATION,
|
||||
modifierType.render(),
|
||||
modifierToken,
|
||||
actualParents.firstOrThis(),
|
||||
context
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
val possibleParentPredicate = possibleParentTargetPredicateMap[modifierType] ?: return true
|
||||
val possibleParentPredicate = possibleParentTargetPredicateMap[modifierToken] ?: return true
|
||||
if (actualParents.any { possibleParentPredicate.isAllowed(it, context.session.languageVersionSettings) }) return true
|
||||
|
||||
reporter.reportOn(
|
||||
modifierSource,
|
||||
FirErrors.WRONG_MODIFIER_CONTAINING_DECLARATION,
|
||||
modifierType.render(),
|
||||
modifierToken,
|
||||
actualParents.firstOrThis(),
|
||||
context
|
||||
)
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.analysis.checkers.declaration
|
||||
|
||||
import javaslang.Function2
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.Returns
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.ValueParametersCount
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.isKProperty
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.member
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.memberOrExtension
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.noDefaultAndVarargs
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.hasModifier
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.isSubtypeOf
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.isSupertypeOf
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.overriddenFunctions
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.containingClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isOperator
|
||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.ASSIGNMENT_OPERATIONS
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.BINARY_OPERATION_NAMES
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.COMPARE_TO
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.COMPONENT_REGEX
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.CONTAINS
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.DEC
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.GET
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.GET_VALUE
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.HAS_NEXT
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.INC
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.INVOKE
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.ITERATOR
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.NEXT
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.PROVIDE_DELEGATE
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.RANGE_TO
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.SET
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.SET_VALUE
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.SIMPLE_UNARY_OPERATION_NAMES
|
||||
|
||||
|
||||
object FirOperatorModifierChecker : FirSimpleFunctionChecker() {
|
||||
|
||||
override fun check(declaration: FirSimpleFunction, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (!declaration.isOperator) return
|
||||
//we are not interested in implicit operators from override
|
||||
if (!declaration.hasModifier(KtTokens.OPERATOR_KEYWORD)) return
|
||||
|
||||
val checks = OperatorFunctionChecks.checksByName.getOrElse(declaration.name) {
|
||||
OperatorFunctionChecks.regexChecks.find { it.first.matches(declaration.name.asString()) }?.second
|
||||
}
|
||||
|
||||
if (checks == null) {
|
||||
reporter.reportOn(declaration.source, FirErrors.INAPPLICABLE_OPERATOR_MODIFIER, "illegal function name", context)
|
||||
return
|
||||
}
|
||||
|
||||
for (check in checks) {
|
||||
check.check(context, declaration)?.let { error ->
|
||||
reporter.reportOn(declaration.source, FirErrors.INAPPLICABLE_OPERATOR_MODIFIER, error, context)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface Check : Function2<CheckerContext, FirSimpleFunction, String?> {
|
||||
override fun apply(t1: CheckerContext, t2: FirSimpleFunction): String? = check(t1, t2)
|
||||
fun check(context: CheckerContext, function: FirSimpleFunction): String?
|
||||
}
|
||||
|
||||
object Checks {
|
||||
fun simple(message: String, predicate: (FirSimpleFunction) -> Boolean) = object : Check {
|
||||
override fun check(context: CheckerContext, function: FirSimpleFunction): String? = message.takeIf { !predicate(function) }
|
||||
}
|
||||
|
||||
fun full(message: String, predicate: (CheckerContext, FirSimpleFunction) -> Boolean) = object : Check {
|
||||
override fun check(context: CheckerContext, function: FirSimpleFunction): String? = message.takeIf { !predicate(context, function) }
|
||||
}
|
||||
|
||||
val memberOrExtension = simple("must be a member or an extension function") {
|
||||
it.dispatchReceiverType != null || it.receiverTypeRef != null
|
||||
}
|
||||
|
||||
val member = simple("must be a member function") {
|
||||
it.dispatchReceiverType != null
|
||||
}
|
||||
|
||||
object ValueParametersCount {
|
||||
fun atLeast(n: Int) = simple("must have at least $n value parameter" + (if (n > 1) "s" else "")) {
|
||||
it.valueParameters.size >= n
|
||||
}
|
||||
|
||||
fun exactly(n: Int) = simple("must have exactly $n value parameters") {
|
||||
it.valueParameters.size == n
|
||||
}
|
||||
|
||||
val single = simple("must have a single value parameter") {
|
||||
it.valueParameters.size == 1
|
||||
}
|
||||
val none = simple("must have no value parameters") {
|
||||
it.valueParameters.isEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
object Returns {
|
||||
val boolean = simple("must return Boolean") {
|
||||
it.returnTypeRef.isBoolean
|
||||
}
|
||||
|
||||
val int = simple("must return Int") {
|
||||
it.returnTypeRef.isInt
|
||||
}
|
||||
|
||||
val unit = simple("must return Unit") {
|
||||
it.returnTypeRef.isUnit
|
||||
}
|
||||
}
|
||||
|
||||
val noDefaultAndVarargs = simple("should not have varargs or parameters with default values") {
|
||||
it.valueParameters.all { param ->
|
||||
param.defaultValue == null && !param.isVararg
|
||||
}
|
||||
}
|
||||
|
||||
private val kPropertyType = ConeClassLikeTypeImpl(
|
||||
ConeClassLikeLookupTagImpl(StandardNames.FqNames.kProperty),
|
||||
arrayOf(ConeStarProjection),
|
||||
isNullable = false
|
||||
)
|
||||
|
||||
val isKProperty = full("second parameter must be of type KProperty<*> or its supertype") { ctx, function ->
|
||||
val paramType = function.valueParameters[1].returnTypeRef.coneType
|
||||
paramType.isSupertypeOf(ctx.session.typeContext, kPropertyType)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
object OperatorFunctionChecks {
|
||||
|
||||
//reimplementation of org.jetbrains.kotlin.util.OperatorChecks for FIR
|
||||
val checksByName: Map<Name, List<Check>> = buildMap<Name, List<Check>> {
|
||||
checkFor(GET, memberOrExtension, ValueParametersCount.atLeast(1))
|
||||
checkFor(
|
||||
SET,
|
||||
memberOrExtension, ValueParametersCount.atLeast(2),
|
||||
Checks.simple("last parameter should not have a default value or be a vararg") {
|
||||
it.valueParameters.lastOrNull()?.let { param ->
|
||||
param.defaultValue == null && !param.isVararg
|
||||
} == true
|
||||
}
|
||||
)
|
||||
checkFor(GET_VALUE, memberOrExtension, noDefaultAndVarargs, ValueParametersCount.atLeast(2), isKProperty)
|
||||
checkFor(SET_VALUE, memberOrExtension, noDefaultAndVarargs, ValueParametersCount.atLeast(3), isKProperty)
|
||||
checkFor(PROVIDE_DELEGATE, memberOrExtension, noDefaultAndVarargs, ValueParametersCount.exactly(2), isKProperty)
|
||||
checkFor(INVOKE, memberOrExtension)
|
||||
checkFor(CONTAINS, memberOrExtension, ValueParametersCount.single, noDefaultAndVarargs, Returns.boolean)
|
||||
checkFor(ITERATOR, memberOrExtension, ValueParametersCount.none)
|
||||
checkFor(NEXT, memberOrExtension, ValueParametersCount.none)
|
||||
checkFor(HAS_NEXT, memberOrExtension, ValueParametersCount.none, Returns.boolean)
|
||||
checkFor(RANGE_TO, memberOrExtension, ValueParametersCount.single, noDefaultAndVarargs)
|
||||
checkFor(
|
||||
EQUALS,
|
||||
member,
|
||||
Checks.full("must override ''equals()'' in Any") { ctx, function ->
|
||||
val containingClass = function.containingClass()?.toFirRegularClass(ctx.session) ?: return@full true
|
||||
function.overriddenFunctions(containingClass, ctx).any {
|
||||
it.containingClass()?.classId?.asSingleFqName() == StandardNames.FqNames.any.toSafe()
|
||||
}
|
||||
}
|
||||
)
|
||||
checkFor(COMPARE_TO, memberOrExtension, Returns.int, ValueParametersCount.single, noDefaultAndVarargs)
|
||||
checkFor(BINARY_OPERATION_NAMES, memberOrExtension, ValueParametersCount.single, noDefaultAndVarargs)
|
||||
checkFor(SIMPLE_UNARY_OPERATION_NAMES, memberOrExtension, ValueParametersCount.none)
|
||||
checkFor(
|
||||
setOf(INC, DEC),
|
||||
memberOrExtension,
|
||||
Checks.full("receiver must be a supertype of the return type") { ctx, function ->
|
||||
val receiver = function.dispatchReceiverType ?: function.receiverTypeRef?.coneType ?: return@full false
|
||||
function.returnTypeRef.coneType.isSubtypeOf(ctx.session.typeContext, receiver)
|
||||
}
|
||||
)
|
||||
checkFor(ASSIGNMENT_OPERATIONS, memberOrExtension, Returns.unit, ValueParametersCount.single, noDefaultAndVarargs)
|
||||
}
|
||||
|
||||
val regexChecks: List<Pair<Regex, List<Check>>> = buildList {
|
||||
checkFor(COMPONENT_REGEX, memberOrExtension, ValueParametersCount.none)
|
||||
}
|
||||
|
||||
private fun MutableMap<Name, List<Check>>.checkFor(name: Name, vararg checks: Check) {
|
||||
put(name, checks.asList())
|
||||
}
|
||||
|
||||
private fun MutableMap<Name, List<Check>>.checkFor(names: Set<Name>, vararg checks: Check) {
|
||||
names.forEach { put(it, checks.asList()) }
|
||||
}
|
||||
|
||||
private fun MutableList<Pair<Regex, List<Check>>>.checkFor(regex: Regex, vararg checks: Check) {
|
||||
add(regex to checks.asList())
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ object FirDeprecationChecker : FirBasicExpressionChecker() {
|
||||
|
||||
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (!allowedSourceKinds.contains(expression.source?.kind)) return
|
||||
if (expression is FirAnnotationCall) return //checked by FirDeprecatedTypeChecker
|
||||
if (expression is FirAnnotationCall || expression is FirDelegatedConstructorCall) return //checked by FirDeprecatedTypeChecker
|
||||
val resolvable = expression as? FirResolvable ?: return
|
||||
val reference = resolvable.calleeReference as? FirResolvedNamedReference ?: return
|
||||
val referencedSymbol = reference.resolvedSymbol
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.analysis.checkers.expression
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.isArrayType
|
||||
|
||||
object FirNamedVarargChecker : FirCallChecker() {
|
||||
override fun check(expression: FirCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (expression !is FirFunctionCall && expression !is FirAnnotationCall && expression !is FirDelegatedConstructorCall) return
|
||||
val isAnnotation = expression is FirAnnotationCall
|
||||
val errorFactory =
|
||||
if (isAnnotation) FirErrors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION
|
||||
else FirErrors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION
|
||||
|
||||
val allowAssignArray = context.session.languageVersionSettings.supportsFeature(
|
||||
if (isAnnotation) LanguageFeature.AssigningArraysToVarargsInNamedFormInAnnotations
|
||||
else LanguageFeature.AllowAssigningArrayElementsToVarargsInNamedFormForFunctions
|
||||
)
|
||||
|
||||
fun checkArgument(argument: FirExpression) {
|
||||
if (argument !is FirNamedArgumentExpression) return
|
||||
if (argument.isSpread) return
|
||||
val typeRef = argument.expression.typeRef
|
||||
if (typeRef is FirErrorTypeRef) return
|
||||
if (argument.expression is FirArrayOfCall) return
|
||||
if (allowAssignArray && typeRef.isArrayType) return
|
||||
|
||||
reporter.reportOn(argument.expression.source, errorFactory, context)
|
||||
}
|
||||
|
||||
val argumentMap = expression.argumentMapping ?: return
|
||||
for ((argument, parameter) in argumentMap) {
|
||||
if (!parameter.isVararg) continue
|
||||
if (argument is FirVarargArgumentsExpression) {
|
||||
argument.arguments.forEach(::checkArgument)
|
||||
} else {
|
||||
checkArgument(argument)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -38,7 +38,7 @@ object FirSuspendModifierChecker : FirTypeRefChecker() {
|
||||
reporter.reportOn(
|
||||
suspendModifier.source,
|
||||
FirErrors.WRONG_MODIFIER_TARGET,
|
||||
suspendModifier.token.toString(),
|
||||
suspendModifier.token,
|
||||
"non-functional type",
|
||||
context
|
||||
)
|
||||
|
||||
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirExpressionChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkersComponent
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
|
||||
@OptIn(CheckersComponentInternal::class)
|
||||
@@ -137,6 +136,10 @@ class ExpressionCheckersDiagnosticComponent(
|
||||
checkers.allBlockCheckers.check(block, data, reporter)
|
||||
}
|
||||
|
||||
override fun visitDelegatedConstructorCall(delegatedConstructorCall: FirDelegatedConstructorCall, data: CheckerContext) {
|
||||
checkers.allCallCheckers.check(delegatedConstructorCall, data, reporter)
|
||||
}
|
||||
|
||||
private fun <E : FirStatement> Collection<FirExpressionChecker<E>>.check(
|
||||
expression: E,
|
||||
context: CheckerContext,
|
||||
|
||||
@@ -65,6 +65,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARGUMENT_TYPE_MIS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGNED_VALUE_IS_NEVER_READ
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGNMENT_TYPE_MISMATCH
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGN_OPERATOR_AMBIGUITY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BACKING_FIELD_IN_INTERFACE
|
||||
@@ -209,6 +211,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_CAND
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_FILE_TARGET
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_INFIX_MODIFIER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_LATEINIT_MODIFIER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_OPERATOR_MODIFIER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_PARAM_TARGET
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_TARGET_ON_PROPERTY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_TARGET_PROPERTY_HAS_NO_BACKING_FIELD
|
||||
@@ -730,18 +733,19 @@ class FirDefaultErrorMessages {
|
||||
|
||||
// Modifiers
|
||||
map.put(INAPPLICABLE_INFIX_MODIFIER, "''infix'' modifier is inapplicable on this function")
|
||||
map.put(REPEATED_MODIFIER, "Repeated ''{0}''", STRING)
|
||||
map.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", STRING, STRING)
|
||||
map.put(DEPRECATED_MODIFIER, "Modifier ''{0}'' is deprecated, use ''{1}'' instead", STRING, STRING)
|
||||
map.put(DEPRECATED_MODIFIER_PAIR, "Modifier ''{0}'' is deprecated in presence of ''{1}''", STRING, STRING)
|
||||
map.put(DEPRECATED_MODIFIER_FOR_TARGET, "Modifier ''{0}'' is deprecated for ''{1}''", STRING, STRING)
|
||||
map.put(REDUNDANT_MODIFIER_FOR_TARGET, "Modifier ''{0}'' is redundant for ''{1}''", STRING, STRING)
|
||||
map.put(INCOMPATIBLE_MODIFIERS, "Modifier ''{0}'' is incompatible with ''{1}''", STRING, STRING)
|
||||
map.put(REPEATED_MODIFIER, "Repeated ''{0}''", TO_STRING)
|
||||
map.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING)
|
||||
map.put(DEPRECATED_MODIFIER, "Modifier ''{0}'' is deprecated, use ''{1}'' instead", TO_STRING, TO_STRING)
|
||||
map.put(DEPRECATED_MODIFIER_PAIR, "Modifier ''{0}'' is deprecated in presence of ''{1}''", TO_STRING, TO_STRING)
|
||||
map.put(DEPRECATED_MODIFIER_FOR_TARGET, "Modifier ''{0}'' is deprecated for ''{1}''", TO_STRING, STRING)
|
||||
map.put(REDUNDANT_MODIFIER_FOR_TARGET, "Modifier ''{0}'' is redundant for ''{1}''", TO_STRING, STRING)
|
||||
map.put(INCOMPATIBLE_MODIFIERS, "Modifier ''{0}'' is incompatible with ''{1}''", TO_STRING, TO_STRING)
|
||||
map.put(REDUNDANT_OPEN_IN_INTERFACE, "Modifier 'open' is redundant for abstract interface members")
|
||||
map.put(WRONG_MODIFIER_TARGET, "Modifier ''{0}'' is not applicable to ''{1}''", STRING, STRING)
|
||||
map.put(WRONG_MODIFIER_TARGET, "Modifier ''{0}'' is not applicable to ''{1}''", TO_STRING, STRING)
|
||||
map.put(INFIX_MODIFIER_REQUIRED, "''infix'' modifier is required on ''{0}''", TO_STRING)
|
||||
map.put(WRONG_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is not applicable inside ''{1}''", STRING, STRING)
|
||||
map.put(DEPRECATED_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is deprecated inside ''{1}''", STRING, STRING)
|
||||
map.put(WRONG_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is not applicable inside ''{1}''", TO_STRING, STRING)
|
||||
map.put(DEPRECATED_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is deprecated inside ''{1}''", TO_STRING, STRING)
|
||||
map.put(INAPPLICABLE_OPERATOR_MODIFIER, "''operator'' modifier is inapplicable on this function: {0}", STRING)
|
||||
|
||||
// Classes and interfaces
|
||||
map.put(SUPERTYPE_NOT_INITIALIZED, "This type has a constructor, and thus must be initialized here")
|
||||
@@ -759,6 +763,8 @@ class FirDefaultErrorMessages {
|
||||
map.put(NAMED_PARAMETER_NOT_FOUND, "Cannot find a parameter with this name: {0}", TO_STRING)
|
||||
map.put(MANY_LAMBDA_EXPRESSION_ARGUMENTS, "Only one lambda expression is allowed outside a parenthesized argument list")
|
||||
map.put(SPREAD_OF_NULLABLE, "The spread operator (*foo) may not be applied to an argument of nullable type")
|
||||
map.put(ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION, "Assigning single elements to varargs in named form is forbidden")
|
||||
map.put(ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION, "Assigning single elements to varargs in named form is forbidden")
|
||||
|
||||
map.put(TYPE_MISMATCH, "Type mismatch: inferred type is {1} but {0} was expected", TO_STRING, TO_STRING)
|
||||
map.put(THROWABLE_TYPE_MISMATCH, "Throwable type mismatch: actual type is {0}", TO_STRING)
|
||||
|
||||
@@ -373,6 +373,9 @@ object LightTreePositioningStrategies {
|
||||
val DATA_MODIFIER: LightTreePositioningStrategy =
|
||||
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.DATA_KEYWORD))
|
||||
|
||||
val OPERATOR_MODIFIER: LightTreePositioningStrategy =
|
||||
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.OPERATOR_KEYWORD))
|
||||
|
||||
val INLINE_PARAMETER_MODIFIER: LightTreePositioningStrategy =
|
||||
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.NOINLINE_KEYWORD, KtTokens.CROSSINLINE_KEYWORD))
|
||||
|
||||
|
||||
@@ -304,4 +304,9 @@ object SourceElementPositioningStrategies {
|
||||
LightTreePositioningStrategies.INLINE_PARAMETER_MODIFIER,
|
||||
PositioningStrategies.INLINE_PARAMETER_MODIFIER
|
||||
)
|
||||
|
||||
val OPERATOR_MODIFIER = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.OPERATOR_MODIFIER,
|
||||
PositioningStrategies.OPERATOR_MODIFIER
|
||||
)
|
||||
}
|
||||
|
||||
@@ -212,11 +212,10 @@ data class ConeCapturedType(
|
||||
|
||||
data class ConeTypeVariableType(
|
||||
override val nullability: ConeNullability,
|
||||
override val lookupTag: ConeClassifierLookupTag
|
||||
override val lookupTag: ConeClassifierLookupTag,
|
||||
override val attributes: ConeAttributes = ConeAttributes.Empty,
|
||||
) : ConeLookupTagBasedType() {
|
||||
override val typeArguments: Array<out ConeTypeProjection> get() = emptyArray()
|
||||
|
||||
override val attributes: ConeAttributes get() = ConeAttributes.Empty
|
||||
}
|
||||
|
||||
data class ConeDefinitelyNotNullType(val original: ConeKotlinType) : ConeSimpleKotlinType(), DefinitelyNotNullTypeMarker {
|
||||
@@ -227,7 +226,7 @@ data class ConeDefinitelyNotNullType(val original: ConeKotlinType) : ConeSimpleK
|
||||
get() = ConeNullability.NOT_NULL
|
||||
|
||||
override val attributes: ConeAttributes
|
||||
get() = ConeAttributes.Empty
|
||||
get() = original.attributes
|
||||
|
||||
companion object
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ class Fir2IrVisitor(
|
||||
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): IrElement {
|
||||
val irFunction = if (simpleFunction.visibility == Visibilities.Local) {
|
||||
declarationStorage.createIrFunction(
|
||||
simpleFunction, irParent = conversionScope.parent(), isLocal = true
|
||||
simpleFunction, irParent = conversionScope.parent(), origin = IrDeclarationOrigin.LOCAL_FUNCTION, isLocal = true
|
||||
)
|
||||
} else {
|
||||
declarationStorage.getCachedIrFunction(simpleFunction)!!
|
||||
@@ -236,7 +236,7 @@ class Fir2IrVisitor(
|
||||
override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: Any?): IrElement {
|
||||
return anonymousFunction.convertWithOffsets { startOffset, endOffset ->
|
||||
val irFunction = declarationStorage.createIrFunction(
|
||||
anonymousFunction, irParent = conversionScope.parent(), isLocal = true
|
||||
anonymousFunction, irParent = conversionScope.parent(), origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA, isLocal = true
|
||||
)
|
||||
conversionScope.withFunction(irFunction) {
|
||||
memberGenerator.convertFunctionContent(irFunction, anonymousFunction, containingClass = null)
|
||||
|
||||
@@ -505,10 +505,15 @@ class CallAndReferenceGenerator(
|
||||
return applyArgumentsWithReorderingIfNeeded(argumentMapping, valueParameters, substitutor, annotationMode)
|
||||
}
|
||||
}
|
||||
// Case without argument mapping (deserialized annotation)
|
||||
// TODO: support argument mapping in deserialized annotations and remove me
|
||||
for ((index, argument) in call.arguments.withIndex()) {
|
||||
val valueParameter = valueParameters?.get(index)
|
||||
val valueParameter = when (argument) {
|
||||
is FirNamedArgumentExpression -> valueParameters?.find { it.name == argument.name }
|
||||
else -> null
|
||||
} ?: valueParameters?.get(index)
|
||||
val argumentExpression = convertArgument(argument, valueParameter, substitutor)
|
||||
putValueArgument(index, argumentExpression)
|
||||
putValueArgument(valueParameters?.indexOf(valueParameter)?.takeIf { it >= 0 } ?: index, argumentExpression)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -2390,6 +2390,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/builtinStubMethods/inheritedImplementations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("int2IntMap.kt")
|
||||
public void testInt2IntMap() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/builtinStubMethods/int2IntMap.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Iterator.kt")
|
||||
public void testIterator() throws Exception {
|
||||
@@ -41754,6 +41760,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/syntheticExtensions"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("firstCapitalizedProperty.kt")
|
||||
public void testFirstCapitalizedProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/syntheticExtensions/firstCapitalizedProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("fromTwoBases.kt")
|
||||
public void testFromTwoBases() throws Exception {
|
||||
|
||||
@@ -1318,6 +1318,18 @@ public class FirBlackBoxInlineCodegenTestGenerated extends AbstractFirBlackBoxIn
|
||||
runTest("compiler/testData/codegen/boxInline/capture/generics.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt48230.kt")
|
||||
public void testKt48230() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/capture/kt48230.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt48230_2.kt")
|
||||
public void testKt48230_2() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/capture/kt48230_2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simpleCapturingInClass.kt")
|
||||
public void testSimpleCapturingInClass() throws Exception {
|
||||
|
||||
@@ -66,11 +66,22 @@ class JavaOverrideChecker internal constructor(
|
||||
candidateTypeRef: FirTypeRef,
|
||||
baseTypeRef: FirTypeRef,
|
||||
substitutor: ConeSubstitutor
|
||||
) = isEqualTypes(
|
||||
candidateTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack),
|
||||
baseTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack),
|
||||
substitutor
|
||||
)
|
||||
): Boolean {
|
||||
val candidateType = candidateTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack)
|
||||
val baseType = baseTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack)
|
||||
|
||||
if (candidateType.isPrimitiveInJava() != baseType.isPrimitiveInJava()) return false
|
||||
|
||||
return isEqualTypes(
|
||||
candidateType,
|
||||
baseType,
|
||||
substitutor
|
||||
)
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.isPrimitiveInJava(): Boolean = with(context) {
|
||||
!isNullableType() && CompilerConeAttributes.EnhancedNullability !in attributes && isPrimitiveOrNullablePrimitive
|
||||
}
|
||||
|
||||
private fun isEqualArrayElementTypeProjections(
|
||||
candidateTypeProjection: ConeTypeProjection,
|
||||
|
||||
@@ -28,6 +28,8 @@ object FirJavaSyntheticNamesProvider : FirSyntheticNamesProvider() {
|
||||
if (name.isSpecial) return emptyList()
|
||||
val identifier = name.identifier
|
||||
if (identifier.isEmpty()) return emptyList()
|
||||
val firstChar = identifier[0]
|
||||
if (!firstChar.isJavaIdentifierStart() || firstChar in 'A'..'Z') return emptyList()
|
||||
val result = ArrayList<Name>(3)
|
||||
val standardName = Name.identifier(GETTER_PREFIX + identifier.capitalizeAsciiOnly())
|
||||
val length = identifier.length
|
||||
|
||||
@@ -15,6 +15,8 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.originalIfFakeOverride
|
||||
import org.jetbrains.kotlin.fir.originalOrSelf
|
||||
import org.jetbrains.kotlin.fir.references.FirThisReference
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
@@ -184,7 +186,7 @@ class VariableStorage(private val session: FirSession) {
|
||||
property.isVar -> PropertyStability.MUTABLE_PROPERTY
|
||||
property.receiverTypeRef != null -> PropertyStability.PROPERTY_WITH_GETTER
|
||||
property.getter.let { it != null && it !is FirDefaultPropertyAccessor } -> PropertyStability.PROPERTY_WITH_GETTER
|
||||
property.moduleData.session != session -> PropertyStability.ALIEN_PUBLIC_PROPERTY
|
||||
property.originalOrSelf().moduleData.session != session -> PropertyStability.ALIEN_PUBLIC_PROPERTY
|
||||
property.modality != Modality.FINAL -> {
|
||||
val dispatchReceiver = (originalFir.unwrapElement() as? FirQualifiedAccess)?.dispatchReceiver ?: return null
|
||||
val receiverType = dispatchReceiver.typeRef.coneTypeSafe<ConeClassLikeType>()?.fullyExpandedType(session) ?: return null
|
||||
|
||||
@@ -84,7 +84,10 @@ abstract class AbstractConeSubstitutor(private val typeContext: ConeTypeContext)
|
||||
}
|
||||
|
||||
private fun ConeDefinitelyNotNullType.substituteOriginal(): ConeKotlinType? {
|
||||
val substituted = substituteOrNull(original)?.withNullability(ConeNullability.NOT_NULL, typeContext) ?: return null
|
||||
val substituted = substituteOrNull(original)
|
||||
?.withNullability(ConeNullability.NOT_NULL, typeContext)
|
||||
?.withAttributes(original.attributes, typeContext)
|
||||
?: return null
|
||||
return ConeDefinitelyNotNullType.create(substituted, typeContext) ?: substituted
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
@@ -110,6 +110,13 @@ fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes, typeSystem
|
||||
lowerBound.withAttributes(attributes, typeSystemContext),
|
||||
upperBound.withAttributes(attributes, typeSystemContext)
|
||||
)
|
||||
is ConeTypeVariableType -> ConeTypeVariableType(nullability, lookupTag, attributes)
|
||||
is ConeCapturedType -> ConeCapturedType(
|
||||
captureStatus, lowerType, nullability, constructor, attributes, isProjectionNotNull,
|
||||
)
|
||||
// TODO: Consider correct application of attributes to ConeIntersectionType
|
||||
// Currently, ConeAttributes.union works a bit strange, because it lefts only `other` parts
|
||||
is ConeIntersectionType -> this
|
||||
else -> error("Not supported: $this: ${this.render()}")
|
||||
} as T
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ val FirTypeRef.isNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing
|
||||
val FirTypeRef.isNullableNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, true)
|
||||
val FirTypeRef.isUnit: Boolean get() = isBuiltinType(StandardClassIds.Unit, false)
|
||||
val FirTypeRef.isBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, false)
|
||||
val FirTypeRef.isInt: Boolean get() = isBuiltinType(StandardClassIds.Int, false)
|
||||
val FirTypeRef.isEnum: Boolean get() = isBuiltinType(StandardClassIds.Enum, false)
|
||||
val FirTypeRef.isArrayType: Boolean
|
||||
get() =
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.FqNames
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
object ArrayFqNames {
|
||||
@@ -20,5 +22,20 @@ object ArrayFqNames {
|
||||
PrimitiveType.DOUBLE to Name.identifier("doubleArrayOf")
|
||||
)
|
||||
|
||||
val ARRAY_OF_FUNCTION = Name.identifier("arrayOf")
|
||||
}
|
||||
val UNSIGNED_TYPE_TO_ARRAY: Map<FqName, Name> = hashMapOf(
|
||||
FqNames.uByteFqName to Name.identifier("ubyteArrayOf"),
|
||||
FqNames.uShortFqName to Name.identifier("ushortArrayOf"),
|
||||
FqNames.uIntFqName to Name.identifier("uintArrayOf"),
|
||||
FqNames.uLongFqName to Name.identifier("ulongArrayOf")
|
||||
)
|
||||
|
||||
val ARRAY_OF_FUNCTION: Name = Name.identifier("arrayOf")
|
||||
|
||||
val EMPTY_ARRAY: Name = Name.identifier("emptyArray")
|
||||
|
||||
val ARRAY_CALL_NAMES: Set<Name> =
|
||||
setOf(ARRAY_OF_FUNCTION, EMPTY_ARRAY) + PRIMITIVE_TYPE_TO_ARRAY.values.toSet() + UNSIGNED_TYPE_TO_ARRAY.values.toSet()
|
||||
|
||||
@JvmField
|
||||
val ARRAY_CALL_FQ_NAMES: Set<FqName> = ARRAY_CALL_NAMES.map { FqName("kotlin." + it.identifier) }.toSet()
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ public interface Errors {
|
||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, KtModifierKeywordToken> REDUNDANT_MODIFIER = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> WRONG_MODIFIER_TARGET = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> DEPRECATED_MODIFIER_FOR_TARGET = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> DEPRECATED_MODIFIER = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, KtModifierKeywordToken> DEPRECATED_MODIFIER = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> REDUNDANT_MODIFIER_FOR_TARGET = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory0<KtDeclaration> NO_EXPLICIT_VISIBILITY_IN_API_MODE = DiagnosticFactory0.create(ERROR, DECLARATION_START_TO_NAME);
|
||||
DiagnosticFactory0<KtNamedDeclaration> NO_EXPLICIT_RETURN_TYPE_IN_API_MODE = DiagnosticFactory0.create(ERROR, DECLARATION_NAME);
|
||||
|
||||
@@ -377,6 +377,9 @@ object PositioningStrategies {
|
||||
@JvmField
|
||||
val DATA_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.DATA_KEYWORD)
|
||||
|
||||
@JvmField
|
||||
val OPERATOR_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.OPERATOR_KEYWORD)
|
||||
|
||||
@JvmField
|
||||
val FOR_REDECLARATION: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
|
||||
override fun mark(element: PsiElement): List<TextRange> {
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve;
|
||||
|
||||
import kotlin.collections.SetsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.psi.KtParameter;
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil;
|
||||
@@ -39,33 +39,16 @@ import org.jetbrains.kotlin.types.TypeProjection;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.INVALID_TYPE_OF_ANNOTATION_MEMBER;
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER;
|
||||
import static org.jetbrains.kotlin.resolve.ArrayFqNames.ARRAY_CALL_FQ_NAMES;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.VALUE_PARAMETER;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isAnnotationClass;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumClass;
|
||||
|
||||
public class CompileTimeConstantUtils {
|
||||
|
||||
private final static Set<String> ARRAY_CALL_NAMES = SetsKt.hashSetOf(
|
||||
"kotlin.arrayOf",
|
||||
"kotlin.doubleArrayOf",
|
||||
"kotlin.floatArrayOf",
|
||||
"kotlin.longArrayOf",
|
||||
"kotlin.intArrayOf",
|
||||
"kotlin.charArrayOf",
|
||||
"kotlin.shortArrayOf",
|
||||
"kotlin.byteArrayOf",
|
||||
"kotlin.booleanArrayOf",
|
||||
"kotlin.emptyArray",
|
||||
"kotlin.ubyteArrayOf",
|
||||
"kotlin.ushortArrayOf",
|
||||
"kotlin.uintArrayOf",
|
||||
"kotlin.ulongArrayOf"
|
||||
);
|
||||
|
||||
public static void checkConstructorParametersType(@NotNull List<KtParameter> parameters, @NotNull BindingTrace trace) {
|
||||
for (KtParameter parameter : parameters) {
|
||||
VariableDescriptor parameterDescriptor = trace.getBindingContext().get(VALUE_PARAMETER, parameter);
|
||||
@@ -121,7 +104,10 @@ public class CompileTimeConstantUtils {
|
||||
}
|
||||
|
||||
public static boolean isArrayFunctionCall(@NotNull ResolvedCall<?> resolvedCall) {
|
||||
return ARRAY_CALL_NAMES.contains(DescriptorUtils.getFqName(resolvedCall.getCandidateDescriptor()).asString());
|
||||
FqNameUnsafe unsafe = DescriptorUtils.getFqName(resolvedCall.getCandidateDescriptor());
|
||||
// If the fully qualified name is unsafe, i.e., contains < or >, it shouldn't be any of `arrayOf` calls.
|
||||
if (!unsafe.isSafe()) return false;
|
||||
return ARRAY_CALL_FQ_NAMES.contains(unsafe.toSafe());
|
||||
}
|
||||
|
||||
public static boolean canBeReducedToBooleanConstant(
|
||||
|
||||
@@ -13,55 +13,15 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
|
||||
import org.jetbrains.kotlin.psi.KtModifierList
|
||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||
import org.jetbrains.kotlin.resolve.KeywordType.*
|
||||
import org.jetbrains.kotlin.resolve.KeywordType.Annotation
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.checkCoroutinesFeature
|
||||
|
||||
object ModifierCheckerCore {
|
||||
private val ktKeywordToKeywordTypeMap: Map<KtKeywordToken, KeywordType> = mapOf(
|
||||
INNER_KEYWORD to Inner,
|
||||
OVERRIDE_KEYWORD to Override,
|
||||
PUBLIC_KEYWORD to Public,
|
||||
PROTECTED_KEYWORD to Protected,
|
||||
INTERNAL_KEYWORD to Internal,
|
||||
PRIVATE_KEYWORD to Private,
|
||||
COMPANION_KEYWORD to KeywordType.Companion,
|
||||
FINAL_KEYWORD to Final,
|
||||
VARARG_KEYWORD to Vararg,
|
||||
ENUM_KEYWORD to KeywordType.Enum,
|
||||
ABSTRACT_KEYWORD to Abstract,
|
||||
OPEN_KEYWORD to Open,
|
||||
SEALED_KEYWORD to Sealed,
|
||||
IN_KEYWORD to In,
|
||||
OUT_KEYWORD to Out,
|
||||
REIFIED_KEYWORD to Reified,
|
||||
LATEINIT_KEYWORD to Lateinit,
|
||||
DATA_KEYWORD to Data,
|
||||
INLINE_KEYWORD to Inline,
|
||||
NOINLINE_KEYWORD to Noinline,
|
||||
TAILREC_KEYWORD to Tailrec,
|
||||
SUSPEND_KEYWORD to Suspend,
|
||||
EXTERNAL_KEYWORD to External,
|
||||
ANNOTATION_KEYWORD to Annotation,
|
||||
CROSSINLINE_KEYWORD to Crossinline,
|
||||
CONST_KEYWORD to Const,
|
||||
OPERATOR_KEYWORD to Operator,
|
||||
INFIX_KEYWORD to Infix,
|
||||
HEADER_KEYWORD to Header,
|
||||
IMPL_KEYWORD to Impl,
|
||||
EXPECT_KEYWORD to Expect,
|
||||
ACTUAL_KEYWORD to Actual,
|
||||
FUN_KEYWORD to Fun,
|
||||
VALUE_KEYWORD to Value
|
||||
)
|
||||
|
||||
fun check(
|
||||
listOwner: KtModifierListOwner,
|
||||
trace: BindingTrace,
|
||||
@@ -123,10 +83,9 @@ object ModifierCheckerCore {
|
||||
owner: PsiElement,
|
||||
incorrectNodes: MutableSet<ASTNode>
|
||||
) {
|
||||
val (firstModifier, firstModifierType) = getModifierAndModifierType(firstNode)
|
||||
val (secondModifier, secondModifierType) = getModifierAndModifierType(secondNode)
|
||||
|
||||
when (val compatibility = compatibility(firstModifierType, secondModifierType)) {
|
||||
val firstModifier = firstNode.elementType as KtModifierKeywordToken
|
||||
val secondModifier = secondNode.elementType as KtModifierKeywordToken
|
||||
when (val compatibility = compatibility(firstModifier, secondModifier)) {
|
||||
Compatibility.COMPATIBLE -> {
|
||||
}
|
||||
Compatibility.REPEATED -> if (incorrectNodes.add(secondNode)) {
|
||||
@@ -156,19 +115,19 @@ object ModifierCheckerCore {
|
||||
|
||||
// Should return false if error is reported, true otherwise
|
||||
private fun checkTarget(trace: BindingTrace, node: ASTNode, actualTargets: List<KotlinTarget>): Boolean {
|
||||
val (modifier, modifierType) = getModifierAndModifierType(node)
|
||||
val modifier = node.elementType as KtModifierKeywordToken
|
||||
|
||||
val possibleTargets = possibleTargetMap[modifierType] ?: emptySet()
|
||||
val possibleTargets = possibleTargetMap[modifier] ?: emptySet()
|
||||
if (!actualTargets.any { it in possibleTargets }) {
|
||||
trace.report(Errors.WRONG_MODIFIER_TARGET.on(node.psi, modifier, actualTargets.firstOrNull()?.description ?: "this"))
|
||||
return false
|
||||
}
|
||||
val deprecatedModifierReplacement = deprecatedModifierMap[modifierType]
|
||||
val deprecatedTargets = deprecatedTargetMap[modifierType] ?: emptySet()
|
||||
val redundantTargets = redundantTargetMap[modifierType] ?: emptySet()
|
||||
val deprecatedModifierReplacement = deprecatedModifierMap[modifier]
|
||||
val deprecatedTargets = deprecatedTargetMap[modifier] ?: emptySet()
|
||||
val redundantTargets = redundantTargetMap[modifier] ?: emptySet()
|
||||
when {
|
||||
deprecatedModifierReplacement != null ->
|
||||
trace.report(Errors.DEPRECATED_MODIFIER.on(node.psi, modifier, deprecatedModifierReplacement.render()))
|
||||
trace.report(Errors.DEPRECATED_MODIFIER.on(node.psi, modifier, deprecatedModifierReplacement))
|
||||
actualTargets.any { it in deprecatedTargets } ->
|
||||
trace.report(
|
||||
Errors.DEPRECATED_MODIFIER_FOR_TARGET.on(
|
||||
@@ -196,7 +155,7 @@ object ModifierCheckerCore {
|
||||
parentDescriptor: DeclarationDescriptor?,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
): Boolean {
|
||||
val (modifier, modifierType) = getModifierAndModifierType(node)
|
||||
val modifier = node.elementType as KtModifierKeywordToken
|
||||
|
||||
val actualParents: List<KotlinTarget> = when (parentDescriptor) {
|
||||
is ClassDescriptor -> KotlinTarget.classActualTargets(
|
||||
@@ -210,7 +169,7 @@ object ModifierCheckerCore {
|
||||
is FunctionDescriptor -> KotlinTarget.FUNCTION_LIST
|
||||
else -> KotlinTarget.FILE_LIST
|
||||
}
|
||||
val deprecatedParents = deprecatedParentTargetMap[modifierType]
|
||||
val deprecatedParents = deprecatedParentTargetMap[modifier]
|
||||
if (deprecatedParents != null && actualParents.any { it in deprecatedParents }) {
|
||||
trace.report(
|
||||
Errors.DEPRECATED_MODIFIER_CONTAINING_DECLARATION.on(
|
||||
@@ -221,7 +180,7 @@ object ModifierCheckerCore {
|
||||
)
|
||||
return true
|
||||
}
|
||||
val possibleParentPredicate = possibleParentTargetPredicateMap[modifierType] ?: return true
|
||||
val possibleParentPredicate = possibleParentTargetPredicateMap[modifier] ?: return true
|
||||
if (actualParents.any { possibleParentPredicate.isAllowed(it, languageVersionSettings) }) return true
|
||||
trace.report(
|
||||
Errors.WRONG_MODIFIER_CONTAINING_DECLARATION.on(
|
||||
@@ -239,9 +198,9 @@ object ModifierCheckerCore {
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
actualTargets: List<KotlinTarget>
|
||||
): Boolean {
|
||||
val (_, modifierType) = getModifierAndModifierType(node)
|
||||
val modifier = node.elementType as KtModifierKeywordToken
|
||||
|
||||
val dependencies = featureDependencies[modifierType] ?: return true
|
||||
val dependencies = featureDependencies[modifier] ?: return true
|
||||
for (dependency in dependencies) {
|
||||
val restrictedTargets = featureDependenciesTargets[dependency]
|
||||
if (restrictedTargets != null && actualTargets.intersect(restrictedTargets).isEmpty()) {
|
||||
@@ -282,9 +241,4 @@ object ModifierCheckerCore {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun getModifierAndModifierType(node: ASTNode): Pair<KtModifierKeywordToken, KeywordType> {
|
||||
val modifier = node.elementType as KtModifierKeywordToken
|
||||
return Pair(modifier, ktKeywordToKeywordTypeMap[modifier]!!)
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass {
|
||||
|
||||
private val removedFunctions = hashMapOf<IrSimpleFunctionSymbol, IrSimpleFunctionSymbol>()
|
||||
private val removedFunctionsWithoutRemapping = mutableSetOf<IrSimpleFunctionSymbol>()
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
if (!irClass.isJvmInterface) return
|
||||
@@ -50,7 +51,7 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran
|
||||
}
|
||||
|
||||
irClass.declarations.removeAll {
|
||||
it is IrFunction && removedFunctions.containsKey(it.symbol)
|
||||
it is IrFunction && (removedFunctions.containsKey(it.symbol) || removedFunctionsWithoutRemapping.contains(it.symbol))
|
||||
}
|
||||
|
||||
val defaultImplsIrClass = context.cachedDeclarations.getDefaultImplsClass(irClass)
|
||||
@@ -131,9 +132,17 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran
|
||||
(function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS &&
|
||||
(isCompatibilityMode || jvmDefaultMode == JvmDefaultMode.ENABLE) &&
|
||||
function.isCompiledToJvmDefault(jvmDefaultMode)) -> {
|
||||
val defaultImpl = createDefaultImpl(function)
|
||||
defaultImpl.body = function.moveBodyTo(defaultImpl)
|
||||
removedFunctions[function.symbol] = defaultImpl.symbol
|
||||
if (function.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA || function.origin == IrDeclarationOrigin.LOCAL_FUNCTION) {
|
||||
//move as is
|
||||
val defaultImplsClass = context.cachedDeclarations.getDefaultImplsClass(irClass)
|
||||
defaultImplsClass.declarations.add(function)
|
||||
removedFunctionsWithoutRemapping.add(function.symbol)
|
||||
function.parent = defaultImplsClass
|
||||
} else {
|
||||
val defaultImpl = createDefaultImpl(function)
|
||||
defaultImpl.body = function.moveBodyTo(defaultImpl)
|
||||
removedFunctions[function.symbol] = defaultImpl.symbol
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,11 +39,15 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
|
||||
constructor(context: GeneratorContext) : this(DeclarationGenerator(context))
|
||||
|
||||
fun generateFunctionDeclaration(ktFunction: KtNamedFunction): IrSimpleFunction =
|
||||
@JvmOverloads
|
||||
fun generateFunctionDeclaration(
|
||||
ktFunction: KtNamedFunction,
|
||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED
|
||||
): IrSimpleFunction =
|
||||
declareSimpleFunction(
|
||||
ktFunction,
|
||||
ktFunction.receiverTypeReference,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
origin,
|
||||
getOrFail(BindingContext.FUNCTION, ktFunction)
|
||||
) {
|
||||
ktFunction.bodyExpression?.let { generateFunctionBody(it) }
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionExpressionImpl
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
@@ -53,5 +54,5 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
|
||||
}
|
||||
|
||||
private fun generateFunctionDeclaration(ktFun: KtNamedFunction) =
|
||||
FunctionGenerator(context).generateFunctionDeclaration(ktFun)
|
||||
FunctionGenerator(context).generateFunctionDeclaration(ktFun, IrDeclarationOrigin.LOCAL_FUNCTION)
|
||||
}
|
||||
@@ -49,6 +49,7 @@ interface IrDeclarationOrigin {
|
||||
object SCRIPT_RESULT_PROPERTY : IrDeclarationOriginImpl("SCRIPT_RESULT_PROPERTY")
|
||||
object GENERATED_DATA_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_DATA_CLASS_MEMBER")
|
||||
object GENERATED_INLINE_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_INLINE_CLASS_MEMBER")
|
||||
object LOCAL_FUNCTION : IrDeclarationOriginImpl("LOCAL_FUNCTION")
|
||||
object LOCAL_FUNCTION_FOR_LAMBDA : IrDeclarationOriginImpl("LOCAL_FUNCTION_FOR_LAMBDA")
|
||||
object CATCH_PARAMETER : IrDeclarationOriginImpl("CATCH_PARAMETER")
|
||||
object INSTANCE_RECEIVER : IrDeclarationOriginImpl("INSTANCE_RECEIVER")
|
||||
|
||||
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* 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.resolve
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
import java.util.*
|
||||
|
||||
enum class Compatibility {
|
||||
// modifier pair is compatible: ok (default)
|
||||
COMPATIBLE,
|
||||
|
||||
// second is redundant to first: warning
|
||||
REDUNDANT,
|
||||
|
||||
// first is redundant to second: warning
|
||||
REVERSE_REDUNDANT,
|
||||
|
||||
// error
|
||||
REPEATED,
|
||||
|
||||
// pair is deprecated, will become incompatible: warning
|
||||
DEPRECATED,
|
||||
|
||||
// pair is incompatible: error
|
||||
INCOMPATIBLE,
|
||||
|
||||
// same but only for functions / properties: error
|
||||
COMPATIBLE_FOR_CLASSES_ONLY
|
||||
}
|
||||
|
||||
val compatibilityTypeMap = hashMapOf<Pair<KtKeywordToken, KtKeywordToken>, Compatibility>()
|
||||
|
||||
fun compatibility(first: KtKeywordToken, second: KtKeywordToken): Compatibility {
|
||||
return if (first == second) {
|
||||
Compatibility.REPEATED
|
||||
} else {
|
||||
mutualCompatibility[Pair(first, second)] ?: Compatibility.COMPATIBLE
|
||||
}
|
||||
}
|
||||
|
||||
// First modifier in pair should be also first in declaration
|
||||
private val mutualCompatibility = buildCompatibilityMap()
|
||||
|
||||
private fun buildCompatibilityMap(): Map<Pair<KtKeywordToken, KtKeywordToken>, Compatibility> {
|
||||
val result = hashMapOf<Pair<KtKeywordToken, KtKeywordToken>, Compatibility>()
|
||||
// Variance: in + out are incompatible
|
||||
result += incompatibilityRegister(IN_KEYWORD, OUT_KEYWORD)
|
||||
// Visibilities: incompatible
|
||||
result += incompatibilityRegister(PRIVATE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD)
|
||||
// Abstract + open + final + sealed: incompatible
|
||||
result += incompatibilityRegister(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD, SEALED_KEYWORD)
|
||||
// data + open, data + inner, data + abstract, data + sealed, data + inline, data + value
|
||||
result += incompatibilityRegister(DATA_KEYWORD, OPEN_KEYWORD)
|
||||
result += incompatibilityRegister(DATA_KEYWORD, INNER_KEYWORD)
|
||||
result += incompatibilityRegister(DATA_KEYWORD, ABSTRACT_KEYWORD)
|
||||
result += incompatibilityRegister(DATA_KEYWORD, SEALED_KEYWORD)
|
||||
result += incompatibilityRegister(DATA_KEYWORD, INLINE_KEYWORD)
|
||||
result += incompatibilityRegister(DATA_KEYWORD, VALUE_KEYWORD)
|
||||
// open is redundant to abstract & override
|
||||
result += redundantRegister(ABSTRACT_KEYWORD, OPEN_KEYWORD)
|
||||
// abstract is redundant to sealed
|
||||
result += redundantRegister(SEALED_KEYWORD, ABSTRACT_KEYWORD)
|
||||
|
||||
// const is incompatible with abstract, open, override
|
||||
result += incompatibilityRegister(CONST_KEYWORD, ABSTRACT_KEYWORD)
|
||||
result += incompatibilityRegister(CONST_KEYWORD, OPEN_KEYWORD)
|
||||
result += incompatibilityRegister(CONST_KEYWORD, OVERRIDE_KEYWORD)
|
||||
|
||||
// private is incompatible with override
|
||||
result += incompatibilityRegister(PRIVATE_KEYWORD, OVERRIDE_KEYWORD)
|
||||
// private is compatible with open / abstract only for classes
|
||||
result += compatibilityForClassesRegister(PRIVATE_KEYWORD, OPEN_KEYWORD)
|
||||
result += compatibilityForClassesRegister(PRIVATE_KEYWORD, ABSTRACT_KEYWORD)
|
||||
|
||||
result += incompatibilityRegister(CROSSINLINE_KEYWORD, NOINLINE_KEYWORD)
|
||||
|
||||
// 1. subclasses contained inside a sealed class can not be instantiated, because their constructors needs
|
||||
// an instance of an outer sealed (effectively abstract) class
|
||||
// 2. subclasses of a non-top-level sealed class must be declared inside the class
|
||||
// (see the KEEP https://github.com/Kotlin/KEEP/blob/master/proposals/sealed-class-inheritance.md)
|
||||
result += incompatibilityRegister(SEALED_KEYWORD, INNER_KEYWORD)
|
||||
|
||||
// header / expect / impl / actual are all incompatible
|
||||
result += incompatibilityRegister(HEADER_KEYWORD, EXPECT_KEYWORD, IMPL_KEYWORD, ACTUAL_KEYWORD)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun incompatibilityRegister(vararg list: KtKeywordToken): Map<Pair<KtKeywordToken, KtKeywordToken>, Compatibility> {
|
||||
return compatibilityRegister(Compatibility.INCOMPATIBLE, *list)
|
||||
}
|
||||
|
||||
private fun redundantRegister(
|
||||
sufficient: KtKeywordToken,
|
||||
redundant: KtKeywordToken
|
||||
): Map<Pair<KtKeywordToken, KtKeywordToken>, Compatibility> {
|
||||
return mapOf(
|
||||
Pair(sufficient, redundant) to Compatibility.REDUNDANT,
|
||||
Pair(redundant, sufficient) to Compatibility.REVERSE_REDUNDANT
|
||||
)
|
||||
}
|
||||
|
||||
private fun compatibilityForClassesRegister(vararg list: KtKeywordToken) =
|
||||
compatibilityRegister(Compatibility.COMPATIBLE_FOR_CLASSES_ONLY, *list)
|
||||
|
||||
private fun compatibilityRegister(
|
||||
compatibility: Compatibility, vararg list: KtKeywordToken
|
||||
): Map<Pair<KtKeywordToken, KtKeywordToken>, Compatibility> {
|
||||
val result = hashMapOf<Pair<KtKeywordToken, KtKeywordToken>, Compatibility>()
|
||||
for (first in list) {
|
||||
for (second in list) {
|
||||
if (first != second) {
|
||||
result[Pair(first, second)] = compatibility
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
val featureDependencies = mapOf(
|
||||
SUSPEND_KEYWORD to listOf(LanguageFeature.Coroutines),
|
||||
INLINE_KEYWORD to listOf(LanguageFeature.InlineProperties, LanguageFeature.InlineClasses),
|
||||
HEADER_KEYWORD to listOf(LanguageFeature.MultiPlatformProjects),
|
||||
IMPL_KEYWORD to listOf(LanguageFeature.MultiPlatformProjects),
|
||||
EXPECT_KEYWORD to listOf(LanguageFeature.MultiPlatformProjects),
|
||||
ACTUAL_KEYWORD to listOf(LanguageFeature.MultiPlatformProjects),
|
||||
LATEINIT_KEYWORD to listOf(LanguageFeature.LateinitTopLevelProperties, LanguageFeature.LateinitLocalVariables),
|
||||
FUN_KEYWORD to listOf(LanguageFeature.FunctionalInterfaceConversion)
|
||||
)
|
||||
|
||||
val featureDependenciesTargets = mapOf(
|
||||
LanguageFeature.InlineProperties to setOf(KotlinTarget.PROPERTY, KotlinTarget.PROPERTY_GETTER, KotlinTarget.PROPERTY_SETTER),
|
||||
LanguageFeature.LateinitLocalVariables to setOf(KotlinTarget.LOCAL_VARIABLE),
|
||||
LanguageFeature.LateinitTopLevelProperties to setOf(KotlinTarget.TOP_LEVEL_PROPERTY),
|
||||
LanguageFeature.InlineClasses to setOf(KotlinTarget.CLASS_ONLY),
|
||||
LanguageFeature.JvmInlineValueClasses to setOf(KotlinTarget.CLASS_ONLY),
|
||||
LanguageFeature.FunctionalInterfaceConversion to setOf(KotlinTarget.INTERFACE)
|
||||
)
|
||||
|
||||
val defaultVisibilityTargets: EnumSet<KotlinTarget> = EnumSet.of(
|
||||
KotlinTarget.CLASS_ONLY, KotlinTarget.OBJECT, KotlinTarget.INTERFACE, KotlinTarget.ENUM_CLASS, KotlinTarget.ANNOTATION_CLASS,
|
||||
KotlinTarget.MEMBER_FUNCTION, KotlinTarget.TOP_LEVEL_FUNCTION, KotlinTarget.PROPERTY_GETTER, KotlinTarget.PROPERTY_SETTER,
|
||||
KotlinTarget.MEMBER_PROPERTY, KotlinTarget.TOP_LEVEL_PROPERTY, KotlinTarget.CONSTRUCTOR, KotlinTarget.TYPEALIAS
|
||||
)
|
||||
|
||||
val possibleTargetMap = mapOf(
|
||||
ENUM_KEYWORD to EnumSet.of(KotlinTarget.ENUM_CLASS),
|
||||
ABSTRACT_KEYWORD to EnumSet.of(
|
||||
KotlinTarget.CLASS_ONLY,
|
||||
KotlinTarget.LOCAL_CLASS,
|
||||
KotlinTarget.INTERFACE,
|
||||
KotlinTarget.MEMBER_PROPERTY,
|
||||
KotlinTarget.MEMBER_FUNCTION
|
||||
),
|
||||
OPEN_KEYWORD to EnumSet.of(
|
||||
KotlinTarget.CLASS_ONLY,
|
||||
KotlinTarget.LOCAL_CLASS,
|
||||
KotlinTarget.INTERFACE,
|
||||
KotlinTarget.MEMBER_PROPERTY,
|
||||
KotlinTarget.MEMBER_FUNCTION
|
||||
),
|
||||
FINAL_KEYWORD to EnumSet.of(
|
||||
KotlinTarget.CLASS_ONLY,
|
||||
KotlinTarget.LOCAL_CLASS,
|
||||
KotlinTarget.ENUM_CLASS,
|
||||
KotlinTarget.OBJECT,
|
||||
KotlinTarget.MEMBER_PROPERTY,
|
||||
KotlinTarget.MEMBER_FUNCTION
|
||||
),
|
||||
SEALED_KEYWORD to EnumSet.of(KotlinTarget.CLASS_ONLY, KotlinTarget.INTERFACE),
|
||||
INNER_KEYWORD to EnumSet.of(KotlinTarget.CLASS_ONLY),
|
||||
OVERRIDE_KEYWORD to EnumSet.of(KotlinTarget.MEMBER_PROPERTY, KotlinTarget.MEMBER_FUNCTION),
|
||||
PRIVATE_KEYWORD to defaultVisibilityTargets,
|
||||
PUBLIC_KEYWORD to defaultVisibilityTargets,
|
||||
INTERNAL_KEYWORD to defaultVisibilityTargets,
|
||||
PROTECTED_KEYWORD to EnumSet.of(
|
||||
KotlinTarget.CLASS_ONLY,
|
||||
KotlinTarget.OBJECT,
|
||||
KotlinTarget.INTERFACE,
|
||||
KotlinTarget.ENUM_CLASS,
|
||||
KotlinTarget.ANNOTATION_CLASS,
|
||||
KotlinTarget.MEMBER_FUNCTION,
|
||||
KotlinTarget.PROPERTY_GETTER,
|
||||
KotlinTarget.PROPERTY_SETTER,
|
||||
KotlinTarget.MEMBER_PROPERTY,
|
||||
KotlinTarget.CONSTRUCTOR,
|
||||
KotlinTarget.TYPEALIAS
|
||||
),
|
||||
IN_KEYWORD to EnumSet.of(KotlinTarget.TYPE_PARAMETER, KotlinTarget.TYPE_PROJECTION),
|
||||
OUT_KEYWORD to EnumSet.of(KotlinTarget.TYPE_PARAMETER, KotlinTarget.TYPE_PROJECTION),
|
||||
REIFIED_KEYWORD to EnumSet.of(KotlinTarget.TYPE_PARAMETER),
|
||||
VARARG_KEYWORD to EnumSet.of(KotlinTarget.VALUE_PARAMETER, KotlinTarget.PROPERTY_PARAMETER),
|
||||
COMPANION_KEYWORD to EnumSet.of(KotlinTarget.OBJECT),
|
||||
LATEINIT_KEYWORD to EnumSet.of(KotlinTarget.MEMBER_PROPERTY, KotlinTarget.TOP_LEVEL_PROPERTY, KotlinTarget.LOCAL_VARIABLE),
|
||||
DATA_KEYWORD to EnumSet.of(KotlinTarget.CLASS_ONLY, KotlinTarget.LOCAL_CLASS),
|
||||
INLINE_KEYWORD to EnumSet.of(
|
||||
KotlinTarget.FUNCTION,
|
||||
KotlinTarget.PROPERTY,
|
||||
KotlinTarget.PROPERTY_GETTER,
|
||||
KotlinTarget.PROPERTY_SETTER,
|
||||
KotlinTarget.CLASS_ONLY
|
||||
),
|
||||
NOINLINE_KEYWORD to EnumSet.of(KotlinTarget.VALUE_PARAMETER),
|
||||
TAILREC_KEYWORD to EnumSet.of(KotlinTarget.FUNCTION),
|
||||
SUSPEND_KEYWORD to EnumSet.of(KotlinTarget.MEMBER_FUNCTION, KotlinTarget.TOP_LEVEL_FUNCTION, KotlinTarget.LOCAL_FUNCTION),
|
||||
EXTERNAL_KEYWORD to EnumSet.of(
|
||||
KotlinTarget.FUNCTION,
|
||||
KotlinTarget.PROPERTY,
|
||||
KotlinTarget.PROPERTY_GETTER,
|
||||
KotlinTarget.PROPERTY_SETTER,
|
||||
KotlinTarget.CLASS
|
||||
),
|
||||
ANNOTATION_KEYWORD to EnumSet.of(KotlinTarget.ANNOTATION_CLASS),
|
||||
CROSSINLINE_KEYWORD to EnumSet.of(KotlinTarget.VALUE_PARAMETER),
|
||||
CONST_KEYWORD to EnumSet.of(KotlinTarget.MEMBER_PROPERTY, KotlinTarget.TOP_LEVEL_PROPERTY),
|
||||
OPERATOR_KEYWORD to EnumSet.of(KotlinTarget.FUNCTION),
|
||||
INFIX_KEYWORD to EnumSet.of(KotlinTarget.FUNCTION),
|
||||
HEADER_KEYWORD to EnumSet.of(
|
||||
KotlinTarget.TOP_LEVEL_FUNCTION,
|
||||
KotlinTarget.TOP_LEVEL_PROPERTY,
|
||||
KotlinTarget.CLASS_ONLY,
|
||||
KotlinTarget.OBJECT,
|
||||
KotlinTarget.INTERFACE,
|
||||
KotlinTarget.ENUM_CLASS,
|
||||
KotlinTarget.ANNOTATION_CLASS
|
||||
),
|
||||
IMPL_KEYWORD to EnumSet.of(
|
||||
KotlinTarget.TOP_LEVEL_FUNCTION,
|
||||
KotlinTarget.MEMBER_FUNCTION,
|
||||
KotlinTarget.TOP_LEVEL_PROPERTY,
|
||||
KotlinTarget.MEMBER_PROPERTY,
|
||||
KotlinTarget.CONSTRUCTOR,
|
||||
KotlinTarget.CLASS_ONLY,
|
||||
KotlinTarget.OBJECT,
|
||||
KotlinTarget.INTERFACE,
|
||||
KotlinTarget.ENUM_CLASS,
|
||||
KotlinTarget.ANNOTATION_CLASS,
|
||||
KotlinTarget.TYPEALIAS
|
||||
),
|
||||
EXPECT_KEYWORD to EnumSet.of(
|
||||
KotlinTarget.TOP_LEVEL_FUNCTION,
|
||||
KotlinTarget.TOP_LEVEL_PROPERTY,
|
||||
KotlinTarget.CLASS_ONLY,
|
||||
KotlinTarget.OBJECT,
|
||||
KotlinTarget.INTERFACE,
|
||||
KotlinTarget.ENUM_CLASS,
|
||||
KotlinTarget.ANNOTATION_CLASS
|
||||
),
|
||||
ACTUAL_KEYWORD to EnumSet.of(
|
||||
KotlinTarget.TOP_LEVEL_FUNCTION,
|
||||
KotlinTarget.MEMBER_FUNCTION,
|
||||
KotlinTarget.TOP_LEVEL_PROPERTY,
|
||||
KotlinTarget.MEMBER_PROPERTY,
|
||||
KotlinTarget.CONSTRUCTOR,
|
||||
KotlinTarget.CLASS_ONLY,
|
||||
KotlinTarget.OBJECT,
|
||||
KotlinTarget.INTERFACE,
|
||||
KotlinTarget.ENUM_CLASS,
|
||||
KotlinTarget.ANNOTATION_CLASS,
|
||||
KotlinTarget.TYPEALIAS
|
||||
),
|
||||
FUN_KEYWORD to EnumSet.of(KotlinTarget.INTERFACE),
|
||||
VALUE_KEYWORD to EnumSet.of(KotlinTarget.CLASS_ONLY)
|
||||
)
|
||||
|
||||
// NOTE: deprecated targets must be possible!
|
||||
val deprecatedTargetMap = mapOf<KtKeywordToken, Set<KotlinTarget>>()
|
||||
|
||||
val deprecatedParentTargetMap = mapOf<KtKeywordToken, Set<KotlinTarget>>()
|
||||
|
||||
val deprecatedModifierMap = mapOf(
|
||||
HEADER_KEYWORD to EXPECT_KEYWORD,
|
||||
IMPL_KEYWORD to ACTUAL_KEYWORD
|
||||
)
|
||||
|
||||
// NOTE: redundant targets must be possible!
|
||||
val redundantTargetMap = mapOf<KtKeywordToken, Set<KotlinTarget>>(
|
||||
OPEN_KEYWORD to EnumSet.of(KotlinTarget.INTERFACE)
|
||||
)
|
||||
|
||||
interface TargetAllowedPredicate {
|
||||
fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings): Boolean
|
||||
}
|
||||
|
||||
fun always(target: KotlinTarget, vararg targets: KotlinTarget) = object : TargetAllowedPredicate {
|
||||
private val targetSet = EnumSet.of(target, *targets)
|
||||
|
||||
override fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings) =
|
||||
target in targetSet
|
||||
}
|
||||
|
||||
fun ifSupported(languageFeature: LanguageFeature, target: KotlinTarget, vararg targets: KotlinTarget) =
|
||||
object : TargetAllowedPredicate {
|
||||
private val targetSet = EnumSet.of(target, *targets)
|
||||
|
||||
override fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings) =
|
||||
languageVersionSettings.supportsFeature(languageFeature) && target in targetSet
|
||||
}
|
||||
|
||||
fun or(p1: TargetAllowedPredicate, p2: TargetAllowedPredicate) = object : TargetAllowedPredicate {
|
||||
override fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings) =
|
||||
p1.isAllowed(target, languageVersionSettings) ||
|
||||
p2.isAllowed(target, languageVersionSettings)
|
||||
}
|
||||
|
||||
val possibleParentTargetPredicateMap = mapOf(
|
||||
INNER_KEYWORD to or(
|
||||
always(KotlinTarget.CLASS_ONLY, KotlinTarget.LOCAL_CLASS, KotlinTarget.ENUM_CLASS),
|
||||
ifSupported(LanguageFeature.InnerClassInEnumEntryClass, KotlinTarget.ENUM_ENTRY)
|
||||
),
|
||||
OVERRIDE_KEYWORD to always(
|
||||
KotlinTarget.CLASS_ONLY,
|
||||
KotlinTarget.LOCAL_CLASS,
|
||||
KotlinTarget.OBJECT,
|
||||
KotlinTarget.OBJECT_LITERAL,
|
||||
KotlinTarget.INTERFACE,
|
||||
KotlinTarget.ENUM_CLASS,
|
||||
KotlinTarget.ENUM_ENTRY
|
||||
),
|
||||
PROTECTED_KEYWORD to always(KotlinTarget.CLASS_ONLY, KotlinTarget.LOCAL_CLASS, KotlinTarget.ENUM_CLASS, KotlinTarget.COMPANION_OBJECT),
|
||||
INTERNAL_KEYWORD to always(
|
||||
KotlinTarget.CLASS_ONLY,
|
||||
KotlinTarget.LOCAL_CLASS,
|
||||
KotlinTarget.OBJECT,
|
||||
KotlinTarget.OBJECT_LITERAL,
|
||||
KotlinTarget.ENUM_CLASS,
|
||||
KotlinTarget.ENUM_ENTRY,
|
||||
KotlinTarget.FILE
|
||||
),
|
||||
PRIVATE_KEYWORD to always(
|
||||
KotlinTarget.CLASS_ONLY,
|
||||
KotlinTarget.LOCAL_CLASS,
|
||||
KotlinTarget.OBJECT,
|
||||
KotlinTarget.OBJECT_LITERAL,
|
||||
KotlinTarget.INTERFACE,
|
||||
KotlinTarget.ENUM_CLASS,
|
||||
KotlinTarget.ENUM_ENTRY,
|
||||
KotlinTarget.FILE
|
||||
),
|
||||
COMPANION_KEYWORD to always(
|
||||
KotlinTarget.CLASS_ONLY,
|
||||
KotlinTarget.INTERFACE,
|
||||
KotlinTarget.ENUM_CLASS,
|
||||
KotlinTarget.ANNOTATION_CLASS
|
||||
),
|
||||
FINAL_KEYWORD to always(
|
||||
KotlinTarget.CLASS_ONLY,
|
||||
KotlinTarget.LOCAL_CLASS,
|
||||
KotlinTarget.OBJECT,
|
||||
KotlinTarget.OBJECT_LITERAL,
|
||||
KotlinTarget.ENUM_CLASS,
|
||||
KotlinTarget.ENUM_ENTRY,
|
||||
KotlinTarget.ANNOTATION_CLASS,
|
||||
KotlinTarget.FILE
|
||||
),
|
||||
VARARG_KEYWORD to always(KotlinTarget.CONSTRUCTOR, KotlinTarget.FUNCTION, KotlinTarget.CLASS)
|
||||
)
|
||||
|
||||
|
||||
@@ -1,400 +0,0 @@
|
||||
/*
|
||||
* 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.resolve;
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.*
|
||||
import java.util.*
|
||||
import org.jetbrains.kotlin.resolve.KeywordType.*
|
||||
|
||||
enum class KeywordType {
|
||||
Inner,
|
||||
Override,
|
||||
Public,
|
||||
Protected,
|
||||
Internal,
|
||||
Private,
|
||||
Companion,
|
||||
Final,
|
||||
Vararg,
|
||||
Enum,
|
||||
Abstract,
|
||||
Open,
|
||||
Sealed,
|
||||
In,
|
||||
Out,
|
||||
Reified,
|
||||
Lateinit,
|
||||
Data,
|
||||
Inline,
|
||||
Noinline,
|
||||
Tailrec,
|
||||
Suspend,
|
||||
External,
|
||||
Annotation,
|
||||
Crossinline,
|
||||
Const,
|
||||
Operator,
|
||||
Infix,
|
||||
Header,
|
||||
Impl,
|
||||
Expect,
|
||||
Actual,
|
||||
Fun,
|
||||
Value
|
||||
}
|
||||
|
||||
fun KeywordType.render(): String {
|
||||
return toString().lowercase()
|
||||
}
|
||||
|
||||
enum class Compatibility {
|
||||
// modifier pair is compatible: ok (default)
|
||||
COMPATIBLE,
|
||||
|
||||
// second is redundant to first: warning
|
||||
REDUNDANT,
|
||||
|
||||
// first is redundant to second: warning
|
||||
REVERSE_REDUNDANT,
|
||||
|
||||
// error
|
||||
REPEATED,
|
||||
|
||||
// pair is deprecated, will become incompatible: warning
|
||||
DEPRECATED,
|
||||
|
||||
// pair is incompatible: error
|
||||
INCOMPATIBLE,
|
||||
|
||||
// same but only for functions / properties: error
|
||||
COMPATIBLE_FOR_CLASSES_ONLY
|
||||
}
|
||||
|
||||
val compatibilityTypeMap = hashMapOf<Pair<KeywordType, KeywordType>, Compatibility>()
|
||||
|
||||
fun compatibility(first: KeywordType, second: KeywordType): Compatibility {
|
||||
return if (first == second) {
|
||||
Compatibility.REPEATED
|
||||
} else {
|
||||
mutualCompatibility[Pair(first, second)] ?: Compatibility.COMPATIBLE
|
||||
}
|
||||
}
|
||||
|
||||
// First modifier in pair should be also first in declaration
|
||||
private val mutualCompatibility = buildCompatibilityMap()
|
||||
|
||||
private fun buildCompatibilityMap(): Map<Pair<KeywordType, KeywordType>, Compatibility> {
|
||||
val result = hashMapOf<Pair<KeywordType, KeywordType>, Compatibility>()
|
||||
// Variance: in + out are incompatible
|
||||
result += incompatibilityRegister(In, Out)
|
||||
// Visibilities: incompatible
|
||||
result += incompatibilityRegister(Private, Protected, Public, Internal)
|
||||
// Abstract + open + final + sealed: incompatible
|
||||
result += incompatibilityRegister(Abstract, Open, Final, Sealed)
|
||||
// data + open, data + inner, data + abstract, data + sealed, data + inline, data + value
|
||||
result += incompatibilityRegister(Data, Open)
|
||||
result += incompatibilityRegister(Data, Inner)
|
||||
result += incompatibilityRegister(Data, Abstract)
|
||||
result += incompatibilityRegister(Data, Sealed)
|
||||
result += incompatibilityRegister(Data, Inline)
|
||||
result += incompatibilityRegister(Data, Value)
|
||||
// open is redundant to abstract & override
|
||||
result += redundantRegister(Abstract, Open)
|
||||
// abstract is redundant to sealed
|
||||
result += redundantRegister(Sealed, Abstract)
|
||||
|
||||
// const is incompatible with abstract, open, override
|
||||
result += incompatibilityRegister(Const, Abstract)
|
||||
result += incompatibilityRegister(Const, Open)
|
||||
result += incompatibilityRegister(Const, Override)
|
||||
|
||||
// private is incompatible with override
|
||||
result += incompatibilityRegister(Private, Override)
|
||||
// private is compatible with open / abstract only for classes
|
||||
result += compatibilityForClassesRegister(Private, Open)
|
||||
result += compatibilityForClassesRegister(Private, Abstract)
|
||||
|
||||
result += incompatibilityRegister(Crossinline, Noinline)
|
||||
|
||||
// 1. subclasses contained inside a sealed class can not be instantiated, because their constructors needs
|
||||
// an instance of an outer sealed (effectively abstract) class
|
||||
// 2. subclasses of a non-top-level sealed class must be declared inside the class
|
||||
// (see the KEEP https://github.com/Kotlin/KEEP/blob/master/proposals/sealed-class-inheritance.md)
|
||||
result += incompatibilityRegister(Sealed, Inner)
|
||||
|
||||
// header / expect / impl / actual are all incompatible
|
||||
result += incompatibilityRegister(Header, Expect, Impl, Actual)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun incompatibilityRegister(vararg list: KeywordType): Map<Pair<KeywordType, KeywordType>, Compatibility> {
|
||||
return compatibilityRegister(Compatibility.INCOMPATIBLE, *list)
|
||||
}
|
||||
|
||||
private fun redundantRegister(
|
||||
sufficient: KeywordType,
|
||||
redundant: KeywordType
|
||||
): Map<Pair<KeywordType, KeywordType>, Compatibility> {
|
||||
return mapOf(
|
||||
Pair(sufficient, redundant) to Compatibility.REDUNDANT,
|
||||
Pair(redundant, sufficient) to Compatibility.REVERSE_REDUNDANT
|
||||
)
|
||||
}
|
||||
|
||||
private fun compatibilityForClassesRegister(vararg list: KeywordType) =
|
||||
compatibilityRegister(Compatibility.COMPATIBLE_FOR_CLASSES_ONLY, *list)
|
||||
|
||||
private fun compatibilityRegister(
|
||||
compatibility: Compatibility, vararg list: KeywordType
|
||||
): Map<Pair<KeywordType, KeywordType>, Compatibility> {
|
||||
val result = hashMapOf<Pair<KeywordType, KeywordType>, Compatibility>()
|
||||
for (first in list) {
|
||||
for (second in list) {
|
||||
if (first != second) {
|
||||
result[Pair(first, second)] = compatibility
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
val featureDependencies = mapOf(
|
||||
Suspend to listOf(LanguageFeature.Coroutines),
|
||||
Inline to listOf(LanguageFeature.InlineProperties, LanguageFeature.InlineClasses),
|
||||
Header to listOf(LanguageFeature.MultiPlatformProjects),
|
||||
Impl to listOf(LanguageFeature.MultiPlatformProjects),
|
||||
Expect to listOf(LanguageFeature.MultiPlatformProjects),
|
||||
Actual to listOf(LanguageFeature.MultiPlatformProjects),
|
||||
Lateinit to listOf(LanguageFeature.LateinitTopLevelProperties, LanguageFeature.LateinitLocalVariables),
|
||||
Fun to listOf(LanguageFeature.FunctionalInterfaceConversion)
|
||||
)
|
||||
|
||||
val featureDependenciesTargets = mapOf(
|
||||
LanguageFeature.InlineProperties to setOf(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER),
|
||||
LanguageFeature.LateinitLocalVariables to setOf(LOCAL_VARIABLE),
|
||||
LanguageFeature.LateinitTopLevelProperties to setOf(TOP_LEVEL_PROPERTY),
|
||||
LanguageFeature.InlineClasses to setOf(CLASS_ONLY),
|
||||
LanguageFeature.JvmInlineValueClasses to setOf(CLASS_ONLY),
|
||||
LanguageFeature.FunctionalInterfaceConversion to setOf(INTERFACE)
|
||||
)
|
||||
|
||||
val defaultVisibilityTargets: EnumSet<KotlinTarget> = EnumSet.of(
|
||||
CLASS_ONLY, OBJECT, INTERFACE, ENUM_CLASS, ANNOTATION_CLASS,
|
||||
MEMBER_FUNCTION, TOP_LEVEL_FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER,
|
||||
MEMBER_PROPERTY, TOP_LEVEL_PROPERTY, CONSTRUCTOR, TYPEALIAS
|
||||
)
|
||||
|
||||
val possibleTargetMap = mapOf(
|
||||
KeywordType.Enum to EnumSet.of(ENUM_CLASS),
|
||||
Abstract to EnumSet.of(
|
||||
CLASS_ONLY,
|
||||
LOCAL_CLASS,
|
||||
INTERFACE,
|
||||
MEMBER_PROPERTY,
|
||||
MEMBER_FUNCTION
|
||||
),
|
||||
Open to EnumSet.of(
|
||||
CLASS_ONLY,
|
||||
LOCAL_CLASS,
|
||||
INTERFACE,
|
||||
MEMBER_PROPERTY,
|
||||
MEMBER_FUNCTION
|
||||
),
|
||||
Final to EnumSet.of(
|
||||
CLASS_ONLY,
|
||||
LOCAL_CLASS,
|
||||
ENUM_CLASS,
|
||||
OBJECT,
|
||||
MEMBER_PROPERTY,
|
||||
MEMBER_FUNCTION
|
||||
),
|
||||
Sealed to EnumSet.of(CLASS_ONLY, INTERFACE),
|
||||
Inner to EnumSet.of(CLASS_ONLY),
|
||||
Override to EnumSet.of(MEMBER_PROPERTY, MEMBER_FUNCTION),
|
||||
Private to defaultVisibilityTargets,
|
||||
Public to defaultVisibilityTargets,
|
||||
Internal to defaultVisibilityTargets,
|
||||
Protected to EnumSet.of(
|
||||
CLASS_ONLY,
|
||||
OBJECT,
|
||||
INTERFACE,
|
||||
ENUM_CLASS,
|
||||
ANNOTATION_CLASS,
|
||||
MEMBER_FUNCTION,
|
||||
PROPERTY_GETTER,
|
||||
PROPERTY_SETTER,
|
||||
MEMBER_PROPERTY,
|
||||
CONSTRUCTOR,
|
||||
TYPEALIAS
|
||||
),
|
||||
In to EnumSet.of(TYPE_PARAMETER, TYPE_PROJECTION),
|
||||
Out to EnumSet.of(TYPE_PARAMETER, TYPE_PROJECTION),
|
||||
Reified to EnumSet.of(TYPE_PARAMETER),
|
||||
Vararg to EnumSet.of(VALUE_PARAMETER, PROPERTY_PARAMETER),
|
||||
KeywordType.Companion to EnumSet.of(OBJECT),
|
||||
Lateinit to EnumSet.of(MEMBER_PROPERTY, TOP_LEVEL_PROPERTY, LOCAL_VARIABLE),
|
||||
Data to EnumSet.of(CLASS_ONLY, LOCAL_CLASS),
|
||||
Inline to EnumSet.of(
|
||||
FUNCTION,
|
||||
PROPERTY,
|
||||
PROPERTY_GETTER,
|
||||
PROPERTY_SETTER,
|
||||
CLASS_ONLY
|
||||
),
|
||||
Noinline to EnumSet.of(VALUE_PARAMETER),
|
||||
Tailrec to EnumSet.of(FUNCTION),
|
||||
Suspend to EnumSet.of(MEMBER_FUNCTION, TOP_LEVEL_FUNCTION, LOCAL_FUNCTION),
|
||||
External to EnumSet.of(
|
||||
FUNCTION,
|
||||
PROPERTY,
|
||||
PROPERTY_GETTER,
|
||||
PROPERTY_SETTER,
|
||||
CLASS
|
||||
),
|
||||
KeywordType.Annotation to EnumSet.of(ANNOTATION_CLASS), // TODO: Workaround for FIR, https://youtrack.jetbrains.com/issue/KT-48157
|
||||
Crossinline to EnumSet.of(VALUE_PARAMETER),
|
||||
Const to EnumSet.of(MEMBER_PROPERTY, TOP_LEVEL_PROPERTY),
|
||||
Operator to EnumSet.of(FUNCTION),
|
||||
Infix to EnumSet.of(FUNCTION),
|
||||
Header to EnumSet.of(
|
||||
TOP_LEVEL_FUNCTION,
|
||||
TOP_LEVEL_PROPERTY,
|
||||
CLASS_ONLY,
|
||||
OBJECT,
|
||||
INTERFACE,
|
||||
ENUM_CLASS,
|
||||
ANNOTATION_CLASS
|
||||
),
|
||||
Impl to EnumSet.of(
|
||||
TOP_LEVEL_FUNCTION,
|
||||
MEMBER_FUNCTION,
|
||||
TOP_LEVEL_PROPERTY,
|
||||
MEMBER_PROPERTY,
|
||||
CONSTRUCTOR,
|
||||
CLASS_ONLY,
|
||||
OBJECT,
|
||||
INTERFACE,
|
||||
ENUM_CLASS,
|
||||
ANNOTATION_CLASS,
|
||||
TYPEALIAS
|
||||
),
|
||||
Expect to EnumSet.of(
|
||||
TOP_LEVEL_FUNCTION,
|
||||
TOP_LEVEL_PROPERTY,
|
||||
CLASS_ONLY,
|
||||
OBJECT,
|
||||
INTERFACE,
|
||||
ENUM_CLASS,
|
||||
ANNOTATION_CLASS
|
||||
),
|
||||
Actual to EnumSet.of(
|
||||
TOP_LEVEL_FUNCTION,
|
||||
MEMBER_FUNCTION,
|
||||
TOP_LEVEL_PROPERTY,
|
||||
MEMBER_PROPERTY,
|
||||
CONSTRUCTOR,
|
||||
CLASS_ONLY,
|
||||
OBJECT,
|
||||
INTERFACE,
|
||||
ENUM_CLASS,
|
||||
ANNOTATION_CLASS,
|
||||
TYPEALIAS
|
||||
),
|
||||
Fun to EnumSet.of(INTERFACE),
|
||||
Value to EnumSet.of(CLASS_ONLY)
|
||||
)
|
||||
|
||||
// NOTE: deprecated targets must be possible!
|
||||
val deprecatedTargetMap = mapOf<KeywordType, Set<KotlinTarget>>()
|
||||
|
||||
val deprecatedParentTargetMap = mapOf<KeywordType, Set<KotlinTarget>>()
|
||||
|
||||
val deprecatedModifierMap = mapOf(
|
||||
Header to Expect,
|
||||
Impl to Actual
|
||||
)
|
||||
|
||||
// NOTE: redundant targets must be possible!
|
||||
val redundantTargetMap = mapOf<KeywordType, Set<KotlinTarget>>(
|
||||
Open to EnumSet.of(INTERFACE)
|
||||
)
|
||||
|
||||
interface TargetAllowedPredicate {
|
||||
fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings): Boolean
|
||||
}
|
||||
|
||||
fun always(target: KotlinTarget, vararg targets: KotlinTarget) = object : TargetAllowedPredicate {
|
||||
private val targetSet = EnumSet.of(target, *targets)
|
||||
|
||||
override fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings) =
|
||||
target in targetSet
|
||||
}
|
||||
|
||||
fun ifSupported(languageFeature: LanguageFeature, target: KotlinTarget, vararg targets: KotlinTarget) =
|
||||
object : TargetAllowedPredicate {
|
||||
private val targetSet = EnumSet.of(target, *targets)
|
||||
|
||||
override fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings) =
|
||||
languageVersionSettings.supportsFeature(languageFeature) && target in targetSet
|
||||
}
|
||||
|
||||
fun or(p1: TargetAllowedPredicate, p2: TargetAllowedPredicate) = object : TargetAllowedPredicate {
|
||||
override fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings) =
|
||||
p1.isAllowed(target, languageVersionSettings) ||
|
||||
p2.isAllowed(target, languageVersionSettings)
|
||||
}
|
||||
|
||||
val possibleParentTargetPredicateMap = mapOf(
|
||||
Inner to or(
|
||||
always(CLASS_ONLY, LOCAL_CLASS, ENUM_CLASS),
|
||||
ifSupported(LanguageFeature.InnerClassInEnumEntryClass, ENUM_ENTRY)
|
||||
),
|
||||
Override to always(
|
||||
CLASS_ONLY,
|
||||
LOCAL_CLASS,
|
||||
OBJECT,
|
||||
OBJECT_LITERAL,
|
||||
INTERFACE,
|
||||
ENUM_CLASS,
|
||||
ENUM_ENTRY
|
||||
),
|
||||
Protected to always(CLASS_ONLY, LOCAL_CLASS, ENUM_CLASS, COMPANION_OBJECT),
|
||||
Internal to always(
|
||||
CLASS_ONLY,
|
||||
LOCAL_CLASS,
|
||||
OBJECT,
|
||||
OBJECT_LITERAL,
|
||||
ENUM_CLASS,
|
||||
ENUM_ENTRY,
|
||||
FILE
|
||||
),
|
||||
Private to always(
|
||||
CLASS_ONLY,
|
||||
LOCAL_CLASS,
|
||||
OBJECT,
|
||||
OBJECT_LITERAL,
|
||||
INTERFACE,
|
||||
ENUM_CLASS,
|
||||
ENUM_ENTRY,
|
||||
FILE
|
||||
),
|
||||
KeywordType.Companion to always(CLASS_ONLY, INTERFACE, ENUM_CLASS, ANNOTATION_CLASS),
|
||||
Final to always(
|
||||
CLASS_ONLY,
|
||||
LOCAL_CLASS,
|
||||
OBJECT,
|
||||
OBJECT_LITERAL,
|
||||
ENUM_CLASS,
|
||||
ENUM_ENTRY,
|
||||
ANNOTATION_CLASS,
|
||||
FILE
|
||||
),
|
||||
Vararg to always(CONSTRUCTOR, FUNCTION, CLASS)
|
||||
)
|
||||
6
compiler/testData/cli/jvm/firVsClassicAnnotation.args
vendored
Normal file
6
compiler/testData/cli/jvm/firVsClassicAnnotation.args
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
$TESTDATA_DIR$/firVsClassicAnnotation.kt
|
||||
-classpath
|
||||
$TESTDATA_DIR$/firVsClassicAnnotation
|
||||
-Xuse-fir
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
24
compiler/testData/cli/jvm/firVsClassicAnnotation.kt
vendored
Normal file
24
compiler/testData/cli/jvm/firVsClassicAnnotation.kt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// Library part (build by FE 1.0)
|
||||
|
||||
//package lib
|
||||
//
|
||||
//@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD)
|
||||
//annotation class Property(
|
||||
// val description: String = "",
|
||||
// val ignore: Boolean = false,
|
||||
//
|
||||
// val externalName: String = ""
|
||||
//)
|
||||
//
|
||||
//open class LocatableRunConfigurationOptions {
|
||||
// @Property(ignore = true)
|
||||
// val isNameGenerated by lazy { false }
|
||||
//}
|
||||
|
||||
// Main part
|
||||
|
||||
package use
|
||||
|
||||
import lib.LocatableRunConfigurationOptions
|
||||
|
||||
class JvmMainMethodRunConfigurationOptions : LocatableRunConfigurationOptions()
|
||||
4
compiler/testData/cli/jvm/firVsClassicAnnotation.out
vendored
Normal file
4
compiler/testData/cli/jvm/firVsClassicAnnotation.out
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
warning: ATTENTION!
|
||||
This build uses in-dev FIR:
|
||||
-Xuse-fir
|
||||
OK
|
||||
Binary file not shown.
BIN
compiler/testData/cli/jvm/firVsClassicAnnotation/lib/LocatableRunConfigurationOptions.class
vendored
Normal file
BIN
compiler/testData/cli/jvm/firVsClassicAnnotation/lib/LocatableRunConfigurationOptions.class
vendored
Normal file
Binary file not shown.
BIN
compiler/testData/cli/jvm/firVsClassicAnnotation/lib/Property.class
vendored
Normal file
BIN
compiler/testData/cli/jvm/firVsClassicAnnotation/lib/Property.class
vendored
Normal file
Binary file not shown.
100
compiler/testData/codegen/box/builtinStubMethods/int2IntMap.kt
vendored
Normal file
100
compiler/testData/codegen/box/builtinStubMethods/int2IntMap.kt
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// JVM_TARGET: 1.8
|
||||
|
||||
// FILE: Int2IntFunction.java
|
||||
public interface Int2IntFunction {
|
||||
boolean containsKey(int key);
|
||||
|
||||
@Deprecated
|
||||
default boolean containsKey(Object key) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// FILE: Int2IntMap.java
|
||||
public interface Int2IntMap extends Int2IntFunction, java.util.Map<Integer, Integer> {
|
||||
boolean containsKey(int var1);
|
||||
|
||||
@Deprecated
|
||||
default boolean containsKey(Object key) {
|
||||
return Int2IntFunction.super.containsKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: Int2IntMapImpl.java
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class Int2IntMapImpl implements Int2IntMap {
|
||||
@Override
|
||||
public boolean containsKey(int var1) {
|
||||
return var1 == 56;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer get(Object key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer put(Integer key, Integer value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer remove(Object key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends Integer, ? extends Integer> m) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> keySet() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Integer> values() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Entry<Integer, Integer>> entrySet() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// FILE: m.kt
|
||||
fun foo(x: Int2IntMap): String {
|
||||
if (!x.containsKey(56)) return "fail 1"
|
||||
if (x.containsKey(239)) return "fail 1"
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return foo(Int2IntMapImpl())
|
||||
}
|
||||
@@ -49,7 +49,7 @@ FILE fqName:<root> fileName:/noSymbolForIntRangeIterator.kt
|
||||
CONST Int type=kotlin.Int value=10
|
||||
VAR name:y type:kotlin.Int [val]
|
||||
CONST Int type=kotlin.Int value=10
|
||||
FUN name:localFunc visibility:local modality:FINAL <> () returnType:kotlin.Unit
|
||||
FUN LOCAL_FUNCTION name:localFunc visibility:local modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
BLOCK type=kotlin.Unit origin=FOR_LOOP
|
||||
VAR FOR_LOOP_ITERATOR name:tmp_1 type:kotlin.collections.IntIterator [val]
|
||||
|
||||
@@ -50,7 +50,7 @@ FILE fqName:<root> fileName:/noSymbolForIntRangeIterator.kt
|
||||
CONST Int type=kotlin.Int value=10
|
||||
VAR name:y type:kotlin.Int [val]
|
||||
CONST Int type=kotlin.Int value=10
|
||||
FUN name:localFunc visibility:local modality:FINAL <> () returnType:kotlin.Unit
|
||||
FUN LOCAL_FUNCTION name:localFunc visibility:local modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
BLOCK type=kotlin.Unit origin=FOR_LOOP
|
||||
VAR FOR_LOOP_ITERATOR name:tmp_1 type:kotlin.collections.IntIterator [val]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// !LANGUAGE: +StrictJavaNullabilityAssertions -ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// See KT-8135
|
||||
// We could generate runtime assertion on call site for 'generic<NOT_NULL_TYPE>()' below.
|
||||
|
||||
|
||||
29
compiler/testData/codegen/box/syntheticExtensions/firstCapitalizedProperty.kt
vendored
Normal file
29
compiler/testData/codegen/box/syntheticExtensions/firstCapitalizedProperty.kt
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// MODULE: lib
|
||||
|
||||
// FILE: test/UI.java
|
||||
package test;
|
||||
public class UI {
|
||||
public static String foo() {
|
||||
return "OK";
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: Parent.java
|
||||
public class Parent {
|
||||
public String getUI() { return "fail"; }
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
|
||||
import test.UI;
|
||||
|
||||
class Derived : Parent() {
|
||||
fun bar(): String = UI.foo()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return Derived().bar()
|
||||
}
|
||||
14
compiler/testData/codegen/boxInline/capture/kt48230.kt
vendored
Normal file
14
compiler/testData/codegen/boxInline/capture/kt48230.kt
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
inline fun withO(block: String.() -> String) = "O".block()
|
||||
|
||||
// FILE: 2.kt
|
||||
interface I {
|
||||
val k: String
|
||||
|
||||
fun foo() = withO { this + k }
|
||||
}
|
||||
|
||||
fun box(): String = object : I {
|
||||
override val k = "K"
|
||||
}.foo()
|
||||
14
compiler/testData/codegen/boxInline/capture/kt48230_2.kt
vendored
Normal file
14
compiler/testData/codegen/boxInline/capture/kt48230_2.kt
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
inline fun withO(block: String.() -> String) = "O".block()
|
||||
|
||||
// FILE: 2.kt
|
||||
interface I {
|
||||
val k: String
|
||||
|
||||
fun foo() = withO(fun String.(): String { return this + k })
|
||||
}
|
||||
|
||||
fun box(): String = object : I {
|
||||
override val k = "K"
|
||||
}.foo()
|
||||
@@ -1,35 +0,0 @@
|
||||
// JSPECIFY_STATE: strict
|
||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
||||
|
||||
// FILE: WildcardsWithDefault.java
|
||||
import org.jspecify.nullness.*;
|
||||
|
||||
@NullMarked
|
||||
public class WildcardsWithDefault {
|
||||
public void noBoundsNotNull(A<?, ?, ?> a) {}
|
||||
public void noBoundsNullable(A<? extends @Nullable Object, ? extends @Nullable Object, ? extends @Nullable Object> a) {}
|
||||
}
|
||||
|
||||
// FILE: A.java
|
||||
import org.jspecify.nullness.*;
|
||||
|
||||
public class A <T extends Object, E extends @Nullable Object, F extends @NullnessUnspecified Object> {}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main(
|
||||
aNotNullNotNullNotNull: A<Any, Any, Any>,
|
||||
aNotNullNotNullNull: A<Any, Any, Any?>,
|
||||
aNotNullNullNotNull: A<Any, Any?, Any>,
|
||||
aNotNullNullNull: A<Any, Any?, Any?>,
|
||||
b: WildcardsWithDefault
|
||||
): Unit {
|
||||
b.noBoundsNotNull(aNotNullNotNullNotNull)
|
||||
b.noBoundsNotNull(aNotNullNotNullNull)
|
||||
b.noBoundsNotNull(aNotNullNullNotNull)
|
||||
b.noBoundsNotNull(aNotNullNullNull)
|
||||
|
||||
b.noBoundsNullable(aNotNullNotNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNotNullNull)
|
||||
b.noBoundsNullable(aNotNullNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNullNull)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// JSPECIFY_STATE: strict
|
||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
||||
|
||||
@@ -24,14 +25,12 @@ fun main(
|
||||
b: WildcardsWithDefault
|
||||
): Unit {
|
||||
b.noBoundsNotNull(aNotNullNotNullNotNull)
|
||||
// jspecify_nullness_mismatch
|
||||
b.noBoundsNotNull(<!TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
||||
b.noBoundsNotNull(aNotNullNotNullNull)
|
||||
b.noBoundsNotNull(aNotNullNullNotNull)
|
||||
// jspecify_nullness_mismatch
|
||||
b.noBoundsNotNull(<!TYPE_MISMATCH!>aNotNullNullNull<!>)
|
||||
b.noBoundsNotNull(aNotNullNullNull)
|
||||
|
||||
b.noBoundsNullable(aNotNullNotNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNotNullNull)
|
||||
b.noBoundsNullable(aNotNullNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNullNull)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ public open class A</*0*/ T : kotlin.Any!, /*1*/ E, /*2*/ F : @org.jspecify.null
|
||||
public constructor WildcardsWithDefault()
|
||||
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 fun noBoundsNotNull(/*0*/ a: A<out kotlin.Any, *, out @org.jspecify.nullness.NullnessUnspecified kotlin.Any>): kotlin.Unit
|
||||
public open fun noBoundsNotNull(/*0*/ a: A<*, *, *>): kotlin.Unit
|
||||
public open fun noBoundsNullable(/*0*/ a: A<out @org.jspecify.nullness.Nullable kotlin.Any?, out @org.jspecify.nullness.Nullable kotlin.Any?, out @org.jspecify.nullness.Nullable kotlin.Any?>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// JSPECIFY_STATE: warn
|
||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
||||
|
||||
// FILE: WildcardsWithDefault.java
|
||||
import org.jspecify.nullness.*;
|
||||
|
||||
@NullMarked
|
||||
public class WildcardsWithDefault {
|
||||
public void noBoundsNotNull(A<?, ?, ?> a) {}
|
||||
public void noBoundsNullable(A<? extends @Nullable Object, ? extends @Nullable Object, ? extends @Nullable Object> a) {}
|
||||
}
|
||||
|
||||
// FILE: A.java
|
||||
import org.jspecify.nullness.*;
|
||||
|
||||
public class A <T extends Object, E extends @Nullable Object, F extends @NullnessUnspecified Object> {}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main(
|
||||
aNotNullNotNullNotNull: A<Any, Any, Any>,
|
||||
aNotNullNotNullNull: A<Any, Any, Any?>,
|
||||
aNotNullNullNotNull: A<Any, Any?, Any>,
|
||||
aNotNullNullNull: A<Any, Any?, Any?>,
|
||||
b: WildcardsWithDefault
|
||||
): Unit {
|
||||
b.noBoundsNotNull(aNotNullNotNullNotNull)
|
||||
b.noBoundsNotNull(aNotNullNotNullNull)
|
||||
b.noBoundsNotNull(aNotNullNullNotNull)
|
||||
b.noBoundsNotNull(aNotNullNullNull)
|
||||
|
||||
b.noBoundsNullable(aNotNullNotNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNotNullNull)
|
||||
b.noBoundsNullable(aNotNullNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNullNull)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// JSPECIFY_STATE: warn
|
||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
||||
|
||||
@@ -24,14 +25,12 @@ fun main(
|
||||
b: WildcardsWithDefault
|
||||
): Unit {
|
||||
b.noBoundsNotNull(aNotNullNotNullNotNull)
|
||||
// jspecify_nullness_mismatch
|
||||
b.noBoundsNotNull(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>aNotNullNotNullNull<!>)
|
||||
b.noBoundsNotNull(aNotNullNotNullNull)
|
||||
b.noBoundsNotNull(aNotNullNullNotNull)
|
||||
// jspecify_nullness_mismatch
|
||||
b.noBoundsNotNull(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>aNotNullNullNull<!>)
|
||||
b.noBoundsNotNull(aNotNullNullNull)
|
||||
|
||||
b.noBoundsNullable(aNotNullNotNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNotNullNull)
|
||||
b.noBoundsNullable(aNotNullNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNullNull)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
class Example {
|
||||
operator fun plus(): String = ""
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(): String = ""
|
||||
operator fun unaryPlus(): Int = 0
|
||||
}
|
||||
|
||||
class ExampleDeprecated {
|
||||
operator fun plus(): String = ""
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(): String = ""
|
||||
}
|
||||
|
||||
operator fun String.plus(): String = this
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun String.plus(): String = this
|
||||
operator fun String.unaryPlus(): Int = 0
|
||||
|
||||
fun test() {
|
||||
@@ -22,8 +22,8 @@ fun requireInt(n: Int) {}
|
||||
fun requireString(s: String) {}
|
||||
|
||||
class Example2 {
|
||||
operator fun plus() = this
|
||||
operator fun minus() = this
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus() = this
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minus() = this
|
||||
|
||||
fun test() {
|
||||
<!INAPPLICABLE_CANDIDATE!>+<!>this
|
||||
|
||||
@@ -27,7 +27,7 @@ abstract class NotRange4() {
|
||||
}
|
||||
|
||||
abstract class ImproperIterator3 {
|
||||
abstract operator fun hasNext() : Int
|
||||
abstract <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hasNext() : Int
|
||||
abstract operator fun next() : Int
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ fun testIncDec() {
|
||||
}
|
||||
|
||||
class WrongIncDec() {
|
||||
operator fun inc() : Int = 1
|
||||
operator fun dec() : Int = 1
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun inc() : Int = 1
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun dec() : Int = 1
|
||||
}
|
||||
|
||||
fun testWrongIncDec() {
|
||||
@@ -29,8 +29,8 @@ fun testWrongIncDec() {
|
||||
}
|
||||
|
||||
class UnitIncDec() {
|
||||
operator fun inc() : Unit {}
|
||||
operator fun dec() : Unit {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun inc() : Unit {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun dec() : Unit {}
|
||||
}
|
||||
|
||||
fun testUnitIncDec() {
|
||||
|
||||
@@ -5,59 +5,59 @@ import kotlin.reflect.KProperty
|
||||
interface Example {
|
||||
operator fun plus(o: Example): Example
|
||||
operator fun div(o: Example): Example
|
||||
operator fun plus(o: Example, s: String = ""): Example
|
||||
operator fun minus(vararg o: Example): Example
|
||||
operator fun plus(): Example
|
||||
operator fun minus(): Example
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(o: Example, s: String = ""): Example
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minus(vararg o: Example): Example
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(): Example
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minus(): Example
|
||||
|
||||
operator fun unaryPlus(): Example
|
||||
operator fun unaryMinus(): Example
|
||||
|
||||
operator fun unaryPlus(s: String = ""): Example
|
||||
operator fun unaryMinus(o: Example)
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryPlus(s: String = ""): Example
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryMinus(o: Example)
|
||||
|
||||
operator fun inc(): Example
|
||||
operator fun dec(): Example?
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun dec(): Example?
|
||||
|
||||
operator fun plusAssign(n: Int)
|
||||
operator fun minusAssign(n: Int): String
|
||||
operator fun divAssign(n: Int, a: String = "")
|
||||
operator fun modAssign(vararg n: Int)
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minusAssign(n: Int): String
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun divAssign(n: Int, a: String = "")
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun modAssign(vararg n: Int)
|
||||
|
||||
operator fun compareTo(other: Example): Int
|
||||
|
||||
override operator fun equals(other: Any?): Boolean
|
||||
operator fun equals(a: String): Boolean
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun equals(a: String): Boolean
|
||||
|
||||
operator fun contains(n: Int): Boolean
|
||||
operator fun contains(n: Int, s: String = ""): Boolean
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun contains(n: Int, s: String = ""): Boolean
|
||||
|
||||
operator fun invoke()
|
||||
|
||||
operator fun get(n: Int)
|
||||
operator fun get(n: Int, n2: Int)
|
||||
operator fun get()
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun get()
|
||||
|
||||
operator fun set(n: Int, v: Int)
|
||||
operator fun set(n: Int, n2: Int, v: Int)
|
||||
operator fun set(v: Int)
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set(v: Int)
|
||||
|
||||
operator fun rangeTo(o: Int)
|
||||
operator fun rangeTo(o: Int, o2: Int)
|
||||
operator fun rangeTo(vararg o: String)
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun rangeTo(o: Int, o2: Int)
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun rangeTo(vararg o: String)
|
||||
|
||||
operator fun component1(): Int
|
||||
operator fun component1(n: Int): Int
|
||||
operator fun componentN(): Int
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun component1(n: Int): Int
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun componentN(): Int
|
||||
|
||||
operator fun iterator(): String
|
||||
operator fun iterator(n: Int): String
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun iterator(n: Int): String
|
||||
|
||||
operator fun next(): String
|
||||
operator fun next(n: Int): String
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun next(n: Int): String
|
||||
|
||||
operator fun hasNext(): Boolean
|
||||
operator fun hasNext(n: Int): String
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hasNext(n: Int): String
|
||||
|
||||
infix fun i1(n: Int)
|
||||
<!INAPPLICABLE_INFIX_MODIFIER!>infix fun i1(n: Int, n2: Int)<!>
|
||||
@@ -72,27 +72,27 @@ class OkDelegates {
|
||||
}
|
||||
|
||||
class DelegatesWithErrors {
|
||||
operator fun getValue(thisRef: Any?, prop: String): String = ""
|
||||
operator fun setValue(thisRef: Any?, prop: String, value: String) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun getValue(thisRef: Any?, prop: String): String = ""
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun setValue(thisRef: Any?, prop: String, value: String) {}
|
||||
|
||||
operator fun setValue(thisRef: Any?, prop: KProperty<*>, vararg n: Int) {}
|
||||
operator fun setValue(thisRef: Any?, prop: KProperty<*>, f: Float = 0.0f) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun setValue(thisRef: Any?, prop: KProperty<*>, vararg n: Int) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun setValue(thisRef: Any?, prop: KProperty<*>, f: Float = 0.0f) {}
|
||||
|
||||
operator fun getValue(prop: KProperty<*>): String = ""
|
||||
operator fun setValue(prop: KProperty<*>, value: String) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun getValue(prop: KProperty<*>): String = ""
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun setValue(prop: KProperty<*>, value: String) {}
|
||||
}
|
||||
|
||||
interface Example2 {
|
||||
operator fun inc(s: String): Example
|
||||
operator fun dec()
|
||||
operator fun compareTo(vararg other: Example): Int
|
||||
operator fun contains(vararg n: Int): Boolean
|
||||
operator fun hasNext(): Int
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun inc(s: String): Example
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun dec()
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun compareTo(vararg other: Example): Int
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun contains(vararg n: Int): Boolean
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hasNext(): Int
|
||||
}
|
||||
|
||||
interface Example3 {
|
||||
operator fun compareTo(other: Example, s: String = ""): Int
|
||||
operator fun contains(n: Int)
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun compareTo(other: Example, s: String = ""): Int
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun contains(n: Int)
|
||||
}
|
||||
|
||||
|
||||
@@ -100,58 +100,58 @@ interface Example3 {
|
||||
|
||||
operator fun Example.plus(o: Any): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.div(o: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.plus(o: Example, s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.minus(vararg o: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.plus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.minus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.plus(o: Example, s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.minus(vararg o: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.plus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.minus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun Example.unaryPlus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.unaryMinus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun Example.unaryPlus(s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.unaryMinus(o: Example) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.unaryPlus(s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.unaryMinus(o: Example) {}
|
||||
|
||||
operator fun Example.inc(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.dec(): Example? {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.dec(): Example? {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun Example.plusAssign(n: Int) {}
|
||||
operator fun Example.minusAssign(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.divAssign(n: Int, a: String = "") {}
|
||||
operator fun Example.modAssign(vararg n: Int) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.minusAssign(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.divAssign(n: Int, a: String = "") {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.modAssign(vararg n: Int) {}
|
||||
|
||||
operator fun Example.compareTo(other: Example): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun Example.equals(a: String): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.equals(a: String): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun Example.contains(n: Int): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.contains(n: Int, s: String = ""): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.contains(n: Int, s: String = ""): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun Example.invoke() {}
|
||||
|
||||
operator fun Example.get(n: Int) {}
|
||||
operator fun Example.get(n: Int, n2: Int) {}
|
||||
operator fun Example.get() {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.get() {}
|
||||
|
||||
operator fun Example.set(n: Int, v: Int) {}
|
||||
operator fun Example.set(n: Int, n2: Int, v: Int) {}
|
||||
operator fun Example.set(v: Int) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.set(v: Int) {}
|
||||
|
||||
operator fun Example.rangeTo(o: Int) {}
|
||||
operator fun Example.rangeTo(o: Int, o2: Int) {}
|
||||
operator fun Example.rangeTo(vararg o: String) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.rangeTo(o: Int, o2: Int) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.rangeTo(vararg o: String) {}
|
||||
|
||||
operator fun Example.component1(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.component1(n: Int): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.componentN(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.component1(n: Int): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.componentN(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun Example.iterator(): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.iterator(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.iterator(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun Example.next(): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.next(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.next(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun Example.hasNext(): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun Example.hasNext(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.hasNext(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
infix fun Example.i1(n: Int) {}
|
||||
<!INAPPLICABLE_INFIX_MODIFIER!>infix fun Example.i1(n: Int, n2: Int) {}<!>
|
||||
@@ -161,58 +161,58 @@ infix fun Example.i1(vararg n: Int) {}
|
||||
|
||||
|
||||
|
||||
operator fun plus(o: String): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun div(o: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun plus(o: Example, s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun minus(vararg o: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(o: String): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun div(o: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(o: Example, s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minus(vararg o: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun unaryPlus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun unaryMinus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryPlus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryMinus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun unaryPlus(s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun unaryMinus(o: Example) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryPlus(s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryMinus(o: Example) {}
|
||||
|
||||
operator fun inc(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun dec(): Example? {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun inc(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun dec(): Example? {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun plusAssign(n: Int) {}
|
||||
operator fun minusAssign(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun divAssign(n: Int, a: String = "") {}
|
||||
operator fun modAssign(vararg n: Int) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plusAssign(n: Int) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minusAssign(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun divAssign(n: Int, a: String = "") {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun modAssign(vararg n: Int) {}
|
||||
|
||||
operator fun compareTo(other: Example): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun compareTo(other: Example): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun equals(a: String): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun equals(a: String): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun contains(n: Int): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun contains(n: Int, s: String = ""): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun contains(n: Int): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun contains(n: Int, s: String = ""): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun invoke() {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun invoke() {}
|
||||
|
||||
operator fun get(n: Int) {}
|
||||
operator fun get(n: Int, n2: Int) {}
|
||||
operator fun get() {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun get(n: Int) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun get(n: Int, n2: Int) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun get() {}
|
||||
|
||||
operator fun set(n: Int, v: Int) {}
|
||||
operator fun set(n: Int, n2: Int, v: Int) {}
|
||||
operator fun set(v: Int) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set(n: Int, v: Int) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set(n: Int, n2: Int, v: Int) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set(v: Int) {}
|
||||
|
||||
operator fun rangeTo(o: Int) {}
|
||||
operator fun rangeTo(o: Int, o2: Int) {}
|
||||
operator fun rangeTo(vararg o: String) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun rangeTo(o: Int) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun rangeTo(o: Int, o2: Int) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun rangeTo(vararg o: String) {}
|
||||
|
||||
operator fun component1(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun component1(n: Int): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun componentN(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun component1(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun component1(n: Int): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun componentN(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun iterator(): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun iterator(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun iterator(): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun iterator(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun next(): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun next(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun next(): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun next(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
operator fun hasNext(): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
operator fun hasNext(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hasNext(): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hasNext(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
<!INAPPLICABLE_INFIX_MODIFIER!>infix fun i1(n: Int) {}<!>
|
||||
<!INAPPLICABLE_INFIX_MODIFIER!>infix fun i1(n: Int, n2: Int) {}<!>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
class A {
|
||||
operator fun A.minus(o: A) = o
|
||||
|
||||
operator fun A.add(o: A) = o
|
||||
operator fun A.get(o: A) = o
|
||||
operator fun A.invokee() {}
|
||||
}
|
||||
|
||||
operator fun A.plus(o: A) = o
|
||||
operator fun A.component1() = 1
|
||||
operator fun A.componentN() = 1
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class A {
|
||||
operator fun A.minus(o: A) = o
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ fun main() {
|
||||
join(1, "2", "3")
|
||||
join(<!NON_VARARG_SPREAD!>*<!>1, "2")
|
||||
join(1, *<!ARGUMENT_TYPE_MISMATCH!>"2"<!>)
|
||||
join(x = 1, a = "2")
|
||||
join(x = 1, a = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>"2"<!>)
|
||||
join(x = *1, a = *"2")
|
||||
join(x = 1, a = a)
|
||||
join(x = 1, a = <!ARGUMENT_TYPE_MISMATCH!>b<!>)
|
||||
@@ -32,7 +32,7 @@ fun main() {
|
||||
joinG<String>(<!NON_VARARG_SPREAD!>*<!>1, "2")
|
||||
joinG<String>(1, *<!ARGUMENT_TYPE_MISMATCH!>"2"<!>)
|
||||
joinG<String>(x = 1, a = a)
|
||||
joinG<String>(x = 1, a = "2")
|
||||
joinG<String>(x = 1, a = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>"2"<!>)
|
||||
joinG<String>(x = *1, a = *"2")
|
||||
joinG<String>(1, *a)
|
||||
joinG<String>(1, *a, "3")
|
||||
@@ -45,7 +45,7 @@ fun main() {
|
||||
joinG(<!NON_VARARG_SPREAD!>*<!>1, "2")
|
||||
joinG(1, *<!ARGUMENT_TYPE_MISMATCH!>"2"<!>)
|
||||
joinG(x = 1, a = a)
|
||||
joinG(x = 1, a = "2")
|
||||
joinG(x = 1, a = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>"2"<!>)
|
||||
joinG(x = *1, a = *"2")
|
||||
joinG(1, *a)
|
||||
joinG(1, *a, "3")
|
||||
|
||||
@@ -16,7 +16,7 @@ object D {
|
||||
}
|
||||
|
||||
object Z {
|
||||
operator fun set() {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class MyProperty2<T, R> {
|
||||
throw Exception()
|
||||
}
|
||||
|
||||
operator fun setValue(i: Int) {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun setValue(i: Int) {
|
||||
println("set")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
operator fun provideDelegate(x: Any?, p: KProperty<*>) {}
|
||||
|
||||
operator fun Any.provideDelegate(x: Any?, p: KProperty<*>) {}
|
||||
|
||||
operator fun Any.provideDelegate(x: Any?, p: Any) {}
|
||||
|
||||
operator fun Any.provideDelegate(x: Any?, p: Int) {}
|
||||
|
||||
class Host1 {
|
||||
operator fun provideDelegate(x: Any?, p: KProperty<*>) {}
|
||||
}
|
||||
|
||||
class Host2 {
|
||||
operator fun Any.provideDelegate(x: Any?, p: KProperty<*>) {}
|
||||
}
|
||||
|
||||
class Host3 {
|
||||
operator fun provideDelegate(x: Any?, p: KProperty<*>, foo: Int) {}
|
||||
}
|
||||
|
||||
class Host4 {
|
||||
operator fun provideDelegate(x: Any?, p: KProperty<*>, foo: Int = 0) {}
|
||||
}
|
||||
|
||||
class Host5 {
|
||||
operator fun provideDelegate(x: Any?, p: KProperty<*>, vararg foo: Int) {}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
operator fun <T, U> Function1<T, U>.minusAssign(p: Function1<T, U>) {}
|
||||
|
||||
inline operator fun <T, U> Function1<T, U>.modAssign(p: Function1<T, U>) = {
|
||||
inline <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun <T, U> Function1<T, U>.modAssign(p: Function1<T, U>) = {
|
||||
this += p
|
||||
p += this
|
||||
}
|
||||
@@ -14,7 +14,7 @@ inline operator fun <T, U> Function1<T, U>.plusAssign(p: Function1<T, U>) {
|
||||
|
||||
operator fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.minusAssign(ext : @ExtensionFunctionType Function2<T, U, V>) {}
|
||||
|
||||
inline operator fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.modAssign(ext : @ExtensionFunctionType Function2<T, U, V>) = {
|
||||
inline <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.modAssign(ext : @ExtensionFunctionType Function2<T, U, V>) = {
|
||||
this += ext
|
||||
ext += this
|
||||
}
|
||||
|
||||
23
compiler/testData/diagnostics/tests/j+k/integerNotNullable.kt
vendored
Normal file
23
compiler/testData/diagnostics/tests/j+k/integerNotNullable.kt
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: Box.java
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Box<T> {
|
||||
public void put(@NotNull T t) {}
|
||||
}
|
||||
|
||||
// FILE: IntBox.java
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class IntBox extends Box<Integer> {
|
||||
public int result = 0;
|
||||
@Override
|
||||
public void put(@NotNull Integer t) {
|
||||
result = t;
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main() {
|
||||
IntBox().put(1)
|
||||
}
|
||||
20
compiler/testData/diagnostics/tests/j+k/integerNotNullable.txt
vendored
Normal file
20
compiler/testData/diagnostics/tests/j+k/integerNotNullable.txt
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
package
|
||||
|
||||
public fun main(): kotlin.Unit
|
||||
|
||||
public open class Box</*0*/ T : kotlin.Any!> {
|
||||
public constructor Box</*0*/ T : kotlin.Any!>()
|
||||
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 fun put(/*0*/ @org.jetbrains.annotations.NotNull t: T!!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class IntBox : Box<kotlin.Int!> {
|
||||
public constructor IntBox()
|
||||
public final var result: kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
@java.lang.Override public open override /*1*/ fun put(/*0*/ @org.jetbrains.annotations.NotNull t: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
// FILE: A.java
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
public class A {
|
||||
public void foo(int x) {}
|
||||
public void bar(@NotNull Double x) {}
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
import org.jetbrains.annotations.*;
|
||||
public class B extends A {
|
||||
public void foo(@NotNull Integer x) {}
|
||||
public void bar(double x) {}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun foo(b: B) {
|
||||
// See KT-9182
|
||||
b.foo(1)
|
||||
b.bar(2.0)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: A.java
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
// FILE: AbstractSpecializedMap.java
|
||||
public abstract class AbstractSpecializedMap implements java.util.Map<Integer, Double> {
|
||||
public abstract double put(int x, double y);
|
||||
public abstract double remove(int k);
|
||||
public abstract double get(int k);
|
||||
|
||||
public abstract boolean containsKey(int k);
|
||||
public boolean containsKey(Object x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract boolean containsValue(double v);
|
||||
public boolean containsValue(Object x) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: SpecializedMap.java
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class SpecializedMap extends AbstractSpecializedMap {
|
||||
public double put(int x, double y) {
|
||||
return 123.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double get(Object key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double put(Integer key, Double value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public double remove(int k) {
|
||||
return 456.0;
|
||||
}
|
||||
|
||||
|
||||
public Double remove(Object ok) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public double get(int k) {
|
||||
return 789.0;
|
||||
}
|
||||
|
||||
public boolean containsKey(int k) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean containsValue(double v) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends Integer, ? extends Double> m) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<Integer> keySet() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<Double> values() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<Entry<Integer, Double>> entrySet() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
fun foo(x: SpecializedMap) {
|
||||
x.containsKey(1)
|
||||
x.containsKey(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
|
||||
x.<!OVERLOAD_RESOLUTION_AMBIGUITY!>get<!>(2)
|
||||
x.<!NONE_APPLICABLE!>get<!>(null)
|
||||
|
||||
x.<!OVERLOAD_RESOLUTION_AMBIGUITY!>remove<!>(3)
|
||||
x.<!NONE_APPLICABLE!>remove<!>(null)
|
||||
|
||||
x.put(4, 5.0)
|
||||
x.put(4, null)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: AbstractSpecializedMap.java
|
||||
public abstract class AbstractSpecializedMap implements java.util.Map<Integer, Double> {
|
||||
public abstract double put(int x, double y);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
class C {
|
||||
operator fun compareTo(c: C): Int? = null
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun compareTo(c: C): Int? = null
|
||||
}
|
||||
|
||||
fun test(c: C) {
|
||||
@@ -9,4 +9,4 @@ fun test(c: C) {
|
||||
c <= c
|
||||
c >= c
|
||||
c > c
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
//KT-1028 Wrong type checking for plusAssign
|
||||
package kt1028
|
||||
|
||||
import java.util.*
|
||||
|
||||
class event<T>()
|
||||
{
|
||||
val callbacks = ArrayList< Function1<T, Unit> >() // Should be ArrayList<()->Unit>, bug posted
|
||||
|
||||
operator fun plusAssign(f : (T) -> Unit) = callbacks.add(f)
|
||||
operator fun minusAssign(f : (T) -> Unit) = callbacks.remove(f)
|
||||
fun call(value : T) { for(c in callbacks) c(value) }
|
||||
}
|
||||
|
||||
class MouseMovedEventArgs()
|
||||
{
|
||||
public val X : Int = 0
|
||||
}
|
||||
|
||||
class Control()
|
||||
{
|
||||
public val MouseMoved : event<MouseMovedEventArgs> = event<MouseMovedEventArgs>()
|
||||
|
||||
fun MoveMouse() = MouseMoved.call(MouseMovedEventArgs())
|
||||
}
|
||||
|
||||
class Test()
|
||||
{
|
||||
fun test()
|
||||
{
|
||||
val control = Control()
|
||||
control.MouseMoved <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>+=<!> { it.X } // here
|
||||
control.MouseMoved.plusAssign( { it.X } ) // ok
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
//KT-1028 Wrong type checking for plusAssign
|
||||
package kt1028
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
package lol
|
||||
|
||||
class B() {
|
||||
operator fun plusAssign(other : B) : String {
|
||||
return "s"
|
||||
}
|
||||
operator fun minusAssign(other : B) : String {
|
||||
return "s"
|
||||
}
|
||||
operator fun remAssign(other : B) : String {
|
||||
return "s"
|
||||
}
|
||||
operator fun divAssign(other : B) : String {
|
||||
return "s"
|
||||
}
|
||||
operator fun timesAssign(other : B) : String {
|
||||
return "s"
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
var c = B()
|
||||
c <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>+=<!> B()
|
||||
c <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>*=<!> B()
|
||||
c <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>/=<!> B()
|
||||
c <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>-=<!> B()
|
||||
c <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>%=<!> B()
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
package lol
|
||||
|
||||
class B() {
|
||||
|
||||
@@ -8,6 +8,6 @@ fun overloadedFun(arg: String, vararg args: String) = X1
|
||||
fun overloadedFun(arg: String, vararg args: String, flag: Boolean = true) = X2
|
||||
|
||||
val test1a: X1 = overloadedFun("", "")
|
||||
val test1b: X1 = overloadedFun("", args = "")
|
||||
val test1b: X1 = overloadedFun("", args = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>""<!>)
|
||||
val test1c: X2 = overloadedFun("", "", "", flag = true)
|
||||
|
||||
|
||||
@@ -9,5 +9,5 @@ fun overloadedFun5(s: String, vararg ss: String) = X2
|
||||
|
||||
val test1 = overloadedFun5("")
|
||||
val test2 = overloadedFun5("", "")
|
||||
val test3: X2 = overloadedFun5(s = "", ss = "")
|
||||
val test4: X1 = overloadedFun5(ss = "")
|
||||
val test3: X2 = overloadedFun5(s = "", ss = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>""<!>)
|
||||
val test4: X1 = overloadedFun5(ss = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>""<!>)
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
class IncDec {
|
||||
operator fun inc(): Unit {}
|
||||
}
|
||||
|
||||
fun foo(): IncDec {
|
||||
var x = IncDec()
|
||||
x = x<!INC_DEC_SHOULD_NOT_RETURN_UNIT!>++<!>
|
||||
x<!INC_DEC_SHOULD_NOT_RETURN_UNIT!>++<!>
|
||||
return x
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class IncDec {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun inc(): Unit {}
|
||||
}
|
||||
|
||||
25
compiler/testData/diagnostics/tests/smartCasts/publicVals/otherModuleInheritance.fir.kt
vendored
Normal file
25
compiler/testData/diagnostics/tests/smartCasts/publicVals/otherModuleInheritance.fir.kt
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// MODULE: m1
|
||||
// FILE: A.kt
|
||||
|
||||
open class Base(val x: Any)
|
||||
open class Generic<T>(val y: T)
|
||||
|
||||
// MODULE: m2(m1)
|
||||
// FILE: B.kt
|
||||
|
||||
class Derived : Base("123") {
|
||||
fun foo() {
|
||||
if (x is String) {
|
||||
<!SMARTCAST_IMPOSSIBLE!>x<!>.length // impossible since `x` is in another module. FE1.0 allows this due to KT-47225
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MyGeneric : Generic<Number>(42) {
|
||||
private fun baz(arg: Int) {}
|
||||
fun bar() {
|
||||
if (y is Int) {
|
||||
baz(<!SMARTCAST_IMPOSSIBLE!>y<!>) // impossible since `y` is in another module. FE1.0 allows this due to KT-47225
|
||||
}
|
||||
}
|
||||
}
|
||||
25
compiler/testData/diagnostics/tests/smartCasts/publicVals/otherModuleInheritance.kt
vendored
Normal file
25
compiler/testData/diagnostics/tests/smartCasts/publicVals/otherModuleInheritance.kt
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// MODULE: m1
|
||||
// FILE: A.kt
|
||||
|
||||
open class Base(val x: Any)
|
||||
open class Generic<T>(val y: T)
|
||||
|
||||
// MODULE: m2(m1)
|
||||
// FILE: B.kt
|
||||
|
||||
class Derived : Base("123") {
|
||||
fun foo() {
|
||||
if (x is String) {
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.length // impossible since `x` is in another module. FE1.0 allows this due to KT-47225
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MyGeneric : Generic<Number>(42) {
|
||||
private fun baz(arg: Int) {}
|
||||
fun bar() {
|
||||
if (y is Int) {
|
||||
baz(<!DEBUG_INFO_SMARTCAST!>y<!>) // impossible since `y` is in another module. FE1.0 allows this due to KT-47225
|
||||
}
|
||||
}
|
||||
}
|
||||
40
compiler/testData/diagnostics/tests/smartCasts/publicVals/otherModuleInheritance.txt
vendored
Normal file
40
compiler/testData/diagnostics/tests/smartCasts/publicVals/otherModuleInheritance.txt
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// -- Module: <m1> --
|
||||
package
|
||||
|
||||
public open class Base {
|
||||
public constructor Base(/*0*/ x: kotlin.Any)
|
||||
public final val x: kotlin.Any
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class Generic</*0*/ T> {
|
||||
public constructor Generic</*0*/ T>(/*0*/ y: T)
|
||||
public final val y: 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
|
||||
}
|
||||
|
||||
// -- Module: <m2> --
|
||||
package
|
||||
|
||||
public final class Derived : Base {
|
||||
public constructor Derived()
|
||||
public final override /*1*/ /*fake_override*/ val x: kotlin.Any
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class MyGeneric : Generic<kotlin.Number> {
|
||||
public constructor MyGeneric()
|
||||
public final override /*1*/ /*fake_override*/ val y: kotlin.Number
|
||||
public final fun bar(): kotlin.Unit
|
||||
private final fun baz(/*0*/ arg: kotlin.Int): kotlin.Unit
|
||||
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
|
||||
}
|
||||
@@ -11,11 +11,11 @@ fun foo() {}
|
||||
fun test_fun(s: String, arr: Array<String>) {
|
||||
withVararg(<!ARGUMENT_TYPE_MISMATCH!>arr<!>) // Error
|
||||
withVararg(*arr) // OK
|
||||
withVararg(s = arr) // Error
|
||||
withVararg(s = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>arr<!>) // Error
|
||||
withVararg(s = *arr) // OK
|
||||
|
||||
withVararg(s) // OK
|
||||
withVararg(s = <!ARGUMENT_TYPE_MISMATCH!>s<!>) // Error
|
||||
withVararg(s = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>s<!>) // Error
|
||||
}
|
||||
|
||||
fun test_ann(s: String, arr: Array<String>) {
|
||||
@@ -30,6 +30,6 @@ fun test_ann(s: String, arr: Array<String>) {
|
||||
|
||||
@Ann("", x = 1)
|
||||
foo()
|
||||
@Ann(s = "", x = 1)
|
||||
@Ann(s = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION_ERROR!>""<!>, x = 1)
|
||||
foo()
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ fun test_fun(s: String, arr: Array<String>) {
|
||||
withVararg(s = *arr) // Warning
|
||||
|
||||
withVararg(s) // OK
|
||||
withVararg(s = <!ARGUMENT_TYPE_MISMATCH!>s<!>) // Error
|
||||
withVararg(s = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>s<!>) // Error
|
||||
}
|
||||
|
||||
fun test_ann(s: String, arr: Array<String>) {
|
||||
@@ -30,6 +30,6 @@ fun test_ann(s: String, arr: Array<String>) {
|
||||
|
||||
@Ann("", x = 1)
|
||||
foo()
|
||||
@Ann(s = "", x = 1)
|
||||
@Ann(s = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION_ERROR!>""<!>, x = 1)
|
||||
foo()
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user