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 6e481905158..d1b7f4dbb72 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/smart/SmartCompletion.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/SmartCompletion.kt @@ -34,6 +34,7 @@ import org.jetbrains.jet.plugin.caches.resolve.getLazyResolveSession import org.jetbrains.jet.renderer.DescriptorRenderer import org.jetbrains.jet.lang.psi.psiUtil.getReceiverExpression import org.jetbrains.jet.plugin.util.IdeDescriptorRenderers +import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor class SmartCompletion(val expression: JetSimpleNameExpression, val resolveSession: ResolveSessionForBodies, @@ -106,7 +107,8 @@ class SmartCompletion(val expression: JetSimpleNameExpression, fun filterDeclaration(descriptor: DeclarationDescriptor): Collection { val result = ArrayList() - if (!itemsToSkip.contains(descriptor)) { + if (!itemsToSkip.contains(descriptor) + && descriptor !is SamConstructorDescriptor /* SAM-constructor is added explicitly and is not needed here */) { val types = typesWithSmartCasts(descriptor) val nonNullTypes = types.map { it.makeNotNullable() } val classifier = { (expectedInfo: ExpectedInfo) -> 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 aaf89dcb04f..6ad48ca08b4 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/smart/TypeInstantiationItems.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/TypeInstantiationItems.kt @@ -37,6 +37,8 @@ import org.jetbrains.jet.lang.descriptors.Visibilities import org.jetbrains.jet.plugin.util.makeNotNullable import org.jetbrains.jet.plugin.util.IdeDescriptorRenderers import org.jetbrains.jet.lang.resolve.BindingContext +import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor +import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor class TypeInstantiationItems(val resolveSession: ResolveSessionForBodies, val bindingContext: BindingContext, val visibilityFilter: (DeclarationDescriptor) -> Boolean) { public fun addToCollection(collection: MutableCollection, expectedInfos: Collection) { @@ -53,6 +55,8 @@ class TypeInstantiationItems(val resolveSession: ResolveSessionForBodies, val bi val classifier = jetType.getConstructor().getDeclarationDescriptor() if (classifier !is ClassDescriptor) return + addSamConstructorItem(collection, classifier, tail) + val isAbstract = classifier.getModality() == Modality.ABSTRACT val allConstructors = classifier.getConstructors() val visibleConstructors = allConstructors.filter { @@ -135,4 +139,22 @@ class TypeInstantiationItems(val resolveSession: ResolveSessionForBodies, val bi collection.add(lookupElement.addTail(tail)) } + + private fun addSamConstructorItem(collection: MutableCollection, `class`: ClassDescriptor, tail: Tail?) { + if (`class`.getKind() == ClassKind.TRAIT) { + val container = `class`.getContainingDeclaration() + val scope = when (container) { + is PackageFragmentDescriptor -> container.getMemberScope() + is ClassDescriptor -> container.getStaticScope() + else -> return + } + val samConstructor = scope.getFunctions(`class`.getName()) + .filterIsInstance(javaClass()) + .singleOrNull() ?: return + val lookupElement = createLookupElement(samConstructor, resolveSession, bindingContext) + .assignSmartCompletionPriority(SmartCompletionItemPriority.INSTANTIATION) + .addTail(tail) + collection.add(lookupElement) + } + } } diff --git a/idea/testData/completion/handlers/smart/SAMExpected2.kt b/idea/testData/completion/handlers/smart/SAMExpected2.kt new file mode 100644 index 00000000000..e32da4197f4 --- /dev/null +++ b/idea/testData/completion/handlers/smart/SAMExpected2.kt @@ -0,0 +1,3 @@ +var a : java.io.Closeable = + +// ELEMENT: Closeable diff --git a/idea/testData/completion/handlers/smart/SAMExpected2.kt.after b/idea/testData/completion/handlers/smart/SAMExpected2.kt.after new file mode 100644 index 00000000000..dd71e3fd3b0 --- /dev/null +++ b/idea/testData/completion/handlers/smart/SAMExpected2.kt.after @@ -0,0 +1,5 @@ +import java.io.Closeable + +var a : java.io.Closeable = Closeable { } + +// ELEMENT: Closeable diff --git a/idea/testData/completion/smart/FunctionReference6.kt b/idea/testData/completion/smart/FunctionReference6.kt.disabled similarity index 100% rename from idea/testData/completion/smart/FunctionReference6.kt rename to idea/testData/completion/smart/FunctionReference6.kt.disabled diff --git a/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java index 7545755fdf9..50b1a1826d4 100644 --- a/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java @@ -234,12 +234,6 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT doTest(fileName); } - @TestMetadata("FunctionReference6.kt") - public void testFunctionReference6() throws Exception { - String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smart/FunctionReference6.kt"); - doTest(fileName); - } - @TestMetadata("FunctionReference7.kt") public void testFunctionReference7() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smart/FunctionReference7.kt"); diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java index f136bb1df0f..609f9a902e3 100644 --- a/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java @@ -522,6 +522,12 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion doTest(fileName); } + @TestMetadata("SAMExpected2.kt") + public void testSAMExpected2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/handlers/smart/SAMExpected2.kt"); + doTest(fileName); + } + @TestMetadata("TabReplaceComma1.kt") public void testTabReplaceComma1() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/handlers/smart/TabReplaceComma1.kt");