Smart completion: offer class instantiating choice
This commit is contained in:
@@ -7,6 +7,14 @@
|
||||
name='com.intellij.codeInsight.completion.CompletionSorter com.intellij.codeInsight.completion.CompletionSorter weighBefore(java.lang.String, com.intellij.codeInsight.lookup.LookupElementWeigher...)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.codeInsight.completion.InsertHandler void handleInsert(com.intellij.codeInsight.completion.InsertionContext, T) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.codeInsight.completion.InsertHandler void handleInsert(com.intellij.codeInsight.completion.InsertionContext, T) 1'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='com.intellij.codeInsight.completion.InsertionContext com.intellij.openapi.project.Project getProject()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
|
||||
@@ -6,4 +6,24 @@
|
||||
<item name='com.intellij.codeInsight.lookup.Lookup com.intellij.openapi.editor.Editor getEditor()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.codeInsight.lookup.LookupElementBuilder com.intellij.codeInsight.lookup.LookupElementBuilder withInsertHandler(com.intellij.codeInsight.completion.InsertHandler<com.intellij.codeInsight.lookup.LookupElement>)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.codeInsight.lookup.LookupElementBuilder com.intellij.codeInsight.lookup.LookupElementBuilder withPresentableText(java.lang.String)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.codeInsight.lookup.LookupElementBuilder com.intellij.codeInsight.lookup.LookupElementBuilder withTailText(java.lang.String)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.codeInsight.lookup.MutableLookupElement com.intellij.codeInsight.lookup.MutableLookupElement<T> setInsertHandler(com.intellij.codeInsight.completion.InsertHandler<? extends com.intellij.codeInsight.lookup.LookupElement>)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.codeInsight.lookup.MutableLookupElement com.intellij.codeInsight.lookup.MutableLookupElement<T> setInsertHandler(com.intellij.codeInsight.completion.InsertHandler<? extends com.intellij.codeInsight.lookup.LookupElement>) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
</root>
|
||||
@@ -1,4 +1,7 @@
|
||||
<root>
|
||||
<item name='com.intellij.psi.PsiDocumentManager com.intellij.psi.PsiDocumentManager getInstance(com.intellij.openapi.project.Project)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.psi.PsiReferenceService java.util.List<com.intellij.psi.PsiReference> getReferences(com.intellij.psi.PsiElement, com.intellij.psi.PsiReferenceService.Hints)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.codeInsight.completion.CompletionParameters;
|
||||
import com.intellij.codeInsight.completion.CompletionResultSet;
|
||||
import com.intellij.codeInsight.completion.CompletionType;
|
||||
import com.intellij.codeInsight.completion.JavaCompletionContributor;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Conditions;
|
||||
@@ -133,14 +134,17 @@ class CompletionSession {
|
||||
assert parameters.getCompletionType() == CompletionType.SMART;
|
||||
|
||||
//noinspection StaticMethodReferencedViaSubclass
|
||||
final SmartCompletionFilter filter = CompletionPackage.buildSmartCompletionFilter(jetReference.getExpression(), getResolveSession());
|
||||
if (filter != null) {
|
||||
final SmartCompletionData data = CompletionPackage.buildSmartCompletionData(jetReference.getExpression(), getResolveSession());
|
||||
if (data != null) {
|
||||
addReferenceVariants(new Condition<DeclarationDescriptor>() {
|
||||
@Override
|
||||
public boolean value(DeclarationDescriptor descriptor) {
|
||||
return filter.accepts(descriptor);
|
||||
return data.accepts(descriptor);
|
||||
}
|
||||
});
|
||||
for (LookupElement element : data.getAdditionalElements()) {
|
||||
jetResult.addElement(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,29 +1,74 @@
|
||||
package org.jetbrains.jet.plugin.completion
|
||||
|
||||
import com.intellij.codeInsight.completion.*
|
||||
import com.intellij.util.*
|
||||
import org.jetbrains.jet.lang.descriptors.*
|
||||
import org.jetbrains.jet.lang.resolve.*
|
||||
import org.jetbrains.jet.lang.psi.*
|
||||
import org.jetbrains.jet.lexer.JetToken
|
||||
import org.jetbrains.jet.lexer.JetTokens
|
||||
import org.jetbrains.jet.plugin.project.CancelableResolveSession
|
||||
import org.jetbrains.jet.lang.types.JetType
|
||||
import org.jetbrains.jet.lang.types.*
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
|
||||
import com.intellij.codeInsight.lookup.*
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer
|
||||
import com.intellij.codeInsight.completion.InsertionContext
|
||||
import com.intellij.codeInsight.completion.InsertHandler
|
||||
import org.jetbrains.jet.plugin.completion.handlers.*
|
||||
import com.intellij.codeInsight.completion.JavaPsiClassReferenceElement
|
||||
|
||||
trait SmartCompletionFilter{
|
||||
trait SmartCompletionData{
|
||||
fun accepts(descriptor: DeclarationDescriptor): Boolean
|
||||
val additionalElements: Iterable<LookupElement>
|
||||
}
|
||||
|
||||
fun buildSmartCompletionFilter(expression: JetSimpleNameExpression, resolveSession: CancelableResolveSession): SmartCompletionFilter? {
|
||||
fun buildSmartCompletionData(expression: JetSimpleNameExpression, resolveSession: CancelableResolveSession): SmartCompletionData? {
|
||||
val parent = expression.getParent()
|
||||
val expressionWithType = if (parent is JetQualifiedExpression) parent else expression
|
||||
val expectedType: JetType? = resolveSession.resolveToElement(expressionWithType).get(BindingContext.EXPECTED_EXPRESSION_TYPE, expressionWithType)
|
||||
val bindingContext = resolveSession.resolveToElement(expressionWithType)
|
||||
val expectedType: JetType? = bindingContext.get(BindingContext.EXPECTED_EXPRESSION_TYPE, expressionWithType)
|
||||
if (expectedType == null) return null
|
||||
|
||||
val itemsToSkip = calcItemsToSkip(expressionWithType, resolveSession)
|
||||
|
||||
return object: SmartCompletionFilter{
|
||||
val additionalElements = ArrayList<LookupElement>()
|
||||
|
||||
if (expression == expressionWithType) { // no qualifier
|
||||
val typeConstructor: TypeConstructor = expectedType.getConstructor()
|
||||
val classifier: ClassifierDescriptor? = typeConstructor.getDeclarationDescriptor()
|
||||
if (classifier is ClassDescriptor) {
|
||||
if (classifier.getModality() != Modality.ABSTRACT){
|
||||
val lookupElement = DescriptorLookupConverter.createLookupElement(resolveSession, bindingContext, classifier)
|
||||
|
||||
val typeArgs = expectedType.getArguments()
|
||||
//TODO: shouldn't be method in DescriptorRenderer to render type arguments?
|
||||
val typeArgsText =
|
||||
if (typeArgs.isEmpty())
|
||||
""
|
||||
else
|
||||
typeArgs.map { DescriptorRenderer.TEXT.renderType(it.getType()) }.makeString(", ", "<", ">")
|
||||
val presentableText = lookupElement.getLookupString() + typeArgsText + "()"
|
||||
|
||||
val constructors: Collection<ConstructorDescriptor> = classifier.getConstructors()
|
||||
val caretPosition =
|
||||
if (constructors.size == 0)
|
||||
CaretPosition.AFTER_BRACKETS
|
||||
else if (constructors.size == 1)
|
||||
if (constructors.first().getValueParameters().isEmpty()) CaretPosition.AFTER_BRACKETS else CaretPosition.IN_BRACKETS
|
||||
else
|
||||
CaretPosition.IN_BRACKETS
|
||||
val insertHandler = JetFunctionInsertHandler(caretPosition, BracketType.PARENTHESIS)
|
||||
|
||||
//TODO: very bad code
|
||||
if (lookupElement is LookupElementBuilder) {
|
||||
additionalElements.add(lookupElement.withPresentableText(presentableText).withInsertHandler(insertHandler))
|
||||
}
|
||||
else if (lookupElement is JavaPsiClassReferenceElement) {
|
||||
additionalElements.add(lookupElement.setPresentableText(presentableText).setInsertHandler(insertHandler))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return object: SmartCompletionData{
|
||||
override fun accepts(descriptor: DeclarationDescriptor): Boolean {
|
||||
if (itemsToSkip.contains(descriptor)) return false
|
||||
|
||||
@@ -35,6 +80,8 @@ fun buildSmartCompletionFilter(expression: JetSimpleNameExpression, resolveSessi
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
override val additionalElements: Iterable<LookupElement> = additionalElements
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,18 +45,16 @@ public enum class BracketType {
|
||||
BRACES
|
||||
}
|
||||
|
||||
public class JetFunctionInsertHandler(val caretPosition : CaretPosition, val bracketType : BracketType) : InsertHandler<LookupElement?> {
|
||||
public class JetFunctionInsertHandler(val caretPosition : CaretPosition, val bracketType : BracketType) : InsertHandler<LookupElement> {
|
||||
{
|
||||
if (caretPosition == CaretPosition.AFTER_BRACKETS && bracketType == BracketType.BRACES) {
|
||||
throw IllegalArgumentException("CaretPosition.AFTER_BRACKETS with bracketType == BracketType.BRACES combination is not supported")
|
||||
}
|
||||
}
|
||||
|
||||
public override fun handleInsert(context: InsertionContext?, item: LookupElement?) {
|
||||
if (context == null || item == null) return
|
||||
|
||||
PsiDocumentManager.getInstance(context.getProject())?.commitAllDocuments()
|
||||
if ((context.getCompletionChar()) == '(') {
|
||||
public override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||
PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments()
|
||||
if (context.getCompletionChar() == '(') {
|
||||
context.setAddCompletionChar(false)
|
||||
}
|
||||
|
||||
@@ -105,7 +103,7 @@ public class JetFunctionInsertHandler(val caretPosition : CaretPosition, val bra
|
||||
else {
|
||||
document.insertString(offset, "()")
|
||||
}
|
||||
PsiDocumentManager.getInstance(context.getProject())?.commitDocument(document)
|
||||
PsiDocumentManager.getInstance(context.getProject()).commitDocument(document)
|
||||
documentText = document.getText()
|
||||
}
|
||||
|
||||
@@ -125,7 +123,7 @@ public class JetFunctionInsertHandler(val caretPosition : CaretPosition, val bra
|
||||
editor.getCaretModel().moveToOffset(closeBracketIndex + 1)
|
||||
}
|
||||
|
||||
PsiDocumentManager.getInstance(context.getProject())?.commitDocument(context.getDocument())
|
||||
PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getDocument())
|
||||
}
|
||||
|
||||
class object {
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
class Foo
|
||||
|
||||
var a : Foo = <caret>
|
||||
@@ -0,0 +1,3 @@
|
||||
class Foo
|
||||
|
||||
var a : Foo = Foo()<caret>
|
||||
@@ -0,0 +1,3 @@
|
||||
import java.util.Date
|
||||
|
||||
var a : Date = <caret>
|
||||
@@ -0,0 +1,3 @@
|
||||
import java.util.Date
|
||||
|
||||
var a : Date = Date(<caret>)
|
||||
@@ -0,0 +1,5 @@
|
||||
class Foo
|
||||
|
||||
fun foo(p : Object){
|
||||
var a : Foo? = <caret>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class Foo
|
||||
|
||||
fun foo(p : Object){
|
||||
var a : Foo? = Foo()<caret>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
fun foo(p: java.util.BitSet){}
|
||||
|
||||
fun f(){
|
||||
foo(<caret>)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import java.util.BitSet
|
||||
|
||||
fun foo(p: java.util.BitSet){}
|
||||
|
||||
fun f(){
|
||||
foo(BitSet(<caret>))
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class Foo(p : Int)
|
||||
|
||||
var a : Foo = <caret>
|
||||
@@ -0,0 +1,3 @@
|
||||
class Foo(p : Int)
|
||||
|
||||
var a : Foo = Foo(<caret>)
|
||||
@@ -0,0 +1,5 @@
|
||||
class Foo
|
||||
|
||||
var a : Foo = <caret>
|
||||
|
||||
// EXIST: Foo@Foo()
|
||||
@@ -0,0 +1,5 @@
|
||||
import java.util.ArrayList
|
||||
|
||||
var a : ArrayList<String> = <caret>
|
||||
|
||||
// EXIST: ArrayList@ArrayList<String>()
|
||||
@@ -0,0 +1,7 @@
|
||||
class Foo<T>
|
||||
|
||||
fun foo(p : Object){
|
||||
var a : Foo<String> = <caret>
|
||||
}
|
||||
|
||||
// EXIST: Foo@Foo<jet.String>()
|
||||
@@ -0,0 +1,5 @@
|
||||
import java.util.Date
|
||||
|
||||
var a : Date = <caret>
|
||||
|
||||
// EXIST: Date@Date()
|
||||
@@ -0,0 +1,7 @@
|
||||
class Foo
|
||||
|
||||
fun foo(p : Object){
|
||||
var a : Foo? = <caret>
|
||||
}
|
||||
|
||||
// EXIST: Foo@Foo()
|
||||
@@ -1,5 +1,5 @@
|
||||
class Foo
|
||||
class Bar : Foo
|
||||
open class Foo
|
||||
class Bar : Foo()
|
||||
|
||||
val foo = Foo()
|
||||
val bar = Bar()
|
||||
@@ -24,3 +24,4 @@ fun f3() : String{}
|
||||
// EXIST: f1
|
||||
// EXIST: f2
|
||||
// ABSENT: f3
|
||||
// EXIST: Foo@Foo()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class Foo
|
||||
class Bar : Foo
|
||||
open class Foo
|
||||
class Bar : Foo()
|
||||
|
||||
val xfoo = Foo()
|
||||
val xbar = Bar()
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
abstract class Foo
|
||||
|
||||
fun foo(p : Object){
|
||||
var a : Foo = <caret>
|
||||
}
|
||||
|
||||
// ABSENT: Foo
|
||||
@@ -0,0 +1,3 @@
|
||||
var a : Appendable = <caret>
|
||||
|
||||
// ABSENT: Appendable
|
||||
@@ -0,0 +1,7 @@
|
||||
trait Foo
|
||||
|
||||
fun foo(p : Object){
|
||||
var a : Foo = <caret>
|
||||
}
|
||||
|
||||
// ABSENT: Foo
|
||||
@@ -0,0 +1,7 @@
|
||||
class Foo
|
||||
|
||||
fun foo(p : Object){
|
||||
var a : Foo = p.<caret>
|
||||
}
|
||||
|
||||
// ABSENT: Foo
|
||||
@@ -1,5 +1,5 @@
|
||||
class Foo
|
||||
class Bar : Foo
|
||||
open class Foo
|
||||
class Bar : Foo()
|
||||
|
||||
val xfoo = Foo()
|
||||
val xbar = Bar()
|
||||
|
||||
@@ -30,17 +30,30 @@ public abstract class JetFixtureCompletionBaseTestCase extends LightCodeInsightF
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
autocompleteSetting = CodeInsightSettings.getInstance().AUTOCOMPLETE_ON_CODE_COMPLETION;
|
||||
CodeInsightSettings.getInstance().AUTOCOMPLETE_ON_CODE_COMPLETION = false;
|
||||
autocompleteSetting = setAutocompleteSetting(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
CodeInsightSettings.getInstance().AUTOCOMPLETE_ON_CODE_COMPLETION = autocompleteSetting;
|
||||
setAutocompleteSetting(autocompleteSetting);
|
||||
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
private boolean setAutocompleteSetting(boolean value){
|
||||
CodeInsightSettings settings = CodeInsightSettings.getInstance();
|
||||
boolean oldValue;
|
||||
if (completionType() == CompletionType.SMART){
|
||||
oldValue = settings.AUTOCOMPLETE_ON_SMART_TYPE_COMPLETION;
|
||||
settings.AUTOCOMPLETE_ON_SMART_TYPE_COMPLETION = value;
|
||||
}
|
||||
else{
|
||||
oldValue = settings.AUTOCOMPLETE_COMMON_PREFIX;
|
||||
settings.AUTOCOMPLETE_ON_CODE_COMPLETION = value;
|
||||
}
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
public abstract TargetPlatform getPlatform();
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -41,6 +41,21 @@ public class JetSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
|
||||
doTest("idea/testData/completion/smart/ChainedCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Constructor.kt")
|
||||
public void testConstructor() throws Exception {
|
||||
doTest("idea/testData/completion/smart/Constructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ConstructorForGenericType.kt")
|
||||
public void testConstructorForGenericType() throws Exception {
|
||||
doTest("idea/testData/completion/smart/ConstructorForGenericType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ConstructorForNullable.kt")
|
||||
public void testConstructorForNullable() throws Exception {
|
||||
doTest("idea/testData/completion/smart/ConstructorForNullable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("EmptyPrefix.kt")
|
||||
public void testEmptyPrefix() throws Exception {
|
||||
doTest("idea/testData/completion/smart/EmptyPrefix.kt");
|
||||
@@ -56,6 +71,26 @@ public class JetSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
|
||||
doTest("idea/testData/completion/smart/MethodCallArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NoConstructorForAbstract.kt")
|
||||
public void testNoConstructorForAbstract() throws Exception {
|
||||
doTest("idea/testData/completion/smart/NoConstructorForAbstract.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NoConstructorForJavaInterface.kt")
|
||||
public void testNoConstructorForJavaInterface() throws Exception {
|
||||
doTest("idea/testData/completion/smart/NoConstructorForJavaInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NoConstructorForTrait.kt")
|
||||
public void testNoConstructorForTrait() throws Exception {
|
||||
doTest("idea/testData/completion/smart/NoConstructorForTrait.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NoConstructorWithQualifier.kt")
|
||||
public void testNoConstructorWithQualifier() throws Exception {
|
||||
doTest("idea/testData/completion/smart/NoConstructorWithQualifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NoSillyAssignment.kt")
|
||||
public void testNoSillyAssignment() throws Exception {
|
||||
doTest("idea/testData/completion/smart/NoSillyAssignment.kt");
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package org.jetbrains.jet.completion.handlers
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionType
|
||||
import org.jetbrains.jet.plugin.formatter.JetCodeStyleSettings
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
||||
|
||||
public class BasicCompletionHandlerTest : CompletionHandlerTestBase(){
|
||||
override val completionType: CompletionType = CompletionType.BASIC
|
||||
override val testDataRelativePath: String = "/completion/handlers"
|
||||
|
||||
fun testClassCompletionImport() = doTest(2, "SortedSet", null, '\n')
|
||||
|
||||
fun testDoNotInsertImportForAlreadyImported() = doTest()
|
||||
|
||||
fun testDoNotInsertDefaultJsImports() = doTest()
|
||||
|
||||
fun testDoNotInsertImportIfResolvedIntoJavaConstructor() = doTest()
|
||||
|
||||
fun testNonStandardArray() = doTest(2, "Array", "java.lang.reflect", '\n')
|
||||
|
||||
fun testNoParamsFunction() = doTest()
|
||||
|
||||
fun testParamsFunction() = doTest()
|
||||
|
||||
fun testInsertJavaClassImport() = doTest()
|
||||
|
||||
fun testInsertVoidJavaMethod() = doTest()
|
||||
|
||||
fun testPropertiesSetter() = doTest()
|
||||
|
||||
fun testExistingSingleBrackets() = doTest()
|
||||
|
||||
fun testExtFunction() = doTest()
|
||||
|
||||
fun testFunctionLiteralInsertOnSpace() = doTest(2, null, null, ' ')
|
||||
|
||||
fun testInsertImportOnTab() = doTest(2, "ArrayList", null, '\t')
|
||||
|
||||
fun testHigherOrderFunction() = doTest()
|
||||
|
||||
fun testInsertFqnForJavaClass() = doTest(2, "SortedSet", "java.util", '\n')
|
||||
|
||||
fun testHigherOrderFunctionWithArg() = doTest(2, "filterNot", null, '\n')
|
||||
|
||||
fun testForceParenthesisForTabChar() = doTest(0, "some", null, '\t')
|
||||
|
||||
fun testTabInsertAtTheFileEnd() = doTest(0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertBeforeBraces() = doTest(0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertBeforeBrackets() = doTest(0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertBeforeOperator() = doTest(0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertBeforeParentheses() = doTest(0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertInsideBraces() = doTest(0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertInsideBrackets() = doTest(0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertInsideEmptyParentheses() = doTest(0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertInsideParentheses() = doTest(0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertInSimpleName() = doTest(0, "vvvvv", null, '\t')
|
||||
|
||||
fun testInsertFunctionWithSingleParameterWithBrace() = doTest(0, "some", null, '{')
|
||||
|
||||
fun testSingleBrackets() {
|
||||
fixture.configureByFile(fileName())
|
||||
fixture.`type`('(')
|
||||
checkResult()
|
||||
}
|
||||
|
||||
fun testInsertFunctionWithBothParentheses() {
|
||||
fixture.configureByFile(fileName())
|
||||
fixture.`type`("test()")
|
||||
checkResult()
|
||||
}
|
||||
|
||||
fun testFunctionLiteralInsertWhenNoSpacesForBraces() {
|
||||
val settings = CodeStyleSettingsManager.getSettings(getProject())
|
||||
val jetSettings = settings.getCustomSettings(javaClass<JetCodeStyleSettings>())!!
|
||||
|
||||
try {
|
||||
jetSettings.INSERT_WHITESPACES_IN_SIMPLE_ONE_LINE_METHOD = false
|
||||
doTest()
|
||||
}
|
||||
finally {
|
||||
jetSettings.INSERT_WHITESPACES_IN_SIMPLE_ONE_LINE_METHOD = true
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-91
@@ -32,112 +32,37 @@ import org.junit.Assert
|
||||
import com.intellij.openapi.application.Result
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
|
||||
import kotlin.properties.Delegates
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
|
||||
public class CompletionHandlerTest() : JetLightCodeInsightFixtureTestCase() {
|
||||
fun testClassCompletionImport() = doTest(CompletionType.BASIC, 2, "SortedSet", null, '\n')
|
||||
public abstract class CompletionHandlerTestBase() : JetLightCodeInsightFixtureTestCase() {
|
||||
protected abstract val completionType : CompletionType
|
||||
protected abstract val testDataRelativePath: String
|
||||
|
||||
fun testDoNotInsertImportForAlreadyImported() = doTest()
|
||||
|
||||
fun testDoNotInsertDefaultJsImports() = doTest()
|
||||
|
||||
fun testDoNotInsertImportIfResolvedIntoJavaConstructor() = doTest()
|
||||
|
||||
fun testNonStandardArray() = doTest(CompletionType.BASIC, 2, "Array", "java.lang.reflect", '\n')
|
||||
|
||||
fun testNoParamsFunction() = doTest()
|
||||
|
||||
fun testParamsFunction() = doTest()
|
||||
|
||||
fun testInsertJavaClassImport() = doTest()
|
||||
|
||||
fun testInsertVoidJavaMethod() = doTest()
|
||||
|
||||
fun testPropertiesSetter() = doTest()
|
||||
|
||||
fun testExistingSingleBrackets() = doTest()
|
||||
|
||||
fun testExtFunction() = doTest()
|
||||
|
||||
fun testFunctionLiteralInsertOnSpace() = doTest(CompletionType.BASIC, 2, null, null, ' ')
|
||||
|
||||
fun testInsertImportOnTab() = doTest(CompletionType.BASIC, 2, "ArrayList", null, '\t')
|
||||
|
||||
fun testHigherOrderFunction() = doTest()
|
||||
|
||||
fun testInsertFqnForJavaClass() = doTest(CompletionType.BASIC, 2, "SortedSet", "java.util", '\n')
|
||||
|
||||
fun testHigherOrderFunctionWithArg() = doTest(CompletionType.BASIC, 2, "filterNot", null, '\n')
|
||||
|
||||
fun testForceParenthesisForTabChar() = doTest(CompletionType.BASIC, 0, "some", null, '\t')
|
||||
|
||||
fun testTabInsertAtTheFileEnd() = doTest(CompletionType.BASIC, 0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertBeforeBraces() = doTest(CompletionType.BASIC, 0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertBeforeBrackets() = doTest(CompletionType.BASIC, 0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertBeforeOperator() = doTest(CompletionType.BASIC, 0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertBeforeParentheses() = doTest(CompletionType.BASIC, 0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertInsideBraces() = doTest(CompletionType.BASIC, 0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertInsideBrackets() = doTest(CompletionType.BASIC, 0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertInsideEmptyParentheses() = doTest(CompletionType.BASIC, 0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertInsideParentheses() = doTest(CompletionType.BASIC, 0, "vvvvv", null, '\t')
|
||||
|
||||
fun testTabInsertInSimpleName() = doTest(CompletionType.BASIC, 0, "vvvvv", null, '\t')
|
||||
|
||||
fun testInsertFunctionWithSingleParameterWithBrace() = doTest(CompletionType.BASIC, 0, "some", null, '{')
|
||||
|
||||
var fixture by Delegates.notNull<JavaCodeInsightTestFixture>()
|
||||
protected var fixture: JavaCodeInsightTestFixture by Delegates.notNull<JavaCodeInsightTestFixture>()
|
||||
|
||||
protected override fun setUp() {
|
||||
super.setUp()
|
||||
fixture = myFixture!!
|
||||
}
|
||||
|
||||
fun testSingleBrackets() {
|
||||
fixture.configureByFile(fileName())
|
||||
fixture.`type`('(')
|
||||
fixture.checkResultByFile(afterFileName())
|
||||
}
|
||||
protected fun doTest() : Unit = doTest(2, null, null, '\n')
|
||||
|
||||
fun testInsertFunctionWithBothParentheses() {
|
||||
fixture.configureByFile(fileName())
|
||||
fixture.`type`("test()")
|
||||
fixture.checkResultByFile(afterFileName())
|
||||
}
|
||||
|
||||
fun testFunctionLiteralInsertWhenNoSpacesForBraces() {
|
||||
val settings = CodeStyleSettingsManager.getSettings(getProject())
|
||||
val jetSettings = settings.getCustomSettings(javaClass<JetCodeStyleSettings>())!!
|
||||
|
||||
try {
|
||||
jetSettings.INSERT_WHITESPACES_IN_SIMPLE_ONE_LINE_METHOD = false
|
||||
doTest()
|
||||
}
|
||||
finally {
|
||||
jetSettings.INSERT_WHITESPACES_IN_SIMPLE_ONE_LINE_METHOD = true
|
||||
}
|
||||
}
|
||||
|
||||
fun doTest() = doTest(CompletionType.BASIC, 2, null, null, '\n')
|
||||
|
||||
private fun doTest(`type` : CompletionType, time : Int, lookupString : String?, tailText : String?, completionChar : Char) : Unit {
|
||||
protected fun doTest(time : Int, lookupString : String?, tailText : String?, completionChar : Char) : Unit {
|
||||
fixture.configureByFile(fileName())
|
||||
if (lookupString != null || tailText != null) {
|
||||
fixture.complete(`type`, time)
|
||||
fixture.complete(completionType, time)
|
||||
val item = getExistentLookupElement(lookupString, tailText)
|
||||
if (item != null) {
|
||||
selectItem(item, completionChar)
|
||||
}
|
||||
}
|
||||
else {
|
||||
forceCompleteFirst(`type`, time)
|
||||
forceCompleteFirst(completionType, time)
|
||||
}
|
||||
checkResult()
|
||||
}
|
||||
|
||||
protected fun checkResult(){
|
||||
fixture.checkResultByFile(afterFileName())
|
||||
}
|
||||
|
||||
@@ -180,9 +105,9 @@ public class CompletionHandlerTest() : JetLightCodeInsightFixtureTestCase() {
|
||||
return foundElement
|
||||
}
|
||||
|
||||
fun afterFileName() = getTestName(false) + ".kt.after"
|
||||
protected fun afterFileName(): String = getTestName(false) + ".kt.after"
|
||||
|
||||
fun forceCompleteFirst(`type` : CompletionType, time : Int) {
|
||||
private fun forceCompleteFirst(`type` : CompletionType, time : Int) {
|
||||
fixture.complete(`type`, time)
|
||||
val items : Array<LookupElement>? = fixture.getLookupElements()
|
||||
if (items != null && items.isNotEmpty()) {
|
||||
@@ -190,7 +115,7 @@ public class CompletionHandlerTest() : JetLightCodeInsightFixtureTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
protected override fun getTestDataPath() : String = File(PluginTestCaseBase.getTestDataPathBase(), "/completion/handlers/").getPath() + File.separator
|
||||
protected override fun getTestDataPath() : String = File(PluginTestCaseBase.getTestDataPathBase(), testDataRelativePath).getPath() + File.separator
|
||||
|
||||
protected fun selectItem(item : LookupElement?) {
|
||||
selectItem(item, 0.toChar())
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.completion.handlers
|
||||
|
||||
import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase
|
||||
import com.intellij.codeInsight.completion.CompletionType
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
||||
import org.jetbrains.jet.plugin.formatter.JetCodeStyleSettings
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import java.io.File
|
||||
import org.jetbrains.jet.plugin.PluginTestCaseBase
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl
|
||||
import com.intellij.codeInsight.lookup.LookupEvent
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.codeInsight.lookup.LookupManager
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
||||
import org.junit.Assert
|
||||
import com.intellij.openapi.application.Result
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
public class SmartCompletionHandlerTest() : CompletionHandlerTestBase() {
|
||||
override val completionType: CompletionType = CompletionType.SMART
|
||||
override val testDataRelativePath: String = "/completion/handlers/smart"
|
||||
|
||||
fun testConstructor() = doTest()
|
||||
fun testConstructorWithParameters() = doTest()
|
||||
fun testConstructorForNullable() = doTest()
|
||||
fun testConstructorForJavaClass() = doTest()
|
||||
//fun testConstructorInsertsImport() = doTest() //TODO
|
||||
}
|
||||
Reference in New Issue
Block a user