Compare commits

...

28 Commits

Author SHA1 Message Date
Svyatoslav Scherbina
99b395b0fa WIP: support Native binary options in Gradle 2021-08-18 18:37:35 +03:00
Svyatoslav Scherbina
0c5bf63844 Native: use binary options machinery for memory model
Old compiler flag (-memory-model) will work too.
2021-08-18 18:29:22 +03:00
Svyatoslav Scherbina
fd7c4c0c2d Native: use binary options machinery for runtime assertions mode 2021-08-18 18:28:19 +03:00
Svyatoslav Scherbina
4a62466671 Native: introduce binary options machinery 2021-08-18 18:27:30 +03:00
pyos
47d0211370 FE: do not enhance ? in jspecify NullMarked scope
No clue whether this should be done for `@TypeQualifierDefault` since it
appears to have no specification whatsoever.

 #KT-48262 Fixed
2021-08-18 16:41:00 +03:00
Jinseong Jeon
5819959cce Consolidate arrayOf call names 2021-08-18 16:04:36 +03:00
Andrey Zinovyev
1cd321a90f [FIR] Add INAPPLICABLE_OPERATOR_MODIFIER diagnostic 2021-08-18 16:03:01 +03:00
Ilya Goncharov
16f41bd80c [Gradle, JS] Use webpack-dev-server rc.1 2021-08-18 15:50:38 +03:00
Mikhael Bogdanov
8ab546ba51 [FIR]: Pass special origins for local functions (named and anonymous) 2021-08-18 09:58:27 +00:00
Mikhael Bogdanov
a5e59e09ee Copy methods for lambdas to DefaultImpls without receiver transformation
#KT-48230 Fixed
2021-08-18 09:58:27 +00:00
pyos
6d7eb2bd21 Add test for KT-48230 2021-08-18 09:58:27 +00:00
Sebastian Sellmair
21f7e16ee6 [Gradle] NativeDistributionCommonizationCache: Acquire FileLock
A `.lock` file will be acquired before running the native
distribution commonizer. This is done to protect data corruption
when multiple process try to commonize at the same time.

This could happen when e.g. two new projects are opened that
both trigger the commonizer during syncing.

^KT-46343 Verification Pending
2021-08-18 09:22:46 +00:00
Tianyu Geng
fb1eac0985 FIR: report SMARTCAST_IMPOSSIBLE on inherited alien properties [KT-48101] 2021-08-18 12:02:02 +03:00
Mikhail Glukhikh
0a6e51e47f FirJavaGenericVarianceViolationTypeChecker: make code a bit more clear 2021-08-18 12:02:01 +03:00
Ilya Goncharov
f37d880964 [Gradle, JS] Add test on valid of webpack config
^KT-48273 fixed
2021-08-18 11:56:19 +03:00
Ivan Kochurkin
301f446433 Restore KtModifierKeywordToken instead of String in modifier diagnostics
Remove KeywordType
2021-08-18 00:45:57 +03:00
Denis.Zharkov
a8077aebb0 FIR: Ignore suspicious test on StrictJavaNullabilityAssertions
^KT-48302 Open
2021-08-17 21:38:01 +03:00
Denis.Zharkov
753ba99b04 FIR: Support enhanced types when checking if Java type is primitive 2021-08-17 21:38:01 +03:00
Denis.Zharkov
a0553f4dfd FIR: Do not build synthetic property named with first capital character 2021-08-17 21:38:01 +03:00
Denis.Zharkov
c3a327e118 FIR: Fix ambiguity on Int2IntMap in IC 2021-08-17 21:38:01 +03:00
Mikhail Glukhikh
1a5552bef8 FIR2IR: fix argument mapping for deserialized annotation #KT-48298 Fixed 2021-08-17 18:22:33 +03:00
Mikhail Glukhikh
6660c9b26b FIR: add test repeating a problem with annotation mapping (KT-48298) 2021-08-17 18:22:33 +03:00
Andrey Zinovyev
ab158a53c3 [FIR] ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION diag 2021-08-17 16:05:42 +03:00
Andrey Zinovyev
1cdbbad367 [FIR] ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION diag 2021-08-17 16:05:42 +03:00
Nikita Bobko
5e87d753b7 Fix coop-dev project import 2021-08-17 13:55:36 +02:00
Ilya Goncharov
a7cc275c7d [Gradle, JS] Update webpack-dev-server
^KT-48273 fixed
2021-08-17 14:44:29 +03:00
Elena Lepilkina
12d694de46 [K/N] Added returns before building DFG 2021-08-17 16:14:07 +05:00
Igor Chevdar
16f0ba8e46 [K/N][optmz] Reworked a bit work with fields 2021-08-17 16:14:07 +05:00
173 changed files with 2195 additions and 1327 deletions

View File

@@ -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")
}

View File

@@ -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
}

View File

@@ -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|)
}

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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")

View File

@@ -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") {

View File

@@ -103,6 +103,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
ABSTRACT_MODIFIER,
LABEL,
COMMAS,
OPERATOR_MODIFIER,
;

View File

@@ -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)
}
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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 }
}

View File

@@ -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>

View File

@@ -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)

View File

@@ -45,6 +45,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
get() = setOf(
FirFunctionNameChecker,
FirFunctionTypeParametersSyntaxChecker,
FirOperatorModifierChecker,
)
override val propertyCheckers: Set<FirPropertyChecker>

View File

@@ -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>

View File

@@ -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
)

View File

@@ -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)
}
}

View File

@@ -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
)

View File

@@ -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())
}
}

View File

@@ -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

View File

@@ -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)
}
}
}
}

View File

@@ -38,7 +38,7 @@ object FirSuspendModifierChecker : FirTypeRefChecker() {
reporter.reportOn(
suspendModifier.source,
FirErrors.WRONG_MODIFIER_TARGET,
suspendModifier.token.toString(),
suspendModifier.token,
"non-functional type",
context
)

View File

@@ -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,

View File

@@ -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)

View File

@@ -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))

View File

@@ -304,4 +304,9 @@ object SourceElementPositioningStrategies {
LightTreePositioningStrategies.INLINE_PARAMETER_MODIFIER,
PositioningStrategies.INLINE_PARAMETER_MODIFIER
)
val OPERATOR_MODIFIER = SourceElementPositioningStrategy(
LightTreePositioningStrategies.OPERATOR_MODIFIER,
PositioningStrategies.OPERATOR_MODIFIER
)
}

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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() =

View File

@@ -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()
}

View File

@@ -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);

View File

@@ -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> {

View File

@@ -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(

View File

@@ -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]!!)
}
}

View File

@@ -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
}
}
/**

View File

@@ -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) }

View File

@@ -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)
}

View File

@@ -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")

View File

@@ -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)
)

View File

@@ -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)
)

View File

@@ -0,0 +1,6 @@
$TESTDATA_DIR$/firVsClassicAnnotation.kt
-classpath
$TESTDATA_DIR$/firVsClassicAnnotation
-Xuse-fir
-d
$TEMP_DIR$

View 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()

View File

@@ -0,0 +1,4 @@
warning: ATTENTION!
This build uses in-dev FIR:
-Xuse-fir
OK

Binary file not shown.

View 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())
}

View File

@@ -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]

View File

@@ -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]

View File

@@ -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.

View 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()
}

View 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()

View 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()

View File

@@ -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)
}

View File

@@ -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)
}
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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)
}
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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() {

View File

@@ -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) {}<!>

View File

@@ -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

View File

@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class A {
operator fun A.minus(o: A) = o

View File

@@ -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")

View File

@@ -16,7 +16,7 @@ object D {
}
object Z {
operator fun set() {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set() {
}
}

View File

@@ -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")
}
}

View File

@@ -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) {}
}

View File

@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER
import kotlin.reflect.KProperty

View File

@@ -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
}

View 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)
}

View 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
}

View File

@@ -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)
}

View File

@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: A.java
import org.jetbrains.annotations.*;

View File

@@ -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)
}

View File

@@ -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);

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -1,3 +1,4 @@
// FIR_IDENTICAL
//KT-1028 Wrong type checking for plusAssign
package kt1028

View File

@@ -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()
}

View File

@@ -1,3 +1,4 @@
// FIR_IDENTICAL
package lol
class B() {

View File

@@ -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)

View File

@@ -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!>""<!>)

View File

@@ -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
}

View File

@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class IncDec {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun inc(): Unit {}
}

View 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
}
}
}

View 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
}
}
}

View 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
}

View File

@@ -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()
}

View File

@@ -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