Rewrite isFirstPartInQualified to work properly inside call expressions
#KT-4000 In Progress
This commit is contained in:
Generated
+24
@@ -214,6 +214,30 @@
|
|||||||
<option name="FOR_BRACE_FORCE" value="1" />
|
<option name="FOR_BRACE_FORCE" value="1" />
|
||||||
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
|
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
|
||||||
</codeStyleSettings>
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="Scala">
|
||||||
|
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
|
||||||
|
<option name="ELSE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="WHILE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="CATCH_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="FINALLY_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />
|
||||||
|
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||||
|
<option name="METHOD_PARAMETERS_WRAP" value="5" />
|
||||||
|
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||||
|
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
|
||||||
|
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
|
||||||
|
<option name="BINARY_OPERATION_WRAP" value="5" />
|
||||||
|
<option name="FOR_STATEMENT_WRAP" value="5" />
|
||||||
|
<option name="IF_BRACE_FORCE" value="1" />
|
||||||
|
<option name="DOWHILE_BRACE_FORCE" value="1" />
|
||||||
|
<option name="WHILE_BRACE_FORCE" value="1" />
|
||||||
|
<option name="FOR_BRACE_FORCE" value="1" />
|
||||||
|
<option name="FIELD_ANNOTATION_WRAP" value="0" />
|
||||||
|
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
|
||||||
|
</codeStyleSettings>
|
||||||
<codeStyleSettings language="XML">
|
<codeStyleSettings language="XML">
|
||||||
<indentOptions>
|
<indentOptions>
|
||||||
<option name="INDENT_SIZE" value="2" />
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
|||||||
@@ -403,19 +403,21 @@ public class JetPsiUtil {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isFirstPartInQualified(@NotNull JetSimpleNameExpression nameExpression) {
|
public static boolean isSelectorInQualified(@NotNull JetSimpleNameExpression nameExpression) {
|
||||||
@SuppressWarnings("unchecked") JetUserType userType = PsiTreeUtil.getParentOfType(nameExpression, JetUserType.class, true,
|
PsiElement nameExpressionParent = nameExpression.getParent();
|
||||||
JetDeclaration.class);
|
|
||||||
if (userType != null) {
|
if (nameExpressionParent instanceof JetUserType) {
|
||||||
return PsiTreeUtil.isAncestor(userType.getFirstChild(), nameExpression, false);
|
assert ((JetUserType) nameExpressionParent).getReferenceExpression() == nameExpression;
|
||||||
|
return ((JetUserType) nameExpressionParent).getQualifier() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked") JetQualifiedExpression qualifiedExpression = PsiTreeUtil.getParentOfType(nameExpression, JetQualifiedExpression.class, true, JetDeclaration.class);
|
JetExpression selector = nameExpression;
|
||||||
if (qualifiedExpression != null) {
|
if (nameExpressionParent instanceof JetCallExpression && ((JetCallExpression) nameExpressionParent).getCalleeExpression() == nameExpression) {
|
||||||
return PsiTreeUtil.isAncestor(qualifiedExpression.getFirstChild(), nameExpression, false);
|
selector = (JetCallExpression) nameExpressionParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
PsiElement selectorParent = selector.getParent();
|
||||||
|
return selectorParent instanceof JetQualifiedExpression && (((JetQualifiedExpression) selectorParent).getSelectorExpression() == selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isVoidType(@Nullable JetTypeReference typeReference) {
|
public static boolean isVoidType(@Nullable JetTypeReference typeReference) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package test.some
|
||||||
|
|
||||||
|
class Test
|
||||||
|
class GTest<T>
|
||||||
|
|
||||||
|
fun <T1: /*false*/test.some.Test,
|
||||||
|
T2: test./*true*/some.Test,
|
||||||
|
T3: test.some./*true*/Test,
|
||||||
|
T: /*false*/Test> 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<test./*true*/some.Test>? = null
|
||||||
|
val t7: GTest<test.some./*true*/Test>? = null
|
||||||
|
val t8: GTest</*false*/Test>? = null
|
||||||
|
val t9: test.some.GTest</*false*/Test>? = null
|
||||||
|
val t10: /*false*/GTest<Test>? = null
|
||||||
|
}
|
||||||
@@ -29,6 +29,8 @@ import org.jetbrains.jet.lang.resolve.name.Name;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class JetPsiUtilTest extends JetLiteFixture {
|
public class JetPsiUtilTest extends JetLiteFixture {
|
||||||
public void testUnquotedIdentifier() {
|
public void testUnquotedIdentifier() {
|
||||||
@@ -85,6 +87,14 @@ public class JetPsiUtilTest extends JetLiteFixture {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIsSelectorInExpression() {
|
||||||
|
checkIsSelectorInQualified();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIsSelectorInType() {
|
||||||
|
checkIsSelectorInQualified();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected JetCoreEnvironment createEnvironment() {
|
protected JetCoreEnvironment createEnvironment() {
|
||||||
return new JetCoreEnvironment(getTestRootDisposable(), new CompilerConfiguration());
|
return new JetCoreEnvironment(getTestRootDisposable(), new CompilerConfiguration());
|
||||||
@@ -98,4 +108,29 @@ public class JetPsiUtilTest extends JetLiteFixture {
|
|||||||
|
|
||||||
return JetPsiUtil.getImportPath(importDirective);
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ public class AutoImportFix extends JetHintAction<JetSimpleNameExpression> implem
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSuppressedTopLevelImportInPosition(@NotNull JetSimpleNameExpression element) {
|
private static boolean isSuppressedTopLevelImportInPosition(@NotNull JetSimpleNameExpression element) {
|
||||||
return element.isImportDirectiveExpression() || !JetPsiUtil.isFirstPartInQualified(element);
|
return element.isImportDirectiveExpression() || JetPsiUtil.isSelectorInQualified(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Collection<FqName> getJetTopLevelFunctions(
|
private static Collection<FqName> getJetTopLevelFunctions(
|
||||||
|
|||||||
Reference in New Issue
Block a user