Commit trace for callable reference's LHS with reserved syntax like foo?::bar?::bar to avoid the lack of diagnostics reporting

^KT-35075 Fixed
This commit is contained in:
Victor Petukhov
2020-06-25 15:41:27 +03:00
parent 1ee8e615fc
commit cbd8b58d5c
7 changed files with 103 additions and 7 deletions
@@ -1999,6 +1999,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/callableReference/whitespacesInExpression.kt");
}
@TestMetadata("withQuestionMarks.kt")
public void testWithQuestionMarks() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt");
}
@TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -325,7 +325,7 @@ class DoubleColonExpressionResolver(
}
private fun resolveReservedExpressionSyntaxOnDoubleColonLHS(doubleColonExpression: KtDoubleColonExpression, c: ExpressionTypingContext):
Pair<Boolean, DoubleColonLHS?> {
ReservedDoubleColonLHSResolutionResult {
val resultForReservedExpr = tryResolveLHS(
doubleColonExpression, c,
this::shouldTryResolveLHSAsReservedExpression,
@@ -335,7 +335,7 @@ class DoubleColonExpressionResolver(
val lhs = resultForReservedExpr.lhs
if (lhs != null) {
c.trace.report(RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS.on(resultForReservedExpr.expression))
return Pair(true, resultForReservedExpr.commit())
return ReservedDoubleColonLHSResolutionResult(true, resultForReservedExpr.commit(), resultForReservedExpr.traceAndCache)
}
}
@@ -349,11 +349,13 @@ class DoubleColonExpressionResolver(
if (lhs != null) {
c.trace.report(RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS.on(resultForReservedCallChain.expression))
// DO NOT commit trace from resultForReservedCallChain here
return Pair(true, null)
return ReservedDoubleColonLHSResolutionResult(true, null, resultForReservedExpr?.traceAndCache)
}
}
return Pair(false, null)
return ReservedDoubleColonLHSResolutionResult(
false, null, resultForReservedExpr?.traceAndCache ?: resultForReservedCallChain?.traceAndCache
)
}
internal fun resolveDoubleColonLHS(doubleColonExpression: KtDoubleColonExpression, c: ExpressionTypingContext): DoubleColonLHS? {
@@ -367,7 +369,9 @@ class DoubleColonExpressionResolver(
}
}
val (isReservedExpressionSyntax, doubleColonLHS) = resolveReservedExpressionSyntaxOnDoubleColonLHS(doubleColonExpression, c)
val (isReservedExpressionSyntax, doubleColonLHS, traceAndCacheFromReservedDoubleColonLHS) =
resolveReservedExpressionSyntaxOnDoubleColonLHS(doubleColonExpression, c)
if (isReservedExpressionSyntax) return doubleColonLHS
val resultForType = tryResolveLHS(doubleColonExpression, c, this::shouldTryResolveLHSAsType) { expression, context ->
@@ -390,14 +394,25 @@ class DoubleColonExpressionResolver(
}
}
// If the LHS could be resolved neither as an expression nor as a type, we should still type-check it to allow all diagnostics
// to be reported and references to be resolved. For that, we commit one of the applicable traces here, preferring the expression
if (resultForExpr != null) return resultForExpr.commit()
if (resultForType != null) return resultForType.commit()
/*
* If the LHS could be resolved neither as an expression nor as a type,
* but it was resolved as expression with reserved syntax like `foo?::bar?::bar`,
* then we commit the trace of that resolution result.
*/
traceAndCacheFromReservedDoubleColonLHS?.commit()
return null
}
private data class ReservedDoubleColonLHSResolutionResult(
val isReservedExpressionSyntax: Boolean,
val lhs: DoubleColonLHS?,
val traceAndCache: TemporaryTraceAndCache?
)
private class LHSResolutionResult<out T : DoubleColonLHS>(
val lhs: T?,
val expression: KtExpression,
@@ -0,0 +1,31 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE
// Issue: KT-35075
fun foo() {}
fun main() {
val x1 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>::info<!>?::print<!>
val x2 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>?::info<!>?::print<!>
val x3 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>?::info<!>::print<!>
val x4 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>?::info<!>?::print<!>?::print<!>?::print<!>?::print<!>?::print<!>?::print<!>?::print<!>?::print<!>?::print<!>?::print<!>
val x5 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>::info<!>?::print<!>?::print<!>?::print<!>?::print<!>?::print<!>?::print<!>?::print<!>?::print<!>?::print<!>?::print<!>
val x6 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>!!::info<!>?::print<!>?::print<!>
val x7 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>::info!!::print<!>?::print<!>
val x8 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>?::info!!::print<!>?::print<!>
val x9 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>!!::info<!>?::print<!>?::print<!>
val x10 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>::info<!>?::print!!::print<!>
val x11 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>!!::info!!::print!!::print<!>
val x12 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>?::info!!::print!!::print<!>
val x13 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>42?::unresolved<!>?::print<!>
val x14 = <!UNRESOLVED_REFERENCE!>logger<!><!SYNTAX!>?!!::info?::print?::print<!>
val x15 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>::info<!><!SYNTAX!>?!!::print?::print<!>
val x16 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>!!?::info<!>?::print<!>?::print<!>
val x17 = <!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!><!UNRESOLVED_REFERENCE!>logger<!>::info!!?::print<!>?::print<!>
// It must be OK
val x18 = String?::hashCode ?: ::foo
val x19 = String::hashCode ?: ::foo
val x20 = String?::hashCode::hashCode
val x21 = kotlin.String?::hashCode::hashCode
}
@@ -0,0 +1,31 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE
// Issue: KT-35075
fun foo() {}
fun main() {
val x1 = <!UNRESOLVED_REFERENCE!>logger<!>::<!DEBUG_INFO_MISSING_UNRESOLVED!>info<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>
val x2 = <!UNRESOLVED_REFERENCE!>logger<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>info<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>
val x3 = <!UNRESOLVED_REFERENCE!>logger<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>info<!>::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>
val x4 = <!UNRESOLVED_REFERENCE!>logger<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>info<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>
val x5 = <!UNRESOLVED_REFERENCE!>logger<!>::<!DEBUG_INFO_MISSING_UNRESOLVED!>info<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>
val x6 = <!UNRESOLVED_REFERENCE!>logger<!>!!::<!DEBUG_INFO_MISSING_UNRESOLVED!>info<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>
val x7 = <!UNRESOLVED_REFERENCE!>logger<!>::<!UNRESOLVED_REFERENCE!>info<!><!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>::<!OVERLOAD_RESOLUTION_AMBIGUITY!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>
val x8 = <!UNRESOLVED_REFERENCE!>logger<!>?::<!UNRESOLVED_REFERENCE!>info<!><!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>::<!OVERLOAD_RESOLUTION_AMBIGUITY!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>
val x9 = <!UNRESOLVED_REFERENCE!>logger<!>!!::<!DEBUG_INFO_MISSING_UNRESOLVED!>info<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>
val x10 = <!UNRESOLVED_REFERENCE!>logger<!>::<!DEBUG_INFO_MISSING_UNRESOLVED!>info<!>?::<!UNRESOLVED_REFERENCE!>print<!><!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>::<!OVERLOAD_RESOLUTION_AMBIGUITY!>print<!>
val x11 = <!UNRESOLVED_REFERENCE!>logger<!>!!::<!UNRESOLVED_REFERENCE!>info<!><!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>print<!><!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>::<!OVERLOAD_RESOLUTION_AMBIGUITY!>print<!>
val x12 = <!UNRESOLVED_REFERENCE!>logger<!>?::<!UNRESOLVED_REFERENCE!>info<!><!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>print<!><!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>::<!OVERLOAD_RESOLUTION_AMBIGUITY!>print<!>
val x13 = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>42<!>?::<!UNRESOLVED_REFERENCE!>unresolved<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>
val x14 = <!UNRESOLVED_REFERENCE!>logger<!><!SYNTAX!>?!!::info?::print?::print<!>
val x15 = <!UNRESOLVED_REFERENCE!>logger<!>::<!DEBUG_INFO_MISSING_UNRESOLVED!>info<!><!SYNTAX!>?!!::print?::print<!>
val x16 = <!UNRESOLVED_REFERENCE!>logger<!>!!?::<!DEBUG_INFO_MISSING_UNRESOLVED!>info<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>
val x17 = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!><!UNRESOLVED_REFERENCE!>logger<!>::<!UNRESOLVED_REFERENCE!>info<!><!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!><!>?::<!OVERLOAD_RESOLUTION_AMBIGUITY!>print<!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>print<!>
// It must be OK
val x18 = String?::hashCode <!USELESS_ELVIS!>?: ::foo<!>
val x19 = String::hashCode <!USELESS_ELVIS!>?: ::foo<!>
val x20 = String?::<!UNSAFE_CALL!>hashCode<!>::hashCode
val x21 = kotlin.String?::<!UNSAFE_CALL!>hashCode<!>::hashCode
}
@@ -0,0 +1,4 @@
package
public fun foo(): kotlin.Unit
public fun main(): kotlin.Unit
@@ -2006,6 +2006,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
runTest("compiler/testData/diagnostics/tests/callableReference/whitespacesInExpression.kt");
}
@TestMetadata("withQuestionMarks.kt")
public void testWithQuestionMarks() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt");
}
@TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -2001,6 +2001,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/callableReference/whitespacesInExpression.kt");
}
@TestMetadata("withQuestionMarks.kt")
public void testWithQuestionMarks() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt");
}
@TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)