diff --git a/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.java b/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.java index cf7a5a24a2e..ee189c6532f 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.java @@ -144,7 +144,7 @@ class CompletionSession { return isVisibleDescriptor(descriptor); } }; - SmartCompletion completion = new SmartCompletion(jetReference.getExpression(), getResolveSession(), visibilityFilter); + SmartCompletion completion = new SmartCompletion(jetReference.getExpression(), getResolveSession(), visibilityFilter, (JetFile)parameters.getOriginalFile()); Collection elements = completion.buildLookupElements(descriptors); if (elements != null) { for (LookupElement element : elements) { 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 cdee3d140be..8778b7d5aa4 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/smart/SmartCompletion.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/SmartCompletion.kt @@ -29,10 +29,13 @@ import org.jetbrains.jet.plugin.completion.* import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns import org.jetbrains.jet.plugin.util.makeNotNullable import org.jetbrains.jet.plugin.util.makeNullable +import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.jet.plugin.caches.resolve.getLazyResolveSession class SmartCompletion(val expression: JetSimpleNameExpression, val resolveSession: ResolveSessionForBodies, - val visibilityFilter: (DeclarationDescriptor) -> Boolean) { + val visibilityFilter: (DeclarationDescriptor) -> Boolean, + val originalFile: JetFile) { private val bindingContext = resolveSession.resolveToElement(expression) private val moduleDescriptor = resolveSession.getModuleDescriptor() @@ -73,7 +76,7 @@ class SmartCompletion(val expression: JetSimpleNameExpression, receiver = null } - val allExpectedInfos = ExpectedInfos(bindingContext, moduleDescriptor).calculate(expressionWithType) ?: return null + val allExpectedInfos = calcExpectedInfos(expressionWithType) ?: return null val filteredExpectedInfos = allExpectedInfos.filter { !it.`type`.isError() } if (filteredExpectedInfos.isEmpty()) return null @@ -125,6 +128,23 @@ class SmartCompletion(val expression: JetSimpleNameExpression, return result } + private fun calcExpectedInfos(expression: JetExpression): Collection? { + // if our expression is initializer of implicitly typed variable - take type of variable from original file + val varDeclaration = expression.getParent() as? JetVariableDeclaration + if (varDeclaration != null && expression == varDeclaration.getInitializer() && varDeclaration.getTypeRef() == null) { + val offset = varDeclaration.getTextRange()!!.getStartOffset() + val originalDeclaration = PsiTreeUtil.findElementOfClassAtOffset(originalFile, offset, javaClass(), true) + if (originalDeclaration != null) { + val variableDescriptor = originalDeclaration.getLazyResolveSession().resolveToDescriptor(originalDeclaration) as? VariableDescriptor + if (variableDescriptor != null) { + return listOf(ExpectedInfo(variableDescriptor.getType(), null)) + } + } + } + + return ExpectedInfos(bindingContext, moduleDescriptor).calculate(expression) + } + private fun calcItemsToSkip(expression: JetExpression): Set { val parent = expression.getParent() when(parent) { diff --git a/idea/testData/completion/smart/ImplicitlyTypedValInitializer1.kt b/idea/testData/completion/smart/ImplicitlyTypedValInitializer1.kt new file mode 100644 index 00000000000..8c400e44129 --- /dev/null +++ b/idea/testData/completion/smart/ImplicitlyTypedValInitializer1.kt @@ -0,0 +1,6 @@ +fun foo(p1: String, p2: Int) { + val v = "a" +} + +// EXIST: p1 +// ABSENT: p2 \ No newline at end of file diff --git a/idea/testData/completion/smart/ImplicitlyTypedValInitializer2.kt b/idea/testData/completion/smart/ImplicitlyTypedValInitializer2.kt new file mode 100644 index 00000000000..eb16eabfffe --- /dev/null +++ b/idea/testData/completion/smart/ImplicitlyTypedValInitializer2.kt @@ -0,0 +1,6 @@ +class A(s: String) { + val v = s.length() +} + +// EXIST: size +// ABSENT: substring \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java index 21b42b79137..bca734361e7 100644 --- a/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java @@ -231,6 +231,16 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT doTest("idea/testData/completion/smart/IfValueInBlock2.kt"); } + @TestMetadata("ImplicitlyTypedValInitializer1.kt") + public void testImplicitlyTypedValInitializer1() throws Exception { + doTest("idea/testData/completion/smart/ImplicitlyTypedValInitializer1.kt"); + } + + @TestMetadata("ImplicitlyTypedValInitializer2.kt") + public void testImplicitlyTypedValInitializer2() throws Exception { + doTest("idea/testData/completion/smart/ImplicitlyTypedValInitializer2.kt"); + } + @TestMetadata("InElvisOperator1.kt") public void testInElvisOperator1() throws Exception { doTest("idea/testData/completion/smart/InElvisOperator1.kt");