Rewrite isFirstPartInQualified to work properly inside call expressions

#KT-4000 In Progress
This commit is contained in:
Nikolay Krasko
2013-09-23 18:41:43 +04:00
parent ed250198d8
commit 143d8d945c
6 changed files with 166 additions and 10 deletions
+24
View File
@@ -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(