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="PARENT_SETTINGS_INSTALLED" value="true" />
|
||||
</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">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ public class AutoImportFix extends JetHintAction<JetSimpleNameExpression> implem
|
||||
}
|
||||
|
||||
private static boolean isSuppressedTopLevelImportInPosition(@NotNull JetSimpleNameExpression element) {
|
||||
return element.isImportDirectiveExpression() || !JetPsiUtil.isFirstPartInQualified(element);
|
||||
return element.isImportDirectiveExpression() || JetPsiUtil.isSelectorInQualified(element);
|
||||
}
|
||||
|
||||
private static Collection<FqName> getJetTopLevelFunctions(
|
||||
|
||||
Reference in New Issue
Block a user