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...)'>
|
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'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</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()'>
|
<item name='com.intellij.codeInsight.completion.InsertionContext com.intellij.openapi.project.Project getProject()'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -6,4 +6,24 @@
|
|||||||
<item name='com.intellij.codeInsight.lookup.Lookup com.intellij.openapi.editor.Editor getEditor()'>
|
<item name='com.intellij.codeInsight.lookup.Lookup com.intellij.openapi.editor.Editor getEditor()'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</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>
|
</root>
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
<root>
|
<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
|
<item
|
||||||
name='com.intellij.psi.PsiReferenceService java.util.List<com.intellij.psi.PsiReference> getReferences(com.intellij.psi.PsiElement, com.intellij.psi.PsiReferenceService.Hints)'>
|
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'/>
|
<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.CompletionResultSet;
|
||||||
import com.intellij.codeInsight.completion.CompletionType;
|
import com.intellij.codeInsight.completion.CompletionType;
|
||||||
import com.intellij.codeInsight.completion.JavaCompletionContributor;
|
import com.intellij.codeInsight.completion.JavaCompletionContributor;
|
||||||
|
import com.intellij.codeInsight.lookup.LookupElement;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.util.Condition;
|
import com.intellij.openapi.util.Condition;
|
||||||
import com.intellij.openapi.util.Conditions;
|
import com.intellij.openapi.util.Conditions;
|
||||||
@@ -133,14 +134,17 @@ class CompletionSession {
|
|||||||
assert parameters.getCompletionType() == CompletionType.SMART;
|
assert parameters.getCompletionType() == CompletionType.SMART;
|
||||||
|
|
||||||
//noinspection StaticMethodReferencedViaSubclass
|
//noinspection StaticMethodReferencedViaSubclass
|
||||||
final SmartCompletionFilter filter = CompletionPackage.buildSmartCompletionFilter(jetReference.getExpression(), getResolveSession());
|
final SmartCompletionData data = CompletionPackage.buildSmartCompletionData(jetReference.getExpression(), getResolveSession());
|
||||||
if (filter != null) {
|
if (data != null) {
|
||||||
addReferenceVariants(new Condition<DeclarationDescriptor>() {
|
addReferenceVariants(new Condition<DeclarationDescriptor>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean value(DeclarationDescriptor descriptor) {
|
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
|
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.descriptors.*
|
||||||
import org.jetbrains.jet.lang.resolve.*
|
import org.jetbrains.jet.lang.resolve.*
|
||||||
import org.jetbrains.jet.lang.psi.*
|
import org.jetbrains.jet.lang.psi.*
|
||||||
import org.jetbrains.jet.lexer.JetToken
|
|
||||||
import org.jetbrains.jet.lexer.JetTokens
|
import org.jetbrains.jet.lexer.JetTokens
|
||||||
import org.jetbrains.jet.plugin.project.CancelableResolveSession
|
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 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
|
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 parent = expression.getParent()
|
||||||
val expressionWithType = if (parent is JetQualifiedExpression) parent else expression
|
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
|
if (expectedType == null) return null
|
||||||
|
|
||||||
val itemsToSkip = calcItemsToSkip(expressionWithType, resolveSession)
|
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 {
|
override fun accepts(descriptor: DeclarationDescriptor): Boolean {
|
||||||
if (itemsToSkip.contains(descriptor)) return false
|
if (itemsToSkip.contains(descriptor)) return false
|
||||||
|
|
||||||
@@ -35,6 +80,8 @@ fun buildSmartCompletionFilter(expression: JetSimpleNameExpression, resolveSessi
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val additionalElements: Iterable<LookupElement> = additionalElements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,18 +45,16 @@ public enum class BracketType {
|
|||||||
BRACES
|
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) {
|
if (caretPosition == CaretPosition.AFTER_BRACKETS && bracketType == BracketType.BRACES) {
|
||||||
throw IllegalArgumentException("CaretPosition.AFTER_BRACKETS with bracketType == BracketType.BRACES combination is not supported")
|
throw IllegalArgumentException("CaretPosition.AFTER_BRACKETS with bracketType == BracketType.BRACES combination is not supported")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun handleInsert(context: InsertionContext?, item: LookupElement?) {
|
public override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
if (context == null || item == null) return
|
PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments()
|
||||||
|
if (context.getCompletionChar() == '(') {
|
||||||
PsiDocumentManager.getInstance(context.getProject())?.commitAllDocuments()
|
|
||||||
if ((context.getCompletionChar()) == '(') {
|
|
||||||
context.setAddCompletionChar(false)
|
context.setAddCompletionChar(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +103,7 @@ public class JetFunctionInsertHandler(val caretPosition : CaretPosition, val bra
|
|||||||
else {
|
else {
|
||||||
document.insertString(offset, "()")
|
document.insertString(offset, "()")
|
||||||
}
|
}
|
||||||
PsiDocumentManager.getInstance(context.getProject())?.commitDocument(document)
|
PsiDocumentManager.getInstance(context.getProject()).commitDocument(document)
|
||||||
documentText = document.getText()
|
documentText = document.getText()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +123,7 @@ public class JetFunctionInsertHandler(val caretPosition : CaretPosition, val bra
|
|||||||
editor.getCaretModel().moveToOffset(closeBracketIndex + 1)
|
editor.getCaretModel().moveToOffset(closeBracketIndex + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
PsiDocumentManager.getInstance(context.getProject())?.commitDocument(context.getDocument())
|
PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getDocument())
|
||||||
}
|
}
|
||||||
|
|
||||||
class object {
|
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
|
open class Foo
|
||||||
class Bar : Foo
|
class Bar : Foo()
|
||||||
|
|
||||||
val foo = Foo()
|
val foo = Foo()
|
||||||
val bar = Bar()
|
val bar = Bar()
|
||||||
@@ -24,3 +24,4 @@ fun f3() : String{}
|
|||||||
// EXIST: f1
|
// EXIST: f1
|
||||||
// EXIST: f2
|
// EXIST: f2
|
||||||
// ABSENT: f3
|
// ABSENT: f3
|
||||||
|
// EXIST: Foo@Foo()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
class Foo
|
open class Foo
|
||||||
class Bar : Foo
|
class Bar : Foo()
|
||||||
|
|
||||||
val xfoo = Foo()
|
val xfoo = Foo()
|
||||||
val xbar = Bar()
|
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
|
open class Foo
|
||||||
class Bar : Foo
|
class Bar : Foo()
|
||||||
|
|
||||||
val xfoo = Foo()
|
val xfoo = Foo()
|
||||||
val xbar = Bar()
|
val xbar = Bar()
|
||||||
|
|||||||
@@ -30,17 +30,30 @@ public abstract class JetFixtureCompletionBaseTestCase extends LightCodeInsightF
|
|||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
|
|
||||||
autocompleteSetting = CodeInsightSettings.getInstance().AUTOCOMPLETE_ON_CODE_COMPLETION;
|
autocompleteSetting = setAutocompleteSetting(false);
|
||||||
CodeInsightSettings.getInstance().AUTOCOMPLETE_ON_CODE_COMPLETION = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void tearDown() throws Exception {
|
protected void tearDown() throws Exception {
|
||||||
CodeInsightSettings.getInstance().AUTOCOMPLETE_ON_CODE_COMPLETION = autocompleteSetting;
|
setAutocompleteSetting(autocompleteSetting);
|
||||||
|
|
||||||
super.tearDown();
|
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();
|
public abstract TargetPlatform getPlatform();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -41,6 +41,21 @@ public class JetSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
|
|||||||
doTest("idea/testData/completion/smart/ChainedCall.kt");
|
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")
|
@TestMetadata("EmptyPrefix.kt")
|
||||||
public void testEmptyPrefix() throws Exception {
|
public void testEmptyPrefix() throws Exception {
|
||||||
doTest("idea/testData/completion/smart/EmptyPrefix.kt");
|
doTest("idea/testData/completion/smart/EmptyPrefix.kt");
|
||||||
@@ -56,6 +71,26 @@ public class JetSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
|
|||||||
doTest("idea/testData/completion/smart/MethodCallArgument.kt");
|
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")
|
@TestMetadata("NoSillyAssignment.kt")
|
||||||
public void testNoSillyAssignment() throws Exception {
|
public void testNoSillyAssignment() throws Exception {
|
||||||
doTest("idea/testData/completion/smart/NoSillyAssignment.kt");
|
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.openapi.application.Result
|
||||||
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
|
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
|
||||||
public class CompletionHandlerTest() : JetLightCodeInsightFixtureTestCase() {
|
public abstract class CompletionHandlerTestBase() : JetLightCodeInsightFixtureTestCase() {
|
||||||
fun testClassCompletionImport() = doTest(CompletionType.BASIC, 2, "SortedSet", null, '\n')
|
protected abstract val completionType : CompletionType
|
||||||
|
protected abstract val testDataRelativePath: String
|
||||||
|
|
||||||
fun testDoNotInsertImportForAlreadyImported() = doTest()
|
protected var fixture: JavaCodeInsightTestFixture by Delegates.notNull<JavaCodeInsightTestFixture>()
|
||||||
|
|
||||||
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 override fun setUp() {
|
protected override fun setUp() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
fixture = myFixture!!
|
fixture = myFixture!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testSingleBrackets() {
|
protected fun doTest() : Unit = doTest(2, null, null, '\n')
|
||||||
fixture.configureByFile(fileName())
|
|
||||||
fixture.`type`('(')
|
|
||||||
fixture.checkResultByFile(afterFileName())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testInsertFunctionWithBothParentheses() {
|
protected fun doTest(time : Int, lookupString : String?, tailText : String?, completionChar : Char) : Unit {
|
||||||
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 {
|
|
||||||
fixture.configureByFile(fileName())
|
fixture.configureByFile(fileName())
|
||||||
if (lookupString != null || tailText != null) {
|
if (lookupString != null || tailText != null) {
|
||||||
fixture.complete(`type`, time)
|
fixture.complete(completionType, time)
|
||||||
val item = getExistentLookupElement(lookupString, tailText)
|
val item = getExistentLookupElement(lookupString, tailText)
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
selectItem(item, completionChar)
|
selectItem(item, completionChar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
forceCompleteFirst(`type`, time)
|
forceCompleteFirst(completionType, time)
|
||||||
}
|
}
|
||||||
|
checkResult()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun checkResult(){
|
||||||
fixture.checkResultByFile(afterFileName())
|
fixture.checkResultByFile(afterFileName())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,9 +105,9 @@ public class CompletionHandlerTest() : JetLightCodeInsightFixtureTestCase() {
|
|||||||
return foundElement
|
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)
|
fixture.complete(`type`, time)
|
||||||
val items : Array<LookupElement>? = fixture.getLookupElements()
|
val items : Array<LookupElement>? = fixture.getLookupElements()
|
||||||
if (items != null && items.isNotEmpty()) {
|
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?) {
|
protected fun selectItem(item : LookupElement?) {
|
||||||
selectItem(item, 0.toChar())
|
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