diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.kt b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.kt index dca79527f3d..2a7f65958f6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.kt @@ -25,47 +25,9 @@ import org.jetbrains.jet.lang.parsing.JetExpressionParsing import org.jetbrains.jet.lang.resolve.name.Name import org.jetbrains.jet.lexer.JetTokens import org.jetbrains.jet.lexer.JetTokens.* -import org.jetbrains.jet.lang.types.expressions.OperatorConventions public trait JetSimpleNameExpression : JetReferenceExpression { - public fun getReceiverExpression(): JetExpression? { - val parent = getParent() - when { - parent is JetQualifiedExpression && !isImportDirectiveExpression() -> { - val receiverExpression = parent.getReceiverExpression() - // Name expression can't be receiver for itself - if (receiverExpression != this) { - return receiverExpression - } - } - parent is JetCallExpression -> { - //This is in case `a().b()` - val callExpression = (parent as JetCallExpression) - val grandParent = callExpression.getParent() - if (grandParent is JetQualifiedExpression) { - val parentsReceiver = grandParent.getReceiverExpression() - if (parentsReceiver != callExpression) { - return parentsReceiver - } - } - } - parent is JetBinaryExpression && parent.getOperationReference() == this -> { - return if (parent.getOperationToken() in OperatorConventions.IN_OPERATIONS) parent.getRight() else parent.getLeft() - } - parent is JetUnaryExpression && parent.getOperationReference() == this -> { - return parent.getBaseExpression()!! - } - parent is JetUserType -> { - val qualifier = parent.getQualifier() - if (qualifier != null) { - return qualifier.getReferenceExpression()!! - } - } - } - return null - } - public fun isImportDirectiveExpression(): Boolean { val parent = getParent() if (parent == null) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/psiUtil/jetPsiUtil.kt b/compiler/frontend/src/org/jetbrains/jet/lang/psi/psiUtil/jetPsiUtil.kt index af0d0dc55aa..95283ae50fe 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/psiUtil/jetPsiUtil.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/psiUtil/jetPsiUtil.kt @@ -33,6 +33,7 @@ import com.intellij.psi.PsiPackage import com.intellij.psi.JavaDirectoryService import com.intellij.psi.PsiDirectory import org.jetbrains.jet.lang.psi.stubs.PsiJetClassOrObjectStub +import org.jetbrains.jet.lang.types.expressions.OperatorConventions public fun JetCallElement.getCallNameExpression(): JetSimpleNameExpression? { val calleeExpression = getCalleeExpression() @@ -264,4 +265,41 @@ public fun PsiElement.isInsideOf(elements: Iterable): Boolean = elem public tailRecursive fun PsiElement.getOutermostParentContainedIn(container: PsiElement): PsiElement? { val parent = getParent() return if (parent == container) this else parent?.getOutermostParentContainedIn(container) -} \ No newline at end of file +} + +public fun JetSimpleNameExpression.getReceiverExpression(): JetExpression? { + val parent = getParent() + when { + parent is JetQualifiedExpression && !isImportDirectiveExpression() -> { + val receiverExpression = parent.getReceiverExpression() + // Name expression can't be receiver for itself + if (receiverExpression != this) { + return receiverExpression + } + } + parent is JetCallExpression -> { + //This is in case `a().b()` + val callExpression = (parent as JetCallExpression) + val grandParent = callExpression.getParent() + if (grandParent is JetQualifiedExpression) { + val parentsReceiver = grandParent.getReceiverExpression() + if (parentsReceiver != callExpression) { + return parentsReceiver + } + } + } + parent is JetBinaryExpression && parent.getOperationReference() == this -> { + return if (parent.getOperationToken() in OperatorConventions.IN_OPERATIONS) parent.getRight() else parent.getLeft() + } + parent is JetUnaryExpression && parent.getOperationReference() == this -> { + return parent.getBaseExpression()!! + } + parent is JetUserType -> { + val qualifier = parent.getQualifier() + if (qualifier != null) { + return qualifier.getReferenceExpression()!! + } + } + } + return null +} diff --git a/compiler/tests/org/jetbrains/jet/lang/psi/JetSimpleNameExpressionTest.kt b/compiler/tests/org/jetbrains/jet/lang/psi/JetSimpleNameExpressionTest.kt index f3261b3a260..d3050d05ef3 100644 --- a/compiler/tests/org/jetbrains/jet/lang/psi/JetSimpleNameExpressionTest.kt +++ b/compiler/tests/org/jetbrains/jet/lang/psi/JetSimpleNameExpressionTest.kt @@ -20,6 +20,7 @@ import org.junit.Assert import org.jetbrains.jet.JetLiteFixture import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment import org.jetbrains.jet.config.CompilerConfiguration +import org.jetbrains.jet.lang.psi.psiUtil.getReceiverExpression public class JetSimpleNameExpressionTest() : JetLiteFixture() { public fun testGetReceiverExpressionIdentifier() { diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index a3581114b44..181cf4bc31c 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -36,6 +36,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.asJava.JavaElementFinder; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.psi.psiUtil.PsiUtilPackage; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext; import org.jetbrains.jet.lang.resolve.ImportPath; @@ -289,7 +290,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { @NotNull GlobalSearchScope searchScope ) { BindingContext context = resolveSession.resolveToElement(expression); - JetExpression receiverExpression = expression.getReceiverExpression(); + JetExpression receiverExpression = PsiUtilPackage.getReceiverExpression(expression); if (receiverExpression == null) { return Collections.emptyList(); } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/KotlinCopyPasteReferenceProcessor.kt b/idea/src/org/jetbrains/jet/plugin/codeInsight/KotlinCopyPasteReferenceProcessor.kt index b8d6485a3bf..698039262ac 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/KotlinCopyPasteReferenceProcessor.kt +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/KotlinCopyPasteReferenceProcessor.kt @@ -60,6 +60,9 @@ import org.jetbrains.jet.lang.psi.JetTypeReference import com.intellij.util.containers.ContainerUtil import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils import org.jetbrains.jet.plugin.imports.* +import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor +import org.jetbrains.jet.lang.psi.psiUtil.getReceiverExpression +import org.jetbrains.jet.utils.* //NOTE: this class is based on CopyPasteReferenceProcessor and JavaCopyPasteReferenceProcessor public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/TipsManager.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/TipsManager.java index d202f6d75e3..2a78d3e0691 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/TipsManager.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/TipsManager.java @@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor; import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.psi.psiUtil.PsiUtilPackage; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastUtils; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; @@ -51,7 +52,7 @@ public final class TipsManager { @NotNull JetSimpleNameExpression expression, @NotNull BindingContext context ) { - JetExpression receiverExpression = expression.getReceiverExpression(); + JetExpression receiverExpression = PsiUtilPackage.getReceiverExpression(expression); PsiElement parent = expression.getParent(); boolean inPositionForCompletionWithReceiver = parent instanceof JetCallExpression || parent instanceof JetQualifiedExpression; if (receiverExpression != null && inPositionForCompletionWithReceiver) { diff --git a/idea/src/org/jetbrains/jet/plugin/imports/ImportsUtils.kt b/idea/src/org/jetbrains/jet/plugin/imports/ImportsUtils.kt index 964b518048a..41e6dded681 100644 --- a/idea/src/org/jetbrains/jet/plugin/imports/ImportsUtils.kt +++ b/idea/src/org/jetbrains/jet/plugin/imports/ImportsUtils.kt @@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor import org.jetbrains.jet.lang.descriptors.ClassDescriptor import org.jetbrains.jet.lang.descriptors.CallableDescriptor import org.jetbrains.jet.lang.psi.JetSimpleNameExpression +import org.jetbrains.jet.lang.psi.psiUtil.getReceiverExpression import com.intellij.psi.PsiElement import org.jetbrains.jet.lang.types.JetType