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:
+5
@@ -1999,6 +1999,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/whitespacesInExpression.kt");
|
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")
|
@TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+22
-7
@@ -325,7 +325,7 @@ class DoubleColonExpressionResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveReservedExpressionSyntaxOnDoubleColonLHS(doubleColonExpression: KtDoubleColonExpression, c: ExpressionTypingContext):
|
private fun resolveReservedExpressionSyntaxOnDoubleColonLHS(doubleColonExpression: KtDoubleColonExpression, c: ExpressionTypingContext):
|
||||||
Pair<Boolean, DoubleColonLHS?> {
|
ReservedDoubleColonLHSResolutionResult {
|
||||||
val resultForReservedExpr = tryResolveLHS(
|
val resultForReservedExpr = tryResolveLHS(
|
||||||
doubleColonExpression, c,
|
doubleColonExpression, c,
|
||||||
this::shouldTryResolveLHSAsReservedExpression,
|
this::shouldTryResolveLHSAsReservedExpression,
|
||||||
@@ -335,7 +335,7 @@ class DoubleColonExpressionResolver(
|
|||||||
val lhs = resultForReservedExpr.lhs
|
val lhs = resultForReservedExpr.lhs
|
||||||
if (lhs != null) {
|
if (lhs != null) {
|
||||||
c.trace.report(RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS.on(resultForReservedExpr.expression))
|
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) {
|
if (lhs != null) {
|
||||||
c.trace.report(RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS.on(resultForReservedCallChain.expression))
|
c.trace.report(RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS.on(resultForReservedCallChain.expression))
|
||||||
// DO NOT commit trace from resultForReservedCallChain here
|
// 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? {
|
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
|
if (isReservedExpressionSyntax) return doubleColonLHS
|
||||||
|
|
||||||
val resultForType = tryResolveLHS(doubleColonExpression, c, this::shouldTryResolveLHSAsType) { expression, context ->
|
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 (resultForExpr != null) return resultForExpr.commit()
|
||||||
if (resultForType != null) return resultForType.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
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private data class ReservedDoubleColonLHSResolutionResult(
|
||||||
|
val isReservedExpressionSyntax: Boolean,
|
||||||
|
val lhs: DoubleColonLHS?,
|
||||||
|
val traceAndCache: TemporaryTraceAndCache?
|
||||||
|
)
|
||||||
|
|
||||||
private class LHSResolutionResult<out T : DoubleColonLHS>(
|
private class LHSResolutionResult<out T : DoubleColonLHS>(
|
||||||
val lhs: T?,
|
val lhs: T?,
|
||||||
val expression: KtExpression,
|
val expression: KtExpression,
|
||||||
|
|||||||
+31
@@ -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");
|
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")
|
@TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Generated
+5
@@ -2001,6 +2001,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/whitespacesInExpression.kt");
|
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")
|
@TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user