FE 1.0: implement typed this label resolve warning for KT-51433
#KT-51433 Fixed
This commit is contained in:
+6
@@ -33575,6 +33575,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("labelClashesWithContextReceivers.kt")
|
||||
public void testLabelClashesWithContextReceivers() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashesWithContextReceivers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("outstar.kt")
|
||||
public void testOutstar() throws Exception {
|
||||
|
||||
+6
@@ -33575,6 +33575,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("labelClashesWithContextReceivers.kt")
|
||||
public void testLabelClashesWithContextReceivers() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashesWithContextReceivers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("outstar.kt")
|
||||
public void testOutstar() throws Exception {
|
||||
|
||||
+6
@@ -33575,6 +33575,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("labelClashesWithContextReceivers.kt")
|
||||
public void testLabelClashesWithContextReceivers() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashesWithContextReceivers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("outstar.kt")
|
||||
public void testOutstar() throws Exception {
|
||||
|
||||
@@ -36,17 +36,24 @@ object LabelResolver {
|
||||
labelName: Name,
|
||||
labelExpression: KtSimpleNameExpression,
|
||||
classNameLabelsEnabled: Boolean
|
||||
): Set<KtElement> {
|
||||
): Pair<Set<KtElement>, KtCallableDeclaration?> {
|
||||
val elements = linkedSetOf<KtElement>()
|
||||
var typedElement: KtCallableDeclaration? = null
|
||||
var parent: PsiElement? = labelExpression.parent
|
||||
while (parent != null) {
|
||||
val names = getLabelNamesIfAny(parent, classNameLabelsEnabled)
|
||||
if (names.contains(labelName)) {
|
||||
elements.add(getExpressionUnderLabel(parent as KtExpression))
|
||||
} else if (parent is KtCallableDeclaration && typedElement == null) {
|
||||
val receiverTypeReference = parent.receiverTypeReference
|
||||
val nameForReceiverLabel = receiverTypeReference?.nameForReceiverLabel()
|
||||
if (nameForReceiverLabel == labelName.asString()) {
|
||||
typedElement = parent
|
||||
}
|
||||
}
|
||||
parent = if (parent is KtCodeFragment) parent.context else parent.parent
|
||||
}
|
||||
return elements
|
||||
return elements to typedElement
|
||||
}
|
||||
|
||||
fun getLabelNamesIfAny(element: PsiElement, addClassNameLabels: Boolean): List<Name> {
|
||||
@@ -123,7 +130,7 @@ object LabelResolver {
|
||||
val labelName = expression.getLabelNameAsName()
|
||||
if (labelElement == null || labelName == null) return null
|
||||
|
||||
return resolveNamedLabel(labelName, labelElement, context.trace, false) ?: run {
|
||||
return resolveNamedLabel(labelName, labelElement, context.trace) ?: run {
|
||||
context.trace.report(UNRESOLVED_REFERENCE.on(labelElement, labelElement))
|
||||
null
|
||||
}
|
||||
@@ -132,10 +139,9 @@ object LabelResolver {
|
||||
private fun resolveNamedLabel(
|
||||
labelName: Name,
|
||||
labelExpression: KtSimpleNameExpression,
|
||||
trace: BindingTrace,
|
||||
classNameLabelsEnabled: Boolean
|
||||
trace: BindingTrace
|
||||
): KtElement? {
|
||||
val list = getElementsByLabelName(labelName, labelExpression, classNameLabelsEnabled)
|
||||
val list = getElementsByLabelName(labelName, labelExpression, classNameLabelsEnabled = false).first
|
||||
if (list.isEmpty()) return null
|
||||
|
||||
if (list.size > 1) {
|
||||
@@ -155,7 +161,7 @@ object LabelResolver {
|
||||
|
||||
val scope = context.scope
|
||||
val declarationsByLabel = scope.getDeclarationsByLabel(labelName)
|
||||
val elementsByLabel = getElementsByLabelName(
|
||||
val (elementsByLabel, typedElement) = getElementsByLabelName(
|
||||
labelName, targetLabelExpression,
|
||||
classNameLabelsEnabled = expression is KtThisExpression && context.languageVersionSettings.supportsFeature(ContextReceivers)
|
||||
)
|
||||
@@ -176,7 +182,13 @@ object LabelResolver {
|
||||
trace.record(REFERENCE_TARGET, referenceExpression, declarationDescriptor)
|
||||
val closestElement = elementsByLabel.firstOrNull()
|
||||
if (closestElement != null && declarationElement in closestElement.parents) {
|
||||
reportLabelResolveWillChange(trace, targetLabelExpression, declarationElement, closestElement)
|
||||
reportLabelResolveWillChange(
|
||||
trace, targetLabelExpression, declarationElement, closestElement, isForExtensionReceiver = false
|
||||
)
|
||||
} else if (typedElement != null && declarationElement in typedElement.parents) {
|
||||
reportLabelResolveWillChange(
|
||||
trace, targetLabelExpression, declarationElement, typedElement, isForExtensionReceiver = true
|
||||
)
|
||||
}
|
||||
|
||||
if (declarationDescriptor is ClassDescriptor) {
|
||||
@@ -229,12 +241,15 @@ object LabelResolver {
|
||||
trace: BindingTrace,
|
||||
target: KtSimpleNameExpression,
|
||||
declarationElement: PsiElement,
|
||||
closestElement: KtElement
|
||||
closestElement: KtElement,
|
||||
isForExtensionReceiver: Boolean
|
||||
) {
|
||||
fun suffix() = if (isForExtensionReceiver) "extension receiver" else "context receiver"
|
||||
|
||||
val closestDescription = when (closestElement) {
|
||||
is KtFunctionLiteral -> "anonymous function"
|
||||
is KtNamedFunction -> "function ${closestElement.name} context receiver"
|
||||
is KtPropertyAccessor -> "property ${closestElement.property.name} context receiver"
|
||||
is KtNamedFunction -> "function ${closestElement.name} ${suffix()}"
|
||||
is KtPropertyAccessor -> "property ${closestElement.property.name} ${suffix()}"
|
||||
else -> "???"
|
||||
}
|
||||
val declarationDescription = when (declarationElement) {
|
||||
|
||||
@@ -32,7 +32,7 @@ private typealias Extension = TypedThis
|
||||
|
||||
class TypedThis {
|
||||
fun TypedThis.baz() {
|
||||
this@TypedThis
|
||||
this<!LABEL_RESOLVE_WILL_CHANGE("class TypedThis; function baz extension receiver")!>@TypedThis<!>
|
||||
}
|
||||
|
||||
fun Extension.bar() {
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// !LANGUAGE: +ContextReceivers
|
||||
|
||||
class Some {
|
||||
context(Some, String)
|
||||
fun foo() {
|
||||
this<!UNRESOLVED_LABEL!>@foo<!>
|
||||
this@Some
|
||||
this<!UNRESOLVED_LABEL!>@String<!>
|
||||
}
|
||||
|
||||
context(Some)
|
||||
val self: Some
|
||||
get() = this@Some
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// !LANGUAGE: +ContextReceivers
|
||||
|
||||
class Some {
|
||||
context(Some, String)
|
||||
fun foo() {
|
||||
<!NO_THIS!>this@foo<!>
|
||||
this<!LABEL_RESOLVE_WILL_CHANGE("class Some; function foo context receiver")!>@Some<!>
|
||||
this@String
|
||||
}
|
||||
|
||||
context(Some)
|
||||
val self: Some
|
||||
get() = this<!LABEL_RESOLVE_WILL_CHANGE("class Some; property self context receiver")!>@Some<!>
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package
|
||||
|
||||
public final class Some {
|
||||
public constructor Some()
|
||||
context(Some) public final val self: Some
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
context(Some, kotlin.String) 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
|
||||
}
|
||||
Generated
+6
@@ -33665,6 +33665,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("labelClashesWithContextReceivers.kt")
|
||||
public void testLabelClashesWithContextReceivers() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashesWithContextReceivers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("outstar.kt")
|
||||
public void testOutstar() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user