diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetExpressionWithLabel.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetExpressionWithLabel.kt index ad0153bcf26..e83ab96c625 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetExpressionWithLabel.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetExpressionWithLabel.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.psi import com.intellij.lang.ASTNode import org.jetbrains.kotlin.JetNodeTypes +import org.jetbrains.kotlin.name.Name open public class JetExpressionWithLabel(node: ASTNode) : JetExpressionImpl(node) { @@ -25,7 +26,8 @@ open public class JetExpressionWithLabel(node: ASTNode) : JetExpressionImpl(node findChildByType(JetNodeTypes.LABEL_QUALIFIER)?. findChildByType(JetNodeTypes.LABEL) as? JetSimpleNameExpression - public fun getLabelName(): String? = getTargetLabel()?.getIdentifier()?.getText() + public fun getLabelName(): String? = getTargetLabel()?.getReferencedName() + public fun getLabelNameAsName(): Name? = getTargetLabel()?.getReferencedNameAsName() override fun accept(visitor: JetVisitor, data: D) = visitor.visitExpressionWithLabel(this, data) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index e2436c6eaba..4d44f934821 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -429,10 +429,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { ExpressionTypingContext context, boolean onlyClassReceivers ) { - String labelName = expression.getLabelName(); + Name labelName = expression.getLabelNameAsName(); if (labelName != null) { LabelResolver.LabeledReceiverResolutionResult resolutionResult = - LabelResolver.INSTANCE.resolveThisOrSuperLabel(expression, context, Name.identifier(labelName)); + LabelResolver.INSTANCE.resolveThisOrSuperLabel(expression, context, labelName); if (resolutionResult.success()) { ReceiverParameterDescriptor receiverParameterDescriptor = resolutionResult.getReceiverParameterDescriptor(); recordThisOrSuperCallInTraceAndCallExtension(context, receiverParameterDescriptor, expression); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/LabelResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/LabelResolver.java index b47be89b211..70a8561bf6b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/LabelResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/LabelResolver.java @@ -57,9 +57,9 @@ public class LabelResolver { @Nullable private Name getLabelNameIfAny(@NotNull PsiElement element) { if (element instanceof JetLabeledExpression) { - String labelName = ((JetLabeledExpression) element).getLabelName(); + Name labelName = ((JetLabeledExpression) element).getLabelNameAsName(); if (labelName != null) { - return Name.identifier(labelName); + return labelName; } } if (element instanceof JetFunctionLiteralExpression) { @@ -126,10 +126,9 @@ public class LabelResolver { @NotNull ResolutionContext context ) { JetSimpleNameExpression labelElement = expression.getTargetLabel(); - String name = expression.getLabelName(); - if (labelElement == null || name == null) return null; + Name labelName = expression.getLabelNameAsName(); + if (labelElement == null || labelName == null) return null; - Name labelName = Name.identifier(name); Collection declarationsByLabel = context.scope.getDeclarationsByLabel(labelName); int size = declarationsByLabel.size(); diff --git a/core/descriptors/src/org/jetbrains/kotlin/name/FqNamesUtil.kt b/core/descriptors/src/org/jetbrains/kotlin/name/FqNamesUtil.kt index ffb60ae9dec..a072d97ca8a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/name/FqNamesUtil.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/name/FqNamesUtil.kt @@ -16,6 +16,8 @@ package org.jetbrains.kotlin.name +import org.jetbrains.kotlin.renderer.DescriptorRenderer + public fun FqName.isSubpackageOf(packageName: FqName): Boolean { return when { this == packageName -> true @@ -76,3 +78,5 @@ public fun isValidJavaFqName(qualifiedName: String?): Boolean { return state != State.AFTER_DOT } + +public fun Name.renderName(): String = DescriptorRenderer.COMPACT.renderName(this) diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/Utils.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/Utils.kt index ed71ebcc294..8bd0518e496 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/Utils.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/Utils.kt @@ -16,9 +16,10 @@ package org.jetbrains.kotlin.idea.util +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* -public fun JetFunctionLiteral.findLabelAndCall(): Pair { +public fun JetFunctionLiteral.findLabelAndCall(): Pair { val literalParent = (this.getParent() as JetFunctionLiteralExpression).getParent() fun JetValueArgument.callExpression(): JetCallExpression? { @@ -29,12 +30,12 @@ public fun JetFunctionLiteral.findLabelAndCall(): Pair { val callExpression = (literalParent.getParent() as? JetValueArgument)?.callExpression() - return Pair(literalParent.getLabelName(), callExpression) + return Pair(literalParent.getLabelNameAsName(), callExpression) } is JetValueArgument -> { val callExpression = literalParent.callExpression() - val label = (callExpression?.getCalleeExpression() as? JetSimpleNameExpression)?.getReferencedName() + val label = (callExpression?.getCalleeExpression() as? JetSimpleNameExpression)?.getReferencedNameAsName() return Pair(label, callExpression) } diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/implicitReceiversUtils.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/implicitReceiversUtils.kt index eccd13f8c61..838c8b26635 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/implicitReceiversUtils.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/implicitReceiversUtils.kt @@ -20,6 +20,8 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.renderName import org.jetbrains.kotlin.psi.JetExpression import org.jetbrains.kotlin.psi.JetFunctionLiteral import org.jetbrains.kotlin.psi.JetPsiFactory @@ -58,7 +60,7 @@ public fun JetScope.getImplicitReceiversWithInstanceToExpression(): Map(element) { @@ -263,12 +264,13 @@ private fun createKeywordWithLabelElement(keyword: String, label: String?, addSp } } -private fun createKeywordWithLabelElement(keyword: String, label: String?): LookupElementBuilder { - var element = LookupElementBuilder.create(KeywordLookupObject, if (label == null) keyword else "$keyword@$label") +private fun createKeywordWithLabelElement(keyword: String, label: Name?): LookupElementBuilder { + val labelInCode = label?.renderName() + var element = LookupElementBuilder.create(KeywordLookupObject, if (label == null) keyword else "$keyword@$labelInCode") element = element.withPresentableText(keyword) element = element.withBoldness(true) if (label != null) { - element = element.withTailText("@$label", false) + element = element.withTailText("@$labelInCode", false) } return element } @@ -284,7 +286,7 @@ fun breakOrContinueExpressionItems(position: JetElement, breakOrContinue: String result.add(createKeywordWithLabelElement(breakOrContinue, null)) } - val label = (parent.getParent() as? JetLabeledExpression)?.getLabelName() + val label = (parent.getParent() as? JetLabeledExpression)?.getLabelNameAsName() if (label != null) { result.add(createKeywordWithLabelElement(breakOrContinue, label)) } diff --git a/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName1.kt b/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName1.kt index 8b870fc5136..5f955c55578 100644 --- a/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName1.kt +++ b/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName1.kt @@ -4,5 +4,5 @@ class `this` { } } -// ELEMENT: "this@this" +// ELEMENT: "this@`this`" diff --git a/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName1.kt.after b/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName1.kt.after index 02867858897..ca5dd02449a 100644 --- a/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName1.kt.after +++ b/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName1.kt.after @@ -1,8 +1,8 @@ class `this` { fun String.foo(){ - val foo: `this` = this@this + val foo: `this` = this@`this` } } -// ELEMENT: "this@this" +// ELEMENT: "this@`this`" diff --git a/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName2.kt b/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName2.kt index b52b0df4d49..367723954db 100644 --- a/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName2.kt +++ b/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName2.kt @@ -9,4 +9,4 @@ fun foo(){ }) } -// ELEMENT: this@fun +// ELEMENT: this@`fun` diff --git a/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName2.kt.after b/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName2.kt.after index 101edc41195..7f59de76c66 100644 --- a/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName2.kt.after +++ b/idea/idea-completion/testData/handlers/smart/QualifiedThisKeywordName2.kt.after @@ -4,9 +4,9 @@ fun bar(handler: Int.() -> Unit){} fun foo(){ `fun`({ bar({ - val s: String = this@fun + val s: String = this@`fun` }) }) } -// ELEMENT: this@fun +// ELEMENT: this@`fun` diff --git a/idea/idea-completion/testData/keywords/ReturnKeywordName.kt b/idea/idea-completion/testData/keywords/ReturnKeywordName.kt new file mode 100644 index 00000000000..db2c8071218 --- /dev/null +++ b/idea/idea-completion/testData/keywords/ReturnKeywordName.kt @@ -0,0 +1,14 @@ +fun foo() { + `fun` { + `val`({ ret }) + } +} + +inline fun `fun`(handler: () -> Unit){} +inline fun `val`(handler: () -> Unit){} + +// INVOCATION_COUNT: 1 +// EXIST: { lookupString: "return", itemText: "return", tailText: null, attributes: "bold" } +// EXIST: { lookupString: "return@`fun`", itemText: "return", tailText: "@`fun`", attributes: "bold" } +// EXIST: { lookupString: "return@`val`", itemText: "return", tailText: "@`val`", attributes: "bold" } +// NOTHING_ELSE: true diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/KeywordCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/KeywordCompletionTestGenerated.java index 9c40c390fef..844e19c7ef0 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/KeywordCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/KeywordCompletionTestGenerated.java @@ -401,6 +401,12 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes doTest(fileName); } + @TestMetadata("ReturnKeywordName.kt") + public void testReturnKeywordName() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/ReturnKeywordName.kt"); + doTest(fileName); + } + @TestMetadata("This.kt") public void testThis() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/This.kt");