From e848fee7a1506ca7b04ec51fa555d3b46ead1e72 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Wed, 30 Jul 2014 20:37:17 +0400 Subject: [PATCH] Completion refactoring: got rid of JetExtensionReceiverTypeContributor --- idea/src/META-INF/plugin.xml | 7 +- .../completion/JetCompletionContributor.kt | 121 +++++++++--------- .../JetExtensionReceiverTypeContributor.kt | 48 ------- .../JetKeywordCompletionContributor.kt | 1 - .../completion/JetPackagesContributor.kt | 7 +- 5 files changed, 66 insertions(+), 118 deletions(-) delete mode 100644 idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.kt diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 55778994f44..643459d6fca 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -228,14 +228,9 @@ order="first" implementationClass="org.jetbrains.jet.plugin.completion.JetPackagesContributor"/> - - = PlatformPatterns.psiElement().afterLeaf(JetTokens.FUN_KEYWORD.toString(), JetTokens.VAL_KEYWORD.toString(), JetTokens.VAR_KEYWORD.toString()) + + ;{ val provider = object : CompletionProvider() { override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) { - doSimpleReferenceCompletion(parameters, result) + performCompletion(parameters, result) } } extend(CompletionType.BASIC, PlatformPatterns.psiElement(), provider) @@ -50,26 +57,21 @@ public class JetCompletionContributor : CompletionContributor() { val offset = context.getStartOffset() val tokenBefore = psiFile.findElementAt(Math.max(0, offset - 1)) - if (context.getCompletionType() == CompletionType.SMART) { - context.setDummyIdentifier(CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED + "$") // add '$' to ignore context after the caret - } - else { - if (JetPackagesContributor.ACTIVATION_PATTERN.accepts(tokenBefore)) { - context.setDummyIdentifier(JetPackagesContributor.DUMMY_IDENTIFIER) - } - else if (JetExtensionReceiverTypeContributor.ACTIVATION_PATTERN.accepts(tokenBefore)) { - context.setDummyIdentifier(JetExtensionReceiverTypeContributor.DUMMY_IDENTIFIER) - } - else { - context.setDummyIdentifier(CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED) - } + val dummyIdentifier = when { + context.getCompletionType() == CompletionType.SMART -> CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED + "$" // add '$' to ignore context after the caret + + JetPackagesContributor.ACTIVATION_PATTERN.accepts(tokenBefore) -> JetPackagesContributor.DUMMY_IDENTIFIER + + EXTENSION_RECEIVER_TYPE_ACTIVATION_PATTERN.accepts(tokenBefore) -> EXTENSION_RECEIVER_TYPE_DUMMY_IDENTIFIER + + else -> CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED } + context.setDummyIdentifier(dummyIdentifier) // this code will make replacement offset "modified" and prevents altering it by the code in CompletionProgressIndicator context.setReplacementOffset(context.getReplacementOffset()) if (context.getCompletionType() == CompletionType.SMART && !isAtEndOfLine(offset, context.getEditor().getDocument()) /* do not use parent expression if we are at the end of line - it's probably parsed incorrectly */) { - val tokenAt = psiFile.findElementAt(Math.max(0, offset)) if (tokenAt != null) { var parent = tokenAt.getParent() @@ -100,54 +102,55 @@ public class JetCompletionContributor : CompletionContributor() { } } - class object { - private val AFTER_NUMBER_LITERAL = psiElement().afterLeafSkipping(psiElement().withText(""), psiElement().withElementType(elementType().oneOf(JetTokens.FLOAT_LITERAL, JetTokens.INTEGER_LITERAL))) + private fun performCompletion(parameters: CompletionParameters, result: CompletionResultSet) { + val position = parameters.getPosition() + if (position.getContainingFile() !is JetFile) return - public fun doSimpleReferenceCompletion(parameters: CompletionParameters, result: CompletionResultSet) { - val position = parameters.getPosition() - if (position.getContainingFile() !is JetFile) return - - if (AFTER_NUMBER_LITERAL.accepts(parameters.getPosition())) { - // First Kotlin completion contributors - stop here will stop all completion - result.stopHere() - return - } - - val jetReference = getJetReference(parameters) - if (jetReference != null) { - try { - result.restartCompletionWhenNothingMatches() - - if (parameters.getCompletionType() == CompletionType.BASIC) { - val somethingAdded = BasicCompletionSession(parameters, result, jetReference).complete() - if (!somethingAdded && parameters.getInvocationCount() < 2) { - // Rerun completion if nothing was found - BasicCompletionSession(parameters.withInvocationCount(2), result, jetReference).complete() - } - } - else { - SmartCompletionSession(parameters, result, jetReference).complete() - } - } - catch (e: ProcessCanceledException) { - throw rethrowWithCancelIndicator(e) - } - } + if (AFTER_NUMBER_LITERAL.accepts(parameters.getPosition())) { + // First Kotlin completion contributors - stop here will stop all completion + result.stopHere() + return } - private fun getJetReference(parameters: CompletionParameters): JetSimpleNameReference? - = parameters.getPosition().getParent()?.getReferences()?.filterIsInstance(javaClass())?.firstOrNull() + if (EXTENSION_RECEIVER_TYPE_ACTIVATION_PATTERN.accepts(position) && parameters.getInvocationCount() == 0) { + result.stopHere() + return + } - private fun isAtEndOfLine(offset: Int, document: Document): Boolean { - var i = offset - val chars = document.getCharsSequence() - while (i < chars.length()) { - val c = chars.charAt(i) - if (c == '\n' || c == 'r') return true - if (!Character.isWhitespace(c)) return false - i++ + val jetReference = getJetReference(parameters) + if (jetReference != null) { + try { + result.restartCompletionWhenNothingMatches() + + if (parameters.getCompletionType() == CompletionType.BASIC) { + val somethingAdded = BasicCompletionSession(parameters, result, jetReference).complete() + if (!somethingAdded && parameters.getInvocationCount() < 2) { + // Rerun completion if nothing was found + BasicCompletionSession(parameters.withInvocationCount(2), result, jetReference).complete() + } + } + else { + SmartCompletionSession(parameters, result, jetReference).complete() + } + } + catch (e: ProcessCanceledException) { + throw rethrowWithCancelIndicator(e) } - return true } } + + private fun getJetReference(parameters: CompletionParameters): JetSimpleNameReference? + = parameters.getPosition().getParent()?.getReferences()?.filterIsInstance(javaClass())?.firstOrNull() + + private fun isAtEndOfLine(offset: Int, document: Document): Boolean { + var i = offset + val chars = document.getCharsSequence() + while (i < chars.length()) { + val c = chars.charAt(i) + if (c == '\n' || c == 'r') return true + if (!Character.isWhitespace(c)) return false + i++ + } + return true + } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.kt b/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.kt deleted file mode 100644 index 12544d6ec23..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2010-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.completion - -import com.intellij.codeInsight.completion.* -import com.intellij.patterns.PlatformPatterns -import com.intellij.util.ProcessingContext -import org.jetbrains.jet.lexer.JetTokens -import com.intellij.psi.PsiElement -import com.intellij.patterns.PsiElementPattern - -/** - * Special contributor for getting completion of type for extensions receiver. - */ -public class JetExtensionReceiverTypeContributor : CompletionContributor() { - class object { - // A way to add reference into file at completion place - public val DUMMY_IDENTIFIER: String = "KotlinExtensionDummy.fake() {}" - - public val ACTIVATION_PATTERN: PsiElementPattern.Capture = PlatformPatterns.psiElement().afterLeaf(JetTokens.FUN_KEYWORD.toString(), JetTokens.VAL_KEYWORD.toString(), JetTokens.VAR_KEYWORD.toString()) - } - - { - extend(CompletionType.BASIC, ACTIVATION_PATTERN, object : CompletionProvider() { - override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) { - if (parameters.getInvocationCount() > 0) { - JetCompletionContributor.doSimpleReferenceCompletion(parameters, result) - } - - result.stopHere() - } - }) - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.kt b/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.kt index 10bae369bc1..4775a20d6e6 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.kt @@ -150,7 +150,6 @@ public class JetKeywordCompletionContributor : CompletionContributor() { CommentFilter(), ParentFilter(ClassFilter(javaClass())), ParentFilter(ClassFilter(javaClass())), - PatternFilter(JetExtensionReceiverTypeContributor.ACTIVATION_PATTERN), LeftNeighbour(TextFilter(".")) )) diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.kt b/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.kt index 21b06fce5b6..d17a5cd5c0b 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.kt @@ -36,19 +36,18 @@ public class JetPackagesContributor : CompletionContributor() { class object { val DUMMY_IDENTIFIER = "___package___" - val ACTIVATION_PATTERN: ElementPattern = PlatformPatterns.psiElement().inside(javaClass()) + val ACTIVATION_PATTERN = PlatformPatterns.psiElement().inside(javaClass()) } { extend(CompletionType.BASIC, ACTIVATION_PATTERN, object : CompletionProvider() { override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) { - val file = parameters.getPosition().getContainingFile() - if (file !is JetFile) return + val file = parameters.getPosition().getContainingFile() as JetFile val ref = file.findReferenceAt(parameters.getOffset()) if (ref is JetSimpleNameReference) { - val name = ref.expression.getText() ?: return + val name = ref.expression.getText()!! try { val prefixLength = parameters.getOffset() - ref.expression.getTextOffset()