Fixed keywords after 'this@' completion + fixed implementation of JetExpressionWithLabel.getLabelName()
This commit is contained in:
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.psi
|
|||||||
|
|
||||||
import com.intellij.lang.ASTNode
|
import com.intellij.lang.ASTNode
|
||||||
import org.jetbrains.kotlin.JetNodeTypes
|
import org.jetbrains.kotlin.JetNodeTypes
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
open public class JetExpressionWithLabel(node: ASTNode) : JetExpressionImpl(node) {
|
open public class JetExpressionWithLabel(node: ASTNode) : JetExpressionImpl(node) {
|
||||||
|
|
||||||
@@ -25,7 +26,8 @@ open public class JetExpressionWithLabel(node: ASTNode) : JetExpressionImpl(node
|
|||||||
findChildByType<JetContainerNode>(JetNodeTypes.LABEL_QUALIFIER)?.
|
findChildByType<JetContainerNode>(JetNodeTypes.LABEL_QUALIFIER)?.
|
||||||
findChildByType(JetNodeTypes.LABEL) as? JetSimpleNameExpression
|
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 <R, D> accept(visitor: JetVisitor<R, D>, data: D) = visitor.visitExpressionWithLabel(this, data)
|
override fun <R, D> accept(visitor: JetVisitor<R, D>, data: D) = visitor.visitExpressionWithLabel(this, data)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -429,10 +429,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
ExpressionTypingContext context,
|
ExpressionTypingContext context,
|
||||||
boolean onlyClassReceivers
|
boolean onlyClassReceivers
|
||||||
) {
|
) {
|
||||||
String labelName = expression.getLabelName();
|
Name labelName = expression.getLabelNameAsName();
|
||||||
if (labelName != null) {
|
if (labelName != null) {
|
||||||
LabelResolver.LabeledReceiverResolutionResult resolutionResult =
|
LabelResolver.LabeledReceiverResolutionResult resolutionResult =
|
||||||
LabelResolver.INSTANCE.resolveThisOrSuperLabel(expression, context, Name.identifier(labelName));
|
LabelResolver.INSTANCE.resolveThisOrSuperLabel(expression, context, labelName);
|
||||||
if (resolutionResult.success()) {
|
if (resolutionResult.success()) {
|
||||||
ReceiverParameterDescriptor receiverParameterDescriptor = resolutionResult.getReceiverParameterDescriptor();
|
ReceiverParameterDescriptor receiverParameterDescriptor = resolutionResult.getReceiverParameterDescriptor();
|
||||||
recordThisOrSuperCallInTraceAndCallExtension(context, receiverParameterDescriptor, expression);
|
recordThisOrSuperCallInTraceAndCallExtension(context, receiverParameterDescriptor, expression);
|
||||||
|
|||||||
@@ -57,9 +57,9 @@ public class LabelResolver {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Name getLabelNameIfAny(@NotNull PsiElement element) {
|
private Name getLabelNameIfAny(@NotNull PsiElement element) {
|
||||||
if (element instanceof JetLabeledExpression) {
|
if (element instanceof JetLabeledExpression) {
|
||||||
String labelName = ((JetLabeledExpression) element).getLabelName();
|
Name labelName = ((JetLabeledExpression) element).getLabelNameAsName();
|
||||||
if (labelName != null) {
|
if (labelName != null) {
|
||||||
return Name.identifier(labelName);
|
return labelName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (element instanceof JetFunctionLiteralExpression) {
|
if (element instanceof JetFunctionLiteralExpression) {
|
||||||
@@ -126,10 +126,9 @@ public class LabelResolver {
|
|||||||
@NotNull ResolutionContext context
|
@NotNull ResolutionContext context
|
||||||
) {
|
) {
|
||||||
JetSimpleNameExpression labelElement = expression.getTargetLabel();
|
JetSimpleNameExpression labelElement = expression.getTargetLabel();
|
||||||
String name = expression.getLabelName();
|
Name labelName = expression.getLabelNameAsName();
|
||||||
if (labelElement == null || name == null) return null;
|
if (labelElement == null || labelName == null) return null;
|
||||||
|
|
||||||
Name labelName = Name.identifier(name);
|
|
||||||
Collection<DeclarationDescriptor> declarationsByLabel = context.scope.getDeclarationsByLabel(labelName);
|
Collection<DeclarationDescriptor> declarationsByLabel = context.scope.getDeclarationsByLabel(labelName);
|
||||||
int size = declarationsByLabel.size();
|
int size = declarationsByLabel.size();
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.name
|
package org.jetbrains.kotlin.name
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
|
|
||||||
public fun FqName.isSubpackageOf(packageName: FqName): Boolean {
|
public fun FqName.isSubpackageOf(packageName: FqName): Boolean {
|
||||||
return when {
|
return when {
|
||||||
this == packageName -> true
|
this == packageName -> true
|
||||||
@@ -76,3 +78,5 @@ public fun isValidJavaFqName(qualifiedName: String?): Boolean {
|
|||||||
|
|
||||||
return state != State.AFTER_DOT
|
return state != State.AFTER_DOT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun Name.renderName(): String = DescriptorRenderer.COMPACT.renderName(this)
|
||||||
|
|||||||
@@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.util
|
package org.jetbrains.kotlin.idea.util
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
|
||||||
public fun JetFunctionLiteral.findLabelAndCall(): Pair<String?, JetCallExpression?> {
|
public fun JetFunctionLiteral.findLabelAndCall(): Pair<Name?, JetCallExpression?> {
|
||||||
val literalParent = (this.getParent() as JetFunctionLiteralExpression).getParent()
|
val literalParent = (this.getParent() as JetFunctionLiteralExpression).getParent()
|
||||||
|
|
||||||
fun JetValueArgument.callExpression(): JetCallExpression? {
|
fun JetValueArgument.callExpression(): JetCallExpression? {
|
||||||
@@ -29,12 +30,12 @@ public fun JetFunctionLiteral.findLabelAndCall(): Pair<String?, JetCallExpressio
|
|||||||
when (literalParent) {
|
when (literalParent) {
|
||||||
is JetLabeledExpression -> {
|
is JetLabeledExpression -> {
|
||||||
val callExpression = (literalParent.getParent() as? JetValueArgument)?.callExpression()
|
val callExpression = (literalParent.getParent() as? JetValueArgument)?.callExpression()
|
||||||
return Pair(literalParent.getLabelName(), callExpression)
|
return Pair(literalParent.getLabelNameAsName(), callExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
is JetValueArgument -> {
|
is JetValueArgument -> {
|
||||||
val callExpression = literalParent.callExpression()
|
val callExpression = literalParent.callExpression()
|
||||||
val label = (callExpression?.getCalleeExpression() as? JetSimpleNameExpression)?.getReferencedName()
|
val label = (callExpression?.getCalleeExpression() as? JetSimpleNameExpression)?.getReferencedNameAsName()
|
||||||
return Pair(label, callExpression)
|
return Pair(label, callExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
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.JetExpression
|
||||||
import org.jetbrains.kotlin.psi.JetFunctionLiteral
|
import org.jetbrains.kotlin.psi.JetFunctionLiteral
|
||||||
import org.jetbrains.kotlin.psi.JetPsiFactory
|
import org.jetbrains.kotlin.psi.JetPsiFactory
|
||||||
@@ -58,7 +60,7 @@ public fun JetScope.getImplicitReceiversWithInstanceToExpression(): Map<Receiver
|
|||||||
for ((index, receiver) in receivers.withIndex()) {
|
for ((index, receiver) in receivers.withIndex()) {
|
||||||
val owner = receiver.getContainingDeclaration()
|
val owner = receiver.getContainingDeclaration()
|
||||||
val (expressionText, isImmediateThis) = if (owner in outerDeclarationsWithInstance) {
|
val (expressionText, isImmediateThis) = if (owner in outerDeclarationsWithInstance) {
|
||||||
val thisWithLabel = thisQualifierName(receiver)?.let { "this@$it" }
|
val thisWithLabel = thisQualifierName(receiver)?.let { "this@${it.renderName()}" }
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
(thisWithLabel ?: "this") to true
|
(thisWithLabel ?: "this") to true
|
||||||
else
|
else
|
||||||
@@ -83,12 +85,10 @@ public fun JetScope.getImplicitReceiversWithInstanceToExpression(): Map<Receiver
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun thisQualifierName(receiver: ReceiverParameterDescriptor): String? {
|
private fun thisQualifierName(receiver: ReceiverParameterDescriptor): Name? {
|
||||||
val descriptor = receiver.getContainingDeclaration()
|
val descriptor = receiver.getContainingDeclaration()
|
||||||
val name = descriptor.getName()
|
val name = descriptor.getName()
|
||||||
if (!name.isSpecial()) {
|
if (!name.isSpecial()) return name
|
||||||
return name.asString()
|
|
||||||
}
|
|
||||||
|
|
||||||
val functionLiteral = DescriptorToSourceUtils.descriptorToDeclaration(descriptor) as? JetFunctionLiteral
|
val functionLiteral = DescriptorToSourceUtils.descriptorToDeclaration(descriptor) as? JetFunctionLiteral
|
||||||
return functionLiteral?.findLabelAndCall()?.first
|
return functionLiteral?.findLabelAndCall()?.first
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.idea.util.FuzzyType
|
|||||||
import org.jetbrains.kotlin.idea.util.findLabelAndCall
|
import org.jetbrains.kotlin.idea.util.findLabelAndCall
|
||||||
import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstanceToExpression
|
import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstanceToExpression
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.name.renderName
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
@@ -209,7 +210,7 @@ fun thisExpressionItems(bindingContext: BindingContext, position: JetExpression,
|
|||||||
val thisType = receiver.getType()
|
val thisType = receiver.getType()
|
||||||
val fuzzyType = FuzzyType(thisType, listOf())
|
val fuzzyType = FuzzyType(thisType, listOf())
|
||||||
|
|
||||||
fun createLookupElement() = createKeywordWithLabelElement("this", expression.getLabelName())
|
fun createLookupElement() = createKeywordWithLabelElement("this", expression.getLabelNameAsName())
|
||||||
.withTypeText(DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(thisType))
|
.withTypeText(DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(thisType))
|
||||||
|
|
||||||
result.add(ThisItemInfo(::createLookupElement, fuzzyType))
|
result.add(ThisItemInfo(::createLookupElement, fuzzyType))
|
||||||
@@ -249,7 +250,7 @@ private fun returnsUnit(declaration: JetDeclarationWithBody, bindingContext: Bin
|
|||||||
return KotlinBuiltIns.isUnit(returnType)
|
return KotlinBuiltIns.isUnit(returnType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createKeywordWithLabelElement(keyword: String, label: String?, addSpace: Boolean): LookupElement {
|
private fun createKeywordWithLabelElement(keyword: String, label: Name?, addSpace: Boolean): LookupElement {
|
||||||
val element = createKeywordWithLabelElement(keyword, label)
|
val element = createKeywordWithLabelElement(keyword, label)
|
||||||
return if (addSpace) {
|
return if (addSpace) {
|
||||||
object: LookupElementDecorator<LookupElement>(element) {
|
object: LookupElementDecorator<LookupElement>(element) {
|
||||||
@@ -263,12 +264,13 @@ private fun createKeywordWithLabelElement(keyword: String, label: String?, addSp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createKeywordWithLabelElement(keyword: String, label: String?): LookupElementBuilder {
|
private fun createKeywordWithLabelElement(keyword: String, label: Name?): LookupElementBuilder {
|
||||||
var element = LookupElementBuilder.create(KeywordLookupObject, if (label == null) keyword else "$keyword@$label")
|
val labelInCode = label?.renderName()
|
||||||
|
var element = LookupElementBuilder.create(KeywordLookupObject, if (label == null) keyword else "$keyword@$labelInCode")
|
||||||
element = element.withPresentableText(keyword)
|
element = element.withPresentableText(keyword)
|
||||||
element = element.withBoldness(true)
|
element = element.withBoldness(true)
|
||||||
if (label != null) {
|
if (label != null) {
|
||||||
element = element.withTailText("@$label", false)
|
element = element.withTailText("@$labelInCode", false)
|
||||||
}
|
}
|
||||||
return element
|
return element
|
||||||
}
|
}
|
||||||
@@ -284,7 +286,7 @@ fun breakOrContinueExpressionItems(position: JetElement, breakOrContinue: String
|
|||||||
result.add(createKeywordWithLabelElement(breakOrContinue, null))
|
result.add(createKeywordWithLabelElement(breakOrContinue, null))
|
||||||
}
|
}
|
||||||
|
|
||||||
val label = (parent.getParent() as? JetLabeledExpression)?.getLabelName()
|
val label = (parent.getParent() as? JetLabeledExpression)?.getLabelNameAsName()
|
||||||
if (label != null) {
|
if (label != null) {
|
||||||
result.add(createKeywordWithLabelElement(breakOrContinue, label))
|
result.add(createKeywordWithLabelElement(breakOrContinue, label))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ class `this` {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ELEMENT: "this@this"
|
// ELEMENT: "this@`this`"
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
class `this` {
|
class `this` {
|
||||||
fun String.foo(){
|
fun String.foo(){
|
||||||
val foo: `this` = this@this<caret>
|
val foo: `this` = this@`this`<caret>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ELEMENT: "this@this"
|
// ELEMENT: "this@`this`"
|
||||||
|
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ fun foo(){
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ELEMENT: this@fun
|
// ELEMENT: this@`fun`
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ fun bar(handler: Int.() -> Unit){}
|
|||||||
fun foo(){
|
fun foo(){
|
||||||
`fun`({
|
`fun`({
|
||||||
bar({
|
bar({
|
||||||
val s: String = this@fun<caret>
|
val s: String = this@`fun`<caret>
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ELEMENT: this@fun
|
// ELEMENT: this@`fun`
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
fun foo() {
|
||||||
|
`fun` {
|
||||||
|
`val`({ ret<caret> })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
+6
@@ -401,6 +401,12 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("This.kt")
|
||||||
public void testThis() throws Exception {
|
public void testThis() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/This.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/This.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user