Files
kotlin-fork/compiler/testData/diagnostics/tests/declarationChecks/namedFunAsLastExpressionInBlock.fir.kt
T
Tianyu Geng d6907222cd FIR: pass the qualified access source when reporting ErrorNamedReference
Currently if there is an error in a function call, FIR would report the
entire expression if this call is qualified, but *only* the name if it's
not qualified. For example, assume the following two calls are all
contains some errors.

```
a.foo(1,2,3)
^^^^^^^^^^^^
bar(1,2,3)
^^^
```

The entire call of `foo` is reported since it's qualified. But only the
reference `bar` is reported since it's not qualified. This limits the
usage of position strategies because the IDE does not allow position
strategies to go outside of the initially reported PSI element
(org.jetbrains.kotlin.idea.fir.highlighter.KotlinHighLevelDiagnosticHighlightingPass#addDiagnostic).

This change passes both the original error named reference and the
surrounding qualified access expression and defer the decision of which
to use to the reporting logic.

For unresolved reference and checks on `super` keyword, the position
strategy should not highlight the surrounding parentheses. Hence a new
position strategy `REFERENCED_NAME_BY_QUALIFIED` is added.

In addition, this change also has the following side effect

* some diagnostics are no longer reported when there is a syntax error
  since the higher level structure does not exist when there is a syntax
  error
2021-03-29 12:45:27 +03:00

76 lines
1.7 KiB
Kotlin
Vendored

// !WITH_NEW_INFERENCE
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
// !CHECK_TYPE
fun foo(block: () -> (() -> Int)) {}
fun test() {
val x = <!EXPRESSION_REQUIRED!>fun named1(x: Int): Int { return 1 }<!>
x <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Function1<Int, Int>>() }
foo { fun named2(): Int {return 1} }
foo({ fun named3() = 1 })
val x1 =
if (1 == 1)
// TODO: Diagnostic content could be better
<!SYNTAX!><!>fun named4(): Int {return 1}
<!SYNTAX!>else<!>
fun named5() = 1
val x2 =
if (1 == 1) {
fun named6(): Int {
return 1
}
}
else
<!SYNTAX!><!>fun named7() = 1
val x3 = when (1) {
0 -> fun named8(): Int {return 1}
else -> fun named9() = 1
}
val x31 = when (1) {
0 -> {
fun named10(): Int {return 1}
}
else -> fun named11() = 1
}
val x4 = {
y: Int -> fun named12(): Int {return 1}
}
x4 checkType { _<Function1<Int, Unit>>() }
{ y: Int -> fun named14(): Int {return 1} }
val b = (<!EXPRESSION_REQUIRED, UNRESOLVED_REFERENCE!>fun named15(): Boolean { return true }<!>)()
baz(<!EXPRESSION_REQUIRED!>fun named16(){}<!>)
}
fun bar() = <!EXPRESSION_REQUIRED!>fun named() {}<!>
fun <T> run(block: () -> T): T = null!!
fun run2(block: () -> Unit): Unit = null!!
fun baz(obj: Any?) {}
fun success() {
run { fun named1() = 1 }
run2 { fun named2() = 1 }
val x = run { fun named3() = 1 }
x checkType { _<Unit>() }
val y = when (1) {
0 -> {
fun named4(): Int {return 1}
}
else -> {
fun named5(): Int {return 1}
}
}
y checkType { _<Unit>() }
}