diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/KeywordValues.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/KeywordValues.kt new file mode 100644 index 00000000000..5d221e6f04d --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/KeywordValues.kt @@ -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, expectedInfos: Collection) { + if (expectedInfos.any { it.`type` == KotlinBuiltIns.getInstance().getBooleanType() }) { + collection.add(LookupElementBuilder.create("true").bold()) + collection.add(LookupElementBuilder.create("false").bold()) + } + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/SmartCompletion.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/SmartCompletion.kt index 3cba6f40903..e17c6f7c946 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/smart/SmartCompletion.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/SmartCompletion.kt @@ -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 diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/TypeInstantiationItems.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/TypeInstantiationItems.kt index 4fbbaf2a7c1..3b051841d0d 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/smart/TypeInstantiationItems.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/TypeInstantiationItems.kt @@ -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, expectedInfos: Collection) { val expectedInfosGrouped: Map> = 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 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 { diff --git a/idea/testData/completion/handlers/smart/True.kt b/idea/testData/completion/handlers/smart/True.kt new file mode 100644 index 00000000000..19d5e215724 --- /dev/null +++ b/idea/testData/completion/handlers/smart/True.kt @@ -0,0 +1,3 @@ +fun foo(): Boolean = + +// ELEMENT: true diff --git a/idea/testData/completion/handlers/smart/True.kt.after b/idea/testData/completion/handlers/smart/True.kt.after new file mode 100644 index 00000000000..0e8a5c0364d --- /dev/null +++ b/idea/testData/completion/handlers/smart/True.kt.after @@ -0,0 +1,3 @@ +fun foo(): Boolean = true + +// ELEMENT: true diff --git a/idea/testData/completion/smart/BooleanExpected.kt b/idea/testData/completion/smart/BooleanExpected.kt new file mode 100644 index 00000000000..3ddb58594a6 --- /dev/null +++ b/idea/testData/completion/smart/BooleanExpected.kt @@ -0,0 +1,5 @@ +fun foo(): Boolean = + +// EXIST: true +// EXIST: false +// ABSENT: Boolean diff --git a/idea/testData/completion/smart/ConstructorForJavaClass.kt b/idea/testData/completion/smart/ConstructorForJavaClass.kt new file mode 100644 index 00000000000..1557ff8246f --- /dev/null +++ b/idea/testData/completion/smart/ConstructorForJavaClass.kt @@ -0,0 +1,5 @@ +import java.util.Date + +var a : Date = + +// EXIST: { lookupString:"Date", itemText:"Date()" } diff --git a/idea/testData/completion/smart/ConstructorForJavaClass.kt.todo b/idea/testData/completion/smart/ConstructorForJavaClass.kt.todo deleted file mode 100644 index 5e6b161db2e..00000000000 --- a/idea/testData/completion/smart/ConstructorForJavaClass.kt.todo +++ /dev/null @@ -1,5 +0,0 @@ -import java.util.Date - -var a : Date = - -// EXIST: Date@Date() diff --git a/idea/testData/completion/smart/InaccessibleConstructor.kt b/idea/testData/completion/smart/InaccessibleConstructor.kt new file mode 100644 index 00000000000..a6f771574c4 --- /dev/null +++ b/idea/testData/completion/smart/InaccessibleConstructor.kt @@ -0,0 +1,5 @@ +class Foo protected() + +var a : Foo = + +// ABSENT: Foo diff --git a/idea/testData/completion/smart/PrivateConstructorForAbstract.kt b/idea/testData/completion/smart/PrivateConstructorForAbstract.kt new file mode 100644 index 00000000000..27db7f5cb4e --- /dev/null +++ b/idea/testData/completion/smart/PrivateConstructorForAbstract.kt @@ -0,0 +1,6 @@ +abstract class Foo private() + +var a : Foo = + +// ABSENT: Foo +// ABSENT: object diff --git a/idea/testData/completion/smart/ProtectedConstructorForAbstract.kt b/idea/testData/completion/smart/ProtectedConstructorForAbstract.kt new file mode 100644 index 00000000000..00d9ad94c59 --- /dev/null +++ b/idea/testData/completion/smart/ProtectedConstructorForAbstract.kt @@ -0,0 +1,6 @@ +abstract class Foo protected() + +var a : Foo = + +// ABSENT: Foo +// EXIST: { lookupString:"object", itemText:"object: Foo(){...}" } diff --git a/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java index 738cea2c631..7fa201c668a 100644 --- a/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java @@ -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"); diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java index 9ad93b3b333..4afa1e6bd01 100644 --- a/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java @@ -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"); + } + }