Smart completion: checking constructor's visibility + true and false for Boolean

#KT-4916 Fixed
This commit is contained in:
Valentin Kipyatkov
2014-04-29 19:43:19 +04:00
parent 9ae59db329
commit 32405e57e6
13 changed files with 100 additions and 13 deletions
@@ -0,0 +1,15 @@
package org.jetbrains.jet.plugin.completion.smart
import com.intellij.codeInsight.lookup.LookupElement
import org.jetbrains.jet.plugin.completion.ExpectedInfo
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import com.intellij.codeInsight.lookup.LookupElementBuilder
object KeywordValues {
public fun addToCollection(collection: MutableCollection<LookupElement>, expectedInfos: Collection<ExpectedInfo>) {
if (expectedInfos.any { it.`type` == KotlinBuiltIns.getInstance().getBooleanType() }) {
collection.add(LookupElementBuilder.create("true").bold())
collection.add(LookupElementBuilder.create("false").bold())
}
}
}
@@ -103,13 +103,15 @@ class SmartCompletion(val expression: JetSimpleNameExpression,
}
if (receiver == null) {
TypeInstantiationItems(bindingContext, resolveSession).addToCollection(result, expectedInfos)
TypeInstantiationItems(bindingContext, resolveSession, visibilityFilter).addToCollection(result, expectedInfos)
StaticMembers(bindingContext, resolveSession).addToCollection(result, expectedInfos, expression)
ThisItems(bindingContext).addToCollection(result, expressionWithType, expectedInfos)
LambdaItems.addToCollection(result, functionExpectedInfos)
KeywordValues.addToCollection(result, expectedInfos)
}
return result
@@ -35,8 +35,12 @@ import org.jetbrains.jet.plugin.project.ResolveSessionForBodies
import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler
import org.jetbrains.jet.plugin.completion.*
import org.jetbrains.jet.plugin.completion.handlers.CaretPosition
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.descriptors.Visibilities
class TypeInstantiationItems(val bindingContext: BindingContext, val resolveSession: ResolveSessionForBodies) {
class TypeInstantiationItems(val bindingContext: BindingContext,
val resolveSession: ResolveSessionForBodies,
val visibilityFilter: (DeclarationDescriptor) -> Boolean) {
public fun addToCollection(collection: MutableCollection<LookupElement>, expectedInfos: Collection<ExpectedInfo>) {
val expectedInfosGrouped: Map<JetType, List<ExpectedInfo>> = expectedInfos.groupBy { TypeUtils.makeNotNullable(it.`type`) }
for ((jetType, types) in expectedInfosGrouped) {
@@ -50,7 +54,16 @@ class TypeInstantiationItems(val bindingContext: BindingContext, val resolveSess
val classifier = jetType.getConstructor().getDeclarationDescriptor()
if (!(classifier is ClassDescriptor)) return
//TODO: check for constructor's visibility
val isAbstract = classifier.getModality() == Modality.ABSTRACT
val allConstructors = classifier.getConstructors()
val visibleConstructors = allConstructors.filter {
if (isAbstract)
visibilityFilter(it) || it.getVisibility() == Visibilities.PROTECTED
else
visibilityFilter(it)
}
if (allConstructors.isNotEmpty() && visibleConstructors.isEmpty()) return
var lookupElement = createLookupElement(classifier, resolveSession, bindingContext)
@@ -61,7 +74,7 @@ class TypeInstantiationItems(val bindingContext: BindingContext, val resolveSess
val insertHandler: InsertHandler<LookupElement>
val typeText = DescriptorUtils.getFqName(classifier).toString() + DescriptorRenderer.SOURCE_CODE.renderTypeArguments(typeArgs)
if (classifier.getModality() == Modality.ABSTRACT) {
if (isAbstract) {
val constructorParenthesis = if (classifier.getKind() != ClassKind.TRAIT) "()" else ""
itemText += constructorParenthesis
itemText = "object: " + itemText + "{...}"
@@ -82,12 +95,11 @@ class TypeInstantiationItems(val bindingContext: BindingContext, val resolveSess
else {
//TODO: when constructor has one parameter of lambda type with more than one parameter, generate special additional item
itemText += "()"
val constructors = classifier.getConstructors()
val baseInsertHandler =
(if (constructors.size == 0)
(if (visibleConstructors.size == 0)
JetFunctionInsertHandler.NO_PARAMETERS_HANDLER
else if (constructors.size == 1)
DescriptorLookupConverter.getDefaultInsertHandler(constructors.first())!!
else if (visibleConstructors.size == 1)
DescriptorLookupConverter.getDefaultInsertHandler(visibleConstructors.single())!!
else
JetFunctionInsertHandler.WITH_PARAMETERS_HANDLER) as JetFunctionInsertHandler
insertHandler = object : InsertHandler<LookupElement> {
@@ -0,0 +1,3 @@
fun foo(): Boolean = <caret>
// ELEMENT: true
@@ -0,0 +1,3 @@
fun foo(): Boolean = true<caret>
// ELEMENT: true
@@ -0,0 +1,5 @@
fun foo(): Boolean = <caret>
// EXIST: true
// EXIST: false
// ABSENT: Boolean
@@ -0,0 +1,5 @@
import java.util.Date
var a : Date = <caret>
// EXIST: { lookupString:"Date", itemText:"Date()" }
@@ -1,5 +0,0 @@
import java.util.Date
var a : Date = <caret>
// EXIST: Date@Date()
@@ -0,0 +1,5 @@
class Foo protected()
var a : Foo = <caret>
// ABSENT: Foo
@@ -0,0 +1,6 @@
abstract class Foo private()
var a : Foo = <caret>
// ABSENT: Foo
// ABSENT: object
@@ -0,0 +1,6 @@
abstract class Foo protected()
var a : Foo = <caret>
// ABSENT: Foo
// EXIST: { lookupString:"object", itemText:"object: Foo(){...}" }
@@ -91,6 +91,11 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
doTest("idea/testData/completion/smart/BeforeArgumentWithBinaryOperation3.kt");
}
@TestMetadata("BooleanExpected.kt")
public void testBooleanExpected() throws Exception {
doTest("idea/testData/completion/smart/BooleanExpected.kt");
}
@TestMetadata("ChainedCall.kt")
public void testChainedCall() throws Exception {
doTest("idea/testData/completion/smart/ChainedCall.kt");
@@ -116,6 +121,11 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
doTest("idea/testData/completion/smart/ConstructorForGenericType.kt");
}
@TestMetadata("ConstructorForJavaClass.kt")
public void testConstructorForJavaClass() throws Exception {
doTest("idea/testData/completion/smart/ConstructorForJavaClass.kt");
}
@TestMetadata("ConstructorForNullable.kt")
public void testConstructorForNullable() throws Exception {
doTest("idea/testData/completion/smart/ConstructorForNullable.kt");
@@ -171,6 +181,11 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
doTest("idea/testData/completion/smart/FunctionReference9.kt");
}
@TestMetadata("InaccessibleConstructor.kt")
public void testInaccessibleConstructor() throws Exception {
doTest("idea/testData/completion/smart/InaccessibleConstructor.kt");
}
@TestMetadata("InsideIdentifier.kt")
public void testInsideIdentifier() throws Exception {
doTest("idea/testData/completion/smart/InsideIdentifier.kt");
@@ -286,6 +301,16 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
doTest("idea/testData/completion/smart/OverloadedMethodCallArgument2.kt");
}
@TestMetadata("PrivateConstructorForAbstract.kt")
public void testPrivateConstructorForAbstract() throws Exception {
doTest("idea/testData/completion/smart/PrivateConstructorForAbstract.kt");
}
@TestMetadata("ProtectedConstructorForAbstract.kt")
public void testProtectedConstructorForAbstract() throws Exception {
doTest("idea/testData/completion/smart/ProtectedConstructorForAbstract.kt");
}
@TestMetadata("QualifiedOverloadedMethodCallArgument1.kt")
public void testQualifiedOverloadedMethodCallArgument1() throws Exception {
doTest("idea/testData/completion/smart/QualifiedOverloadedMethodCallArgument1.kt");
@@ -356,4 +356,9 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion
doTest("idea/testData/completion/handlers/smart/TabReplaceOperand.kt");
}
@TestMetadata("True.kt")
public void testTrue() throws Exception {
doTest("idea/testData/completion/handlers/smart/True.kt");
}
}