diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/Utils.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/Utils.kt index f00efef0cc8..f6d155e70fe 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/Utils.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/Utils.kt @@ -34,12 +34,13 @@ import org.jetbrains.kotlin.idea.core.* import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.util.* import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.PossiblyBareType import org.jetbrains.kotlin.types.TypeSubstitutor import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver import org.jetbrains.kotlin.types.expressions.DoubleColonLHS +import org.jetbrains.kotlin.types.isDynamic import org.jetbrains.kotlin.types.typeUtil.TypeNullability import org.jetbrains.kotlin.types.typeUtil.isNothing +import org.jetbrains.kotlin.types.typeUtil.isNullableNothing import org.jetbrains.kotlin.util.descriptorsEqualWithSubstitution import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList import java.util.* @@ -300,8 +301,14 @@ fun DeclarationDescriptor.fuzzyTypesForSmartCompletion( if (this is CallableDescriptor) { val returnType = fuzzyReturnType() ?: return emptyList() - // skip declarations of type Nothing or of generic parameter type which has no real bounds - if (returnType.type.isNothing() || returnType.isAlmostEverything()) return emptyList() + + // skip declarations of types Nothing, Nothing?, dynamic or of generic parameter type which has no real bounds + if (returnType.type.isNothing() || + returnType.type.isNullableNothing() || + returnType.type.isDynamic() || + returnType.isAlmostEverything()) { + return emptyList() + } if (this is VariableDescriptor) { //TODO: generic properties! return smartCastCalculator.types(this).map { it.toFuzzyType(emptyList()) } diff --git a/idea/idea-completion/testData/basic/js/DoNotPreferDynamic.kt b/idea/idea-completion/testData/basic/js/DoNotPreferDynamic.kt new file mode 100644 index 00000000000..c42fbfc31d6 --- /dev/null +++ b/idea/idea-completion/testData/basic/js/DoNotPreferDynamic.kt @@ -0,0 +1,10 @@ +fun returnDynamic(): dynamic = TODO() +fun returnString(): String = "" +fun returnNothing(): Nothing? = TODO() + +val test: Any? = return + +// WITH_ORDER +// EXIST: returnString +// EXIST: returnDynamic +// EXIST: returnNothing diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java index ab91487bc91..c38608fe871 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java @@ -2683,6 +2683,12 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes doTest(fileName); } + @TestMetadata("DoNotPreferDynamic.kt") + public void testDoNotPreferDynamic() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/js/DoNotPreferDynamic.kt"); + doTest(fileName); + } + @TestMetadata("DynamicKeyword.kt") public void testDynamicKeyword() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/js/DynamicKeyword.kt");