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");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashes.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("labelClashesWithContextReceivers.kt")
|
||||||
|
public void testLabelClashesWithContextReceivers() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashesWithContextReceivers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("outstar.kt")
|
@TestMetadata("outstar.kt")
|
||||||
public void testOutstar() throws Exception {
|
public void testOutstar() throws Exception {
|
||||||
|
|||||||
+6
@@ -33575,6 +33575,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashes.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashes.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("labelClashesWithContextReceivers.kt")
|
||||||
|
public void testLabelClashesWithContextReceivers() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashesWithContextReceivers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("outstar.kt")
|
@TestMetadata("outstar.kt")
|
||||||
public void testOutstar() throws Exception {
|
public void testOutstar() throws Exception {
|
||||||
|
|||||||
+6
@@ -33575,6 +33575,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashes.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashes.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("labelClashesWithContextReceivers.kt")
|
||||||
|
public void testLabelClashesWithContextReceivers() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashesWithContextReceivers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("outstar.kt")
|
@TestMetadata("outstar.kt")
|
||||||
public void testOutstar() throws Exception {
|
public void testOutstar() throws Exception {
|
||||||
|
|||||||
@@ -36,17 +36,24 @@ object LabelResolver {
|
|||||||
labelName: Name,
|
labelName: Name,
|
||||||
labelExpression: KtSimpleNameExpression,
|
labelExpression: KtSimpleNameExpression,
|
||||||
classNameLabelsEnabled: Boolean
|
classNameLabelsEnabled: Boolean
|
||||||
): Set<KtElement> {
|
): Pair<Set<KtElement>, KtCallableDeclaration?> {
|
||||||
val elements = linkedSetOf<KtElement>()
|
val elements = linkedSetOf<KtElement>()
|
||||||
|
var typedElement: KtCallableDeclaration? = null
|
||||||
var parent: PsiElement? = labelExpression.parent
|
var parent: PsiElement? = labelExpression.parent
|
||||||
while (parent != null) {
|
while (parent != null) {
|
||||||
val names = getLabelNamesIfAny(parent, classNameLabelsEnabled)
|
val names = getLabelNamesIfAny(parent, classNameLabelsEnabled)
|
||||||
if (names.contains(labelName)) {
|
if (names.contains(labelName)) {
|
||||||
elements.add(getExpressionUnderLabel(parent as KtExpression))
|
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
|
parent = if (parent is KtCodeFragment) parent.context else parent.parent
|
||||||
}
|
}
|
||||||
return elements
|
return elements to typedElement
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLabelNamesIfAny(element: PsiElement, addClassNameLabels: Boolean): List<Name> {
|
fun getLabelNamesIfAny(element: PsiElement, addClassNameLabels: Boolean): List<Name> {
|
||||||
@@ -123,7 +130,7 @@ object LabelResolver {
|
|||||||
val labelName = expression.getLabelNameAsName()
|
val labelName = expression.getLabelNameAsName()
|
||||||
if (labelElement == null || labelName == null) return null
|
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))
|
context.trace.report(UNRESOLVED_REFERENCE.on(labelElement, labelElement))
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@@ -132,10 +139,9 @@ object LabelResolver {
|
|||||||
private fun resolveNamedLabel(
|
private fun resolveNamedLabel(
|
||||||
labelName: Name,
|
labelName: Name,
|
||||||
labelExpression: KtSimpleNameExpression,
|
labelExpression: KtSimpleNameExpression,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace
|
||||||
classNameLabelsEnabled: Boolean
|
|
||||||
): KtElement? {
|
): KtElement? {
|
||||||
val list = getElementsByLabelName(labelName, labelExpression, classNameLabelsEnabled)
|
val list = getElementsByLabelName(labelName, labelExpression, classNameLabelsEnabled = false).first
|
||||||
if (list.isEmpty()) return null
|
if (list.isEmpty()) return null
|
||||||
|
|
||||||
if (list.size > 1) {
|
if (list.size > 1) {
|
||||||
@@ -155,7 +161,7 @@ object LabelResolver {
|
|||||||
|
|
||||||
val scope = context.scope
|
val scope = context.scope
|
||||||
val declarationsByLabel = scope.getDeclarationsByLabel(labelName)
|
val declarationsByLabel = scope.getDeclarationsByLabel(labelName)
|
||||||
val elementsByLabel = getElementsByLabelName(
|
val (elementsByLabel, typedElement) = getElementsByLabelName(
|
||||||
labelName, targetLabelExpression,
|
labelName, targetLabelExpression,
|
||||||
classNameLabelsEnabled = expression is KtThisExpression && context.languageVersionSettings.supportsFeature(ContextReceivers)
|
classNameLabelsEnabled = expression is KtThisExpression && context.languageVersionSettings.supportsFeature(ContextReceivers)
|
||||||
)
|
)
|
||||||
@@ -176,7 +182,13 @@ object LabelResolver {
|
|||||||
trace.record(REFERENCE_TARGET, referenceExpression, declarationDescriptor)
|
trace.record(REFERENCE_TARGET, referenceExpression, declarationDescriptor)
|
||||||
val closestElement = elementsByLabel.firstOrNull()
|
val closestElement = elementsByLabel.firstOrNull()
|
||||||
if (closestElement != null && declarationElement in closestElement.parents) {
|
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) {
|
if (declarationDescriptor is ClassDescriptor) {
|
||||||
@@ -229,12 +241,15 @@ object LabelResolver {
|
|||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
target: KtSimpleNameExpression,
|
target: KtSimpleNameExpression,
|
||||||
declarationElement: PsiElement,
|
declarationElement: PsiElement,
|
||||||
closestElement: KtElement
|
closestElement: KtElement,
|
||||||
|
isForExtensionReceiver: Boolean
|
||||||
) {
|
) {
|
||||||
|
fun suffix() = if (isForExtensionReceiver) "extension receiver" else "context receiver"
|
||||||
|
|
||||||
val closestDescription = when (closestElement) {
|
val closestDescription = when (closestElement) {
|
||||||
is KtFunctionLiteral -> "anonymous function"
|
is KtFunctionLiteral -> "anonymous function"
|
||||||
is KtNamedFunction -> "function ${closestElement.name} context receiver"
|
is KtNamedFunction -> "function ${closestElement.name} ${suffix()}"
|
||||||
is KtPropertyAccessor -> "property ${closestElement.property.name} context receiver"
|
is KtPropertyAccessor -> "property ${closestElement.property.name} ${suffix()}"
|
||||||
else -> "???"
|
else -> "???"
|
||||||
}
|
}
|
||||||
val declarationDescription = when (declarationElement) {
|
val declarationDescription = when (declarationElement) {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ private typealias Extension = TypedThis
|
|||||||
|
|
||||||
class TypedThis {
|
class TypedThis {
|
||||||
fun TypedThis.baz() {
|
fun TypedThis.baz() {
|
||||||
this@TypedThis
|
this<!LABEL_RESOLVE_WILL_CHANGE("class TypedThis; function baz extension receiver")!>@TypedThis<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Extension.bar() {
|
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");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashes.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("labelClashesWithContextReceivers.kt")
|
||||||
|
public void testLabelClashesWithContextReceivers() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/labelClashesWithContextReceivers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("outstar.kt")
|
@TestMetadata("outstar.kt")
|
||||||
public void testOutstar() throws Exception {
|
public void testOutstar() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user