diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
index f3e5ce91994..b889fc617aa 100644
--- a/.idea/codeStyleSettings.xml
+++ b/.idea/codeStyleSettings.xml
@@ -214,6 +214,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java
index 8198e936ca6..a462ab8f612 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java
@@ -403,19 +403,21 @@ public class JetPsiUtil {
return null;
}
- public static boolean isFirstPartInQualified(@NotNull JetSimpleNameExpression nameExpression) {
- @SuppressWarnings("unchecked") JetUserType userType = PsiTreeUtil.getParentOfType(nameExpression, JetUserType.class, true,
- JetDeclaration.class);
- if (userType != null) {
- return PsiTreeUtil.isAncestor(userType.getFirstChild(), nameExpression, false);
+ public static boolean isSelectorInQualified(@NotNull JetSimpleNameExpression nameExpression) {
+ PsiElement nameExpressionParent = nameExpression.getParent();
+
+ if (nameExpressionParent instanceof JetUserType) {
+ assert ((JetUserType) nameExpressionParent).getReferenceExpression() == nameExpression;
+ return ((JetUserType) nameExpressionParent).getQualifier() != null;
}
- @SuppressWarnings("unchecked") JetQualifiedExpression qualifiedExpression = PsiTreeUtil.getParentOfType(nameExpression, JetQualifiedExpression.class, true, JetDeclaration.class);
- if (qualifiedExpression != null) {
- return PsiTreeUtil.isAncestor(qualifiedExpression.getFirstChild(), nameExpression, false);
+ JetExpression selector = nameExpression;
+ if (nameExpressionParent instanceof JetCallExpression && ((JetCallExpression) nameExpressionParent).getCalleeExpression() == nameExpression) {
+ selector = (JetCallExpression) nameExpressionParent;
}
- return true;
+ PsiElement selectorParent = selector.getParent();
+ return selectorParent instanceof JetQualifiedExpression && (((JetQualifiedExpression) selectorParent).getSelectorExpression() == selector);
}
public static boolean isVoidType(@Nullable JetTypeReference typeReference) {
diff --git a/compiler/testData/psiUtil/isSelectorInExpression.kt b/compiler/testData/psiUtil/isSelectorInExpression.kt
new file mode 100644
index 00000000000..ae2ddcff111
--- /dev/null
+++ b/compiler/testData/psiUtil/isSelectorInExpression.kt
@@ -0,0 +1,73 @@
+package testing.groovytest
+
+class Test {
+ fun foo(a: Any) = this
+ val test: Test = this
+ fun test() = this
+ fun get(index: Int) = this
+
+ fun i() = 0
+ var i: Int = 0
+}
+
+fun bar() = Test()
+
+fun test() {
+ val t = Test()
+ val s = t
+
+ /*false*/t.test()
+ /*false*/t.test()!!
+ /*false*/t.test()?.test
+ /*false*/t.test()[0]
+ /*false*/t.test[0]
+ /*false*/t.test[t.i()]!!
+
+ /*false*/t.test
+ /*false*/t!!.test
+ /*false*/t?.test
+
+ t[/*false*/s.i()]
+ t[/*false*/s!!.i()]
+ t[/*false*/s?.i()]
+ t[/*false*/s[0]?.i()]
+
+ /*false*/t[0].test
+ /*false*/t[0]!!.test
+ /*false*/t[0]?.test
+
+ bar()./*true*/test
+ bar()!!./*true*/test
+ bar()?./*true*/test
+
+ t[0]./*true*/test()
+ t[0]!!./*true*/test()
+ t[0]?./*true*/test()
+
+ t.foo(/*false*/t.test)
+ t.foo(/*false*/t!!.test)
+ t.foo(/*false*/t?.test)
+ t.foo(/*false*/t[0].test)
+
+ t.foo(t./*true*/test())
+ t.foo(t!!./*true*/test)
+ t.foo(t?./*true*/test())
+ t.foo(t[0]./*true*/test)
+
+ /*false*/t.i++
+ /*false*/t!!.i++
+ /*false*/t?.i++
+ /*false*/t[0].i++
+ /*false*/t.test.i++
+
+ t./*true*/i++
+ t!!./*true*/i++
+ t?./*true*/i++
+ t[0]./*true*/i++
+ t.test./*true*/i++
+
+ val t1 = 1
+ val t2 = /*false*/t1
+
+ /*false*/t1 + /*false*/t2
+}
\ No newline at end of file
diff --git a/compiler/testData/psiUtil/isSelectorInType.kt b/compiler/testData/psiUtil/isSelectorInType.kt
new file mode 100644
index 00000000000..6d3e3187726
--- /dev/null
+++ b/compiler/testData/psiUtil/isSelectorInType.kt
@@ -0,0 +1,22 @@
+package test.some
+
+class Test
+class GTest
+
+fun foo(a: /*false*/test.some.Test, b: test./*true*/some.Test, c: test.some./*true*/Test, d: /*false*/Test) {
+
+ val t1: /*false*/test.some.Test? = null
+ val t2: test./*true*/some.Test? = null
+ val t3: test.some./*true*/Test? = null
+ val t4: /*false*/Test? = null
+
+ val t5: GTest*false*/test.some.Test>? = null
+ val t6: GTest? = null
+ val t7: GTest? = null
+ val t8: GTest*false*/Test>? = null
+ val t9: test.some.GTest*false*/Test>? = null
+ val t10: /*false*/GTest? = null
+}
\ No newline at end of file
diff --git a/compiler/tests/org/jetbrains/jet/lang/psi/JetPsiUtilTest.java b/compiler/tests/org/jetbrains/jet/lang/psi/JetPsiUtilTest.java
index e58f05676cf..9a6c34bebb5 100644
--- a/compiler/tests/org/jetbrains/jet/lang/psi/JetPsiUtilTest.java
+++ b/compiler/tests/org/jetbrains/jet/lang/psi/JetPsiUtilTest.java
@@ -29,6 +29,8 @@ import org.jetbrains.jet.lang.resolve.name.Name;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
public class JetPsiUtilTest extends JetLiteFixture {
public void testUnquotedIdentifier() {
@@ -85,6 +87,14 @@ public class JetPsiUtilTest extends JetLiteFixture {
}
}
+ public void testIsSelectorInExpression() {
+ checkIsSelectorInQualified();
+ }
+
+ public void testIsSelectorInType() {
+ checkIsSelectorInQualified();
+ }
+
@Override
protected JetCoreEnvironment createEnvironment() {
return new JetCoreEnvironment(getTestRootDisposable(), new CompilerConfiguration());
@@ -98,4 +108,29 @@ public class JetPsiUtilTest extends JetLiteFixture {
return JetPsiUtil.getImportPath(importDirective);
}
+
+ private void checkIsSelectorInQualified() {
+ String trueResultString = "/*true*/";
+ String falseResultString = "/*false*/";
+
+ JetFile file = loadPsiFile(new File("psiUtil/" + getTestName(true) + ".kt").getPath());
+ String text = file.getText();
+
+ // /*true*/|/*false*/
+ Pattern pattern = Pattern.compile(String.format("%s|%s", Pattern.quote(trueResultString), Pattern.quote(falseResultString)));
+ Matcher matcher = pattern.matcher(text);
+
+ while (matcher.find()) {
+ boolean expected = trueResultString.equals(matcher.group());
+ int offset = matcher.end();
+
+ JetSimpleNameExpression expression = PsiTreeUtil.findElementOfClassAtOffset(file, offset, JetSimpleNameExpression.class, true);
+
+ String modifiedWithOffset = new StringBuilder(text).insert(offset, "<======caret======>").toString();
+
+ Assert.assertNotNull("Can't find expression in text:\n" + modifiedWithOffset, expression);
+ Assert.assertSame(expected + " result was expected at\n" + modifiedWithOffset,
+ expected, JetPsiUtil.isSelectorInQualified(expression));
+ }
+ }
}
diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java
index 9e268cc73b3..6c5c91e52cc 100644
--- a/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java
+++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java
@@ -107,7 +107,7 @@ public class AutoImportFix extends JetHintAction implem
}
private static boolean isSuppressedTopLevelImportInPosition(@NotNull JetSimpleNameExpression element) {
- return element.isImportDirectiveExpression() || !JetPsiUtil.isFirstPartInQualified(element);
+ return element.isImportDirectiveExpression() || JetPsiUtil.isSelectorInQualified(element);
}
private static Collection getJetTopLevelFunctions(