[FIR] KT-54978 Prohibit explicit type arguments in property accesses

- Add a checker which ensures that property accesses have no explicit
  type arguments. If an error on the property access's callee reference
  already exists, the new error is not reported in favor of the existing
  error, as the property access may have been intended to be a function
  call.
- `complicatedLTGT.fir.kt`: The underlying parser issue is not yet
  solved, which is why `x` is parsed as a property access with explicit
  type arguments.
- `reservedExpressionSyntax` tests: This new check makes a lot of the
  access expressions in these tests illegal, so valid lines have been
  added and invalid lines appropriately marked with
  `EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS` errors.

^KT-54978 fixed
This commit is contained in:
Marco Pennekamp
2022-11-23 16:04:07 +01:00
committed by teamcity
parent 4d20b43619
commit d4e6a4ad54
26 changed files with 281 additions and 16 deletions
@@ -17,17 +17,19 @@ class Test {
val <T> List<T>.a: Int get() = size
val <T> List<T>.b: Int? get() = size
fun <T> List<T>.testCallable1(): () -> Unit = a<T>::foo
fun <T> List<T>.testCallable1(): () -> Unit = a::foo
fun <T> List<T>.testCallable1a(): () -> Unit = <!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>a<!><T>::foo
fun <T> List<T>.testCallable2(): () -> Unit = b?::<!UNRESOLVED_REFERENCE!>foo<!>
fun <T> List<T>.testCallable3(): () -> Unit = b<T, Any>::<!UNRESOLVED_REFERENCE!>foo<!>
fun <T> List<T>.testCallable4(): () -> Unit = b<T>?::<!UNRESOLVED_REFERENCE!>foo<!>
fun <T> List<T>.testCallable3(): () -> Unit = <!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>b<!><T, Any>::<!UNRESOLVED_REFERENCE!>foo<!>
fun <T> List<T>.testCallable4(): () -> Unit = <!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>b<!><T>?::<!UNRESOLVED_REFERENCE!>foo<!>
fun <T> List<T>.testClassLiteral1() = a<T>::class
fun <T> List<T>.testClassLiteral1() = a::class
fun <T> List<T>.testClassLiteral1a() = <!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>a<!><T>::class
fun <T> List<T>.testClassLiteral2() = <!EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS!>b<!>?::class
fun <T> List<T>.testClassLiteral3() = <!EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS!>b<T, Any><!>::class
fun <T> List<T>.testClassLiteral3() = <!EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS!><!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>b<!><T, Any><!>::class
fun <T> List<T>.testUnresolved1() = <!UNRESOLVED_REFERENCE!>unresolved<!><T>::foo
fun <T> List<T>.testUnresolved2() = a<<!UNRESOLVED_REFERENCE!>unresolved<!>>::foo
fun <T> List<T>.testUnresolved2() = <!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>a<!><<!UNRESOLVED_REFERENCE!>unresolved<!>>::foo
fun <T> List<T>.testUnresolved3() = a<<!SYNTAX!><!>>::foo
fun <T> List<T>.testUnresolved4() = <!UNRESOLVED_REFERENCE!>unresolved<!>?::foo
}
@@ -17,12 +17,14 @@ class Test {
val <T> List<T>.a: Int get() = size
val <T> List<T>.b: Int? get() = size
fun <T> List<T>.testCallable1(): () -> Unit = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>a<T><!>::foo
fun <T> List<T>.testCallable1(): () -> Unit = a::foo
fun <T> List<T>.testCallable1a(): () -> Unit = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>a<T><!>::foo
fun <T> List<T>.testCallable2(): () -> Unit = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>b<!>?::<!TYPE_MISMATCH, UNSAFE_CALL!>foo<!>
fun <T> List<T>.testCallable3(): () -> Unit = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>b<T, Any><!>::<!TYPE_MISMATCH, UNSAFE_CALL!>foo<!>
fun <T> List<T>.testCallable4(): () -> Unit = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>b<T><!>?::<!TYPE_MISMATCH, UNSAFE_CALL!>foo<!>
fun <T> List<T>.testClassLiteral1() = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>a<T><!>::class
fun <T> List<T>.testClassLiteral1() = a::class
fun <T> List<T>.testClassLiteral1a() = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>a<T><!>::class
fun <T> List<T>.testClassLiteral2() = <!EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>b<!>?::class
fun <T> List<T>.testClassLiteral3() = <!EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>b<T, Any><!>::class
@@ -18,10 +18,12 @@ package test {
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final fun </*0*/ T> kotlin.collections.List<T>.testCallable1(): () -> kotlin.Unit
public final fun </*0*/ T> kotlin.collections.List<T>.testCallable1a(): () -> kotlin.Unit
public final fun </*0*/ T> kotlin.collections.List<T>.testCallable2(): () -> kotlin.Unit
public final fun </*0*/ T> kotlin.collections.List<T>.testCallable3(): () -> kotlin.Unit
public final fun </*0*/ T> kotlin.collections.List<T>.testCallable4(): () -> kotlin.Unit
public final fun </*0*/ T> kotlin.collections.List<T>.testClassLiteral1(): kotlin.reflect.KClass<out kotlin.Int>
public final fun </*0*/ T> kotlin.collections.List<T>.testClassLiteral1a(): kotlin.reflect.KClass<out kotlin.Int>
public final fun </*0*/ T> kotlin.collections.List<T>.testClassLiteral2(): kotlin.reflect.KClass<out kotlin.Int?>
public final fun </*0*/ T> kotlin.collections.List<T>.testClassLiteral3(): kotlin.reflect.KClass<out kotlin.Int?>
public final fun </*0*/ T> kotlin.collections.List<T>.testUnresolved1(): [Error type: Return type for function cannot be resolved]
@@ -21,8 +21,9 @@ class Test {
val Int.c: Int get() = 42
val test1: () -> Right = a.b<Int>.c::foo
val test1a: () -> Right = a.b.c::foo
val test1: () -> Right = a.b.c::foo
val test1a: () -> Right = a.<!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>b<!><Int>.c::foo
val test2: () -> Right = a.b<Int>.c?::foo
val test2: () -> Right = a.b.c?::foo
val test2a: () -> Right = a.<!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>b<!><Int>.c?::foo
}
@@ -21,8 +21,9 @@ class Test {
val Int.c: Int get() = 42
val test1: () -> Right = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!><!DEBUG_INFO_MISSING_UNRESOLVED!>a<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>b<!><<!DEBUG_INFO_MISSING_UNRESOLVED!>Int<!>>.<!DEBUG_INFO_MISSING_UNRESOLVED!>c<!><!>::<!DEBUG_INFO_MISSING_UNRESOLVED!>foo<!>
val test1a: () -> Right = a.<!DEBUG_INFO_LEAKING_THIS!>b<!>.<!DEBUG_INFO_LEAKING_THIS!>c<!>::foo
val test1: () -> Right = a.<!DEBUG_INFO_LEAKING_THIS!>b<!>.<!DEBUG_INFO_LEAKING_THIS!>c<!>::foo
val test1a: () -> Right = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!><!DEBUG_INFO_MISSING_UNRESOLVED!>a<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>b<!><<!DEBUG_INFO_MISSING_UNRESOLVED!>Int<!>>.<!DEBUG_INFO_MISSING_UNRESOLVED!>c<!><!>::<!DEBUG_INFO_MISSING_UNRESOLVED!>foo<!>
val test2: () -> Right = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!><!DEBUG_INFO_MISSING_UNRESOLVED!>a<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>b<!><<!DEBUG_INFO_MISSING_UNRESOLVED!>Int<!>>.<!DEBUG_INFO_MISSING_UNRESOLVED!>c<!><!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>foo<!>
val test2: () -> Right = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>a.<!DEBUG_INFO_LEAKING_THIS!>b<!>.<!DEBUG_INFO_LEAKING_THIS!>c<!><!>?::foo
val test2a: () -> Right = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!><!DEBUG_INFO_MISSING_UNRESOLVED!>a<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>b<!><<!DEBUG_INFO_MISSING_UNRESOLVED!>Int<!>>.<!DEBUG_INFO_MISSING_UNRESOLVED!>c<!><!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>foo<!>
}
@@ -16,6 +16,7 @@ package test {
public final val test1: () -> test.Right
public final val test1a: () -> test.Right
public final val test2: () -> test.Right
public final val test2a: () -> test.Right
public final val </*0*/ T> kotlin.collections.List<T>.b: kotlin.Int
public final val kotlin.Int.c: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -2,7 +2,7 @@
// ISSUE: KT-8263
fun test(x: Int, y: Int) {
if (<!CONDITION_TYPE_MISMATCH!>x < (<!SYNTAX!>if<!><!SYNTAX!><!> <!SYNTAX!>(<!><!UNRESOLVED_REFERENCE!><!SYNTAX!><!>y<!> ><!><!SYNTAX!><!> 115<!SYNTAX!>) 1 else 2))<!> {
if (<!CONDITION_TYPE_MISMATCH!><!EXPLICIT_TYPE_ARGUMENTS_IN_PROPERTY_ACCESS!>x<!> < (<!SYNTAX!>if<!><!SYNTAX!><!> <!SYNTAX!>(<!><!UNRESOLVED_REFERENCE!><!SYNTAX!><!>y<!> ><!><!SYNTAX!><!> 115<!SYNTAX!>) 1 else 2))<!> {
Unit
}
}