Completion refactoring: got rid of JetExtensionReceiverTypeContributor
This commit is contained in:
@@ -228,14 +228,9 @@
|
|||||||
order="first"
|
order="first"
|
||||||
implementationClass="org.jetbrains.jet.plugin.completion.JetPackagesContributor"/>
|
implementationClass="org.jetbrains.jet.plugin.completion.JetPackagesContributor"/>
|
||||||
|
|
||||||
<completion.contributor language="jet"
|
|
||||||
id="JetExtensionFunctionReceiverContributor"
|
|
||||||
order="after JetPackagesContributor"
|
|
||||||
implementationClass="org.jetbrains.jet.plugin.completion.JetExtensionReceiverTypeContributor"/>
|
|
||||||
|
|
||||||
<completion.contributor language="jet"
|
<completion.contributor language="jet"
|
||||||
id="JetCompletionContributor"
|
id="JetCompletionContributor"
|
||||||
order="after JetExtensionFunctionReceiverContributor"
|
order="after JetPackagesContributor"
|
||||||
implementationClass="org.jetbrains.jet.plugin.completion.JetCompletionContributor"/>
|
implementationClass="org.jetbrains.jet.plugin.completion.JetCompletionContributor"/>
|
||||||
|
|
||||||
<completion.contributor language="jet"
|
<completion.contributor language="jet"
|
||||||
|
|||||||
@@ -31,13 +31,20 @@ import org.jetbrains.jet.plugin.references.JetSimpleNameReference
|
|||||||
|
|
||||||
import com.intellij.patterns.PsiJavaPatterns.elementType
|
import com.intellij.patterns.PsiJavaPatterns.elementType
|
||||||
import com.intellij.patterns.PsiJavaPatterns.psiElement
|
import com.intellij.patterns.PsiJavaPatterns.psiElement
|
||||||
|
import com.intellij.patterns.PsiElementPattern
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
|
||||||
public class JetCompletionContributor : CompletionContributor() {
|
public class JetCompletionContributor : CompletionContributor() {
|
||||||
|
|
||||||
{
|
private val AFTER_NUMBER_LITERAL = psiElement().afterLeafSkipping(psiElement().withText(""), psiElement().withElementType(elementType().oneOf(JetTokens.FLOAT_LITERAL, JetTokens.INTEGER_LITERAL)))
|
||||||
|
|
||||||
|
private val EXTENSION_RECEIVER_TYPE_DUMMY_IDENTIFIER: String = "KotlinExtensionDummy.fake() {}" // A way to add reference into file at completion place
|
||||||
|
private val EXTENSION_RECEIVER_TYPE_ACTIVATION_PATTERN: PsiElementPattern.Capture<PsiElement> = PlatformPatterns.psiElement().afterLeaf(JetTokens.FUN_KEYWORD.toString(), JetTokens.VAL_KEYWORD.toString(), JetTokens.VAR_KEYWORD.toString())
|
||||||
|
|
||||||
|
;{
|
||||||
val provider = object : CompletionProvider<CompletionParameters>() {
|
val provider = object : CompletionProvider<CompletionParameters>() {
|
||||||
override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) {
|
override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) {
|
||||||
doSimpleReferenceCompletion(parameters, result)
|
performCompletion(parameters, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extend(CompletionType.BASIC, PlatformPatterns.psiElement(), provider)
|
extend(CompletionType.BASIC, PlatformPatterns.psiElement(), provider)
|
||||||
@@ -50,26 +57,21 @@ public class JetCompletionContributor : CompletionContributor() {
|
|||||||
|
|
||||||
val offset = context.getStartOffset()
|
val offset = context.getStartOffset()
|
||||||
val tokenBefore = psiFile.findElementAt(Math.max(0, offset - 1))
|
val tokenBefore = psiFile.findElementAt(Math.max(0, offset - 1))
|
||||||
if (context.getCompletionType() == CompletionType.SMART) {
|
val dummyIdentifier = when {
|
||||||
context.setDummyIdentifier(CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED + "$") // add '$' to ignore context after the caret
|
context.getCompletionType() == CompletionType.SMART -> CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED + "$" // add '$' to ignore context after the caret
|
||||||
}
|
|
||||||
else {
|
JetPackagesContributor.ACTIVATION_PATTERN.accepts(tokenBefore) -> JetPackagesContributor.DUMMY_IDENTIFIER
|
||||||
if (JetPackagesContributor.ACTIVATION_PATTERN.accepts(tokenBefore)) {
|
|
||||||
context.setDummyIdentifier(JetPackagesContributor.DUMMY_IDENTIFIER)
|
EXTENSION_RECEIVER_TYPE_ACTIVATION_PATTERN.accepts(tokenBefore) -> EXTENSION_RECEIVER_TYPE_DUMMY_IDENTIFIER
|
||||||
}
|
|
||||||
else if (JetExtensionReceiverTypeContributor.ACTIVATION_PATTERN.accepts(tokenBefore)) {
|
else -> CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED
|
||||||
context.setDummyIdentifier(JetExtensionReceiverTypeContributor.DUMMY_IDENTIFIER)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
context.setDummyIdentifier(CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
context.setDummyIdentifier(dummyIdentifier)
|
||||||
|
|
||||||
// this code will make replacement offset "modified" and prevents altering it by the code in CompletionProgressIndicator
|
// this code will make replacement offset "modified" and prevents altering it by the code in CompletionProgressIndicator
|
||||||
context.setReplacementOffset(context.getReplacementOffset())
|
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 */) {
|
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))
|
val tokenAt = psiFile.findElementAt(Math.max(0, offset))
|
||||||
if (tokenAt != null) {
|
if (tokenAt != null) {
|
||||||
var parent = tokenAt.getParent()
|
var parent = tokenAt.getParent()
|
||||||
@@ -100,54 +102,55 @@ public class JetCompletionContributor : CompletionContributor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class object {
|
private fun performCompletion(parameters: CompletionParameters, result: CompletionResultSet) {
|
||||||
private val AFTER_NUMBER_LITERAL = psiElement().afterLeafSkipping(psiElement().withText(""), psiElement().withElementType(elementType().oneOf(JetTokens.FLOAT_LITERAL, JetTokens.INTEGER_LITERAL)))
|
val position = parameters.getPosition()
|
||||||
|
if (position.getContainingFile() !is JetFile) return
|
||||||
|
|
||||||
public fun doSimpleReferenceCompletion(parameters: CompletionParameters, result: CompletionResultSet) {
|
if (AFTER_NUMBER_LITERAL.accepts(parameters.getPosition())) {
|
||||||
val position = parameters.getPosition()
|
// First Kotlin completion contributors - stop here will stop all completion
|
||||||
if (position.getContainingFile() !is JetFile) return
|
result.stopHere()
|
||||||
|
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getJetReference(parameters: CompletionParameters): JetSimpleNameReference?
|
if (EXTENSION_RECEIVER_TYPE_ACTIVATION_PATTERN.accepts(position) && parameters.getInvocationCount() == 0) {
|
||||||
= parameters.getPosition().getParent()?.getReferences()?.filterIsInstance(javaClass<JetSimpleNameReference>())?.firstOrNull()
|
result.stopHere()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
private fun isAtEndOfLine(offset: Int, document: Document): Boolean {
|
val jetReference = getJetReference(parameters)
|
||||||
var i = offset
|
if (jetReference != null) {
|
||||||
val chars = document.getCharsSequence()
|
try {
|
||||||
while (i < chars.length()) {
|
result.restartCompletionWhenNothingMatches()
|
||||||
val c = chars.charAt(i)
|
|
||||||
if (c == '\n' || c == 'r') return true
|
if (parameters.getCompletionType() == CompletionType.BASIC) {
|
||||||
if (!Character.isWhitespace(c)) return false
|
val somethingAdded = BasicCompletionSession(parameters, result, jetReference).complete()
|
||||||
i++
|
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<JetSimpleNameReference>())?.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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<PsiElement> = PlatformPatterns.psiElement().afterLeaf(JetTokens.FUN_KEYWORD.toString(), JetTokens.VAL_KEYWORD.toString(), JetTokens.VAR_KEYWORD.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
extend(CompletionType.BASIC, ACTIVATION_PATTERN, object : CompletionProvider<CompletionParameters>() {
|
|
||||||
override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) {
|
|
||||||
if (parameters.getInvocationCount() > 0) {
|
|
||||||
JetCompletionContributor.doSimpleReferenceCompletion(parameters, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
result.stopHere()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -150,7 +150,6 @@ public class JetKeywordCompletionContributor : CompletionContributor() {
|
|||||||
CommentFilter(),
|
CommentFilter(),
|
||||||
ParentFilter(ClassFilter(javaClass<JetLiteralStringTemplateEntry>())),
|
ParentFilter(ClassFilter(javaClass<JetLiteralStringTemplateEntry>())),
|
||||||
ParentFilter(ClassFilter(javaClass<JetConstantExpression>())),
|
ParentFilter(ClassFilter(javaClass<JetConstantExpression>())),
|
||||||
PatternFilter(JetExtensionReceiverTypeContributor.ACTIVATION_PATTERN),
|
|
||||||
LeftNeighbour(TextFilter("."))
|
LeftNeighbour(TextFilter("."))
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|||||||
@@ -36,19 +36,18 @@ public class JetPackagesContributor : CompletionContributor() {
|
|||||||
class object {
|
class object {
|
||||||
val DUMMY_IDENTIFIER = "___package___"
|
val DUMMY_IDENTIFIER = "___package___"
|
||||||
|
|
||||||
val ACTIVATION_PATTERN: ElementPattern<out PsiElement> = PlatformPatterns.psiElement().inside(javaClass<JetPackageDirective>())
|
val ACTIVATION_PATTERN = PlatformPatterns.psiElement().inside(javaClass<JetPackageDirective>())
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
extend(CompletionType.BASIC, ACTIVATION_PATTERN, object : CompletionProvider<CompletionParameters>() {
|
extend(CompletionType.BASIC, ACTIVATION_PATTERN, object : CompletionProvider<CompletionParameters>() {
|
||||||
override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) {
|
override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) {
|
||||||
val file = parameters.getPosition().getContainingFile()
|
val file = parameters.getPosition().getContainingFile() as JetFile
|
||||||
if (file !is JetFile) return
|
|
||||||
|
|
||||||
val ref = file.findReferenceAt(parameters.getOffset())
|
val ref = file.findReferenceAt(parameters.getOffset())
|
||||||
|
|
||||||
if (ref is JetSimpleNameReference) {
|
if (ref is JetSimpleNameReference) {
|
||||||
val name = ref.expression.getText() ?: return
|
val name = ref.expression.getText()!!
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val prefixLength = parameters.getOffset() - ref.expression.getTextOffset()
|
val prefixLength = parameters.getOffset() - ref.expression.getTextOffset()
|
||||||
|
|||||||
Reference in New Issue
Block a user