From 7905d32c14b8701ce522e71ccf73c92b8e7620d7 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Wed, 23 Apr 2014 17:58:46 +0400 Subject: [PATCH] Smart completion: static members insertion reworked to support single lambda parameter, more correct reference shortening in range --- .../plugin/codeInsight/ShortenReferences.kt | 19 ++++++++++----- .../plugin/completion/smart/StaticMembers.kt | 23 +++++-------------- .../handlers/smart/ClassObjectMethod3.kt | 13 +++++++++++ .../smart/ClassObjectMethod3.kt.after | 13 +++++++++++ .../handlers/smart/ClassObjectMethod4.kt | 13 +++++++++++ .../smart/ClassObjectMethod4.kt.after | 13 +++++++++++ .../JvmBasicCompletionTestGenerated.java | 7 ++++-- .../SmartCompletionHandlerTestGenerated.java | 20 ++++++++++++++-- .../shortenRefs/AbstractShortenRefsTest.kt | 9 ++++---- 9 files changed, 98 insertions(+), 32 deletions(-) create mode 100644 idea/testData/completion/handlers/smart/ClassObjectMethod3.kt create mode 100644 idea/testData/completion/handlers/smart/ClassObjectMethod3.kt.after create mode 100644 idea/testData/completion/handlers/smart/ClassObjectMethod4.kt create mode 100644 idea/testData/completion/handlers/smart/ClassObjectMethod4.kt.after diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ShortenReferences.kt b/idea/src/org/jetbrains/jet/plugin/codeInsight/ShortenReferences.kt index 6b70a2265b5..430166bff21 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ShortenReferences.kt +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/ShortenReferences.kt @@ -18,6 +18,7 @@ import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyPackageFragmentF import org.jetbrains.jet.lang.resolve.java.descriptor.JavaMethodDescriptor import com.intellij.openapi.util.TextRange import com.intellij.psi.SmartPointerManager +import com.intellij.psi.PsiDocumentManager import org.jetbrains.jet.plugin.caches.resolve.getLazyResolveSession public object ShortenReferences { @@ -30,13 +31,19 @@ public object ShortenReferences { } public fun process(file: JetFile, startOffset: Int, endOffset: Int) { - val smartPointerManager = SmartPointerManager.getInstance(file.getProject()) - val pointer = smartPointerManager.createSmartPsiFileRangePointer(file, TextRange(startOffset, endOffset)) + val documentManager = PsiDocumentManager.getInstance(file.getProject()) + val document = documentManager.getDocument(file)!! + if (!documentManager.isCommitted(document)) { + throw IllegalStateException("Document should be committed to shorten references in range") + } + + val rangeMarker = document.createRangeMarker(startOffset, endOffset) + rangeMarker.setGreedyToLeft(true) + rangeMarker.setGreedyToRight(true) try { process(listOf(file), { element -> - val segment = pointer.getRange() - if (segment != null) { - val range = TextRange(segment.getStartOffset(), segment.getEndOffset()) + if (rangeMarker.isValid()) { + val range = TextRange(rangeMarker.getStartOffset(), rangeMarker.getEndOffset()) val elementRange = element.getTextRange()!! when { range.contains(elementRange) -> FilterResult.PROCESS @@ -50,7 +57,7 @@ public object ShortenReferences { }) } finally { - smartPointerManager.removePointer(pointer) + rangeMarker.dispose() } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/StaticMembers.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/StaticMembers.kt index 4366a75d228..5c1a41b7cfb 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/smart/StaticMembers.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/StaticMembers.kt @@ -93,14 +93,6 @@ class StaticMembers(val bindingContext: BindingContext, val resolveSession: Reso val lookupString = qualifierPresentation + "." + lookupElement.getLookupString() val qualifierText = DescriptorUtils.getFqName(classDescriptor).asString() //TODO: escape keywords - val caretPosition: CaretPosition? - if (memberDescriptor is FunctionDescriptor) { - caretPosition = if (memberDescriptor.getValueParameters().empty) CaretPosition.AFTER_BRACKETS else CaretPosition.IN_BRACKETS - } - else { - caretPosition = null - } - return object: LookupElementDecorator(lookupElement) { override fun getLookupString() = lookupString @@ -123,19 +115,16 @@ class StaticMembers(val bindingContext: BindingContext, val resolveSession: Reso } override fun handleInsert(context: InsertionContext) { - val editor = context.getEditor() - val startOffset = context.getStartOffset() var text = qualifierText + "." + memberDescriptor.getName().asString() //TODO: escape + + context.getDocument().replaceString(context.getStartOffset(), context.getTailOffset(), text) + context.setTailOffset(context.getStartOffset() + text.length) + if (memberDescriptor is FunctionDescriptor) { - text += "()" - //TODO: auto-popup parameter info and other functionality from JetFunctionInsertHandler + getDelegate().handleInsert(context) } - editor.getDocument().replaceString(startOffset, context.getTailOffset(), text) - val endOffset = startOffset + text.length - editor.getCaretModel().moveToOffset(if (caretPosition == CaretPosition.IN_BRACKETS) endOffset - 1 else endOffset) - - shortenReferences(context, startOffset, startOffset + qualifierText.length) + shortenReferences(context, context.getStartOffset(), context.getTailOffset()) } } } diff --git a/idea/testData/completion/handlers/smart/ClassObjectMethod3.kt b/idea/testData/completion/handlers/smart/ClassObjectMethod3.kt new file mode 100644 index 00000000000..6d0e95a7202 --- /dev/null +++ b/idea/testData/completion/handlers/smart/ClassObjectMethod3.kt @@ -0,0 +1,13 @@ +package sample + +class K { + class object { + fun bar(p: () -> Unit): K = K() + } +} + +fun foo(){ + val k : K = +} + +// ELEMENT: K.bar diff --git a/idea/testData/completion/handlers/smart/ClassObjectMethod3.kt.after b/idea/testData/completion/handlers/smart/ClassObjectMethod3.kt.after new file mode 100644 index 00000000000..a6b5465fd9c --- /dev/null +++ b/idea/testData/completion/handlers/smart/ClassObjectMethod3.kt.after @@ -0,0 +1,13 @@ +package sample + +class K { + class object { + fun bar(p: () -> Unit): K = K() + } +} + +fun foo(){ + val k : K = K.bar { } +} + +// ELEMENT: K.bar diff --git a/idea/testData/completion/handlers/smart/ClassObjectMethod4.kt b/idea/testData/completion/handlers/smart/ClassObjectMethod4.kt new file mode 100644 index 00000000000..0618629c605 --- /dev/null +++ b/idea/testData/completion/handlers/smart/ClassObjectMethod4.kt @@ -0,0 +1,13 @@ +package sample + +class K { + class object { + fun bar(p: (Int, String) -> Unit): K = K() + } +} + +fun foo(){ + val k : K = +} + +// ELEMENT: K.bar diff --git a/idea/testData/completion/handlers/smart/ClassObjectMethod4.kt.after b/idea/testData/completion/handlers/smart/ClassObjectMethod4.kt.after new file mode 100644 index 00000000000..e2e05bffb7e --- /dev/null +++ b/idea/testData/completion/handlers/smart/ClassObjectMethod4.kt.after @@ -0,0 +1,13 @@ +package sample + +class K { + class object { + fun bar(p: (Int, String) -> Unit): K = K() + } +} + +fun foo(){ + val k : K = K.bar() +} + +// ELEMENT: K.bar diff --git a/idea/tests/org/jetbrains/jet/completion/JvmBasicCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JvmBasicCompletionTestGenerated.java index 7e00f03ed57..3e18e5dbc9b 100644 --- a/idea/tests/org/jetbrains/jet/completion/JvmBasicCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JvmBasicCompletionTestGenerated.java @@ -16,14 +16,17 @@ package org.jetbrains.jet.completion; +import junit.framework.Assert; import junit.framework.Test; import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.test.InnerTestClasses; import org.jetbrains.jet.test.TestMetadata; -import java.io.File; -import java.util.regex.Pattern; +import org.jetbrains.jet.completion.AbstractJvmBasicCompletionTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java index 6d60021175a..8ca7114b222 100644 --- a/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java @@ -16,11 +16,17 @@ package org.jetbrains.jet.completion.handlers; -import org.jetbrains.jet.JetTestUtils; -import org.jetbrains.jet.test.TestMetadata; +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; import java.io.File; import java.util.regex.Pattern; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.completion.handlers.AbstractSmartCompletionHandlerTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @@ -60,6 +66,16 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion doTest("idea/testData/completion/handlers/smart/ClassObjectMethod2.kt"); } + @TestMetadata("ClassObjectMethod3.kt") + public void testClassObjectMethod3() throws Exception { + doTest("idea/testData/completion/handlers/smart/ClassObjectMethod3.kt"); + } + + @TestMetadata("ClassObjectMethod4.kt") + public void testClassObjectMethod4() throws Exception { + doTest("idea/testData/completion/handlers/smart/ClassObjectMethod4.kt"); + } + @TestMetadata("ClosingParenthesis1.kt") public void testClosingParenthesis1() throws Exception { doTest("idea/testData/completion/handlers/smart/ClosingParenthesis1.kt"); diff --git a/idea/tests/org/jetbrains/jet/shortenRefs/AbstractShortenRefsTest.kt b/idea/tests/org/jetbrains/jet/shortenRefs/AbstractShortenRefsTest.kt index 90d0208cdf1..2b73fe81ba7 100644 --- a/idea/tests/org/jetbrains/jet/shortenRefs/AbstractShortenRefsTest.kt +++ b/idea/tests/org/jetbrains/jet/shortenRefs/AbstractShortenRefsTest.kt @@ -31,7 +31,7 @@ abstract class AbstractShortenRefsTest : LightCodeInsightFixtureTestCase() { override fun getProjectDescriptor() = JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE protected fun doTest(testPath: String) { - val fixture = myFixture!! + val fixture = myFixture val dependencyPath = testPath.replace(".kt", ".dependency.kt") if (File(dependencyPath).exists()) { fixture.configureByFile(dependencyPath) @@ -44,13 +44,12 @@ abstract class AbstractShortenRefsTest : LightCodeInsightFixtureTestCase() { fixture.configureByFile(testPath) val file = fixture.getFile() as JetFile - val selectionModel = fixture.getEditor()!!.getSelectionModel() + val selectionModel = fixture.getEditor().getSelectionModel() if (!selectionModel.hasSelection()) error("No selection in input file") - val element = PsiTreeUtil.findElementOfClassAtRange(file, selectionModel.getSelectionStart(), selectionModel.getSelectionEnd(), javaClass())!! - CommandProcessor.getInstance()!!.executeCommand(getProject(), { + CommandProcessor.getInstance().executeCommand(getProject(), { ApplicationManager.getApplication()!!.runWriteAction { - ShortenReferences.process(element) + ShortenReferences.process(file, selectionModel.getSelectionStart(), selectionModel.getSelectionEnd()) } }, null, null) selectionModel.removeSelection()