Skip to content

Commit

Permalink
Merge #4270
Browse files Browse the repository at this point in the history
4270: COMP: extend keyword completion r=Undin a=Undin

Also, make minor refactoring of function completion

Co-authored-by: Arseniy Pendryak <a.pendryak@yandex.ru>
  • Loading branch information
bors[bot] and Undin committed Aug 16, 2019
2 parents ea7fa0b + 6573aa2 commit 3e38c84
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -209,15 +209,11 @@ open class RsDefaultInsertHandler : InsertHandler<LookupElement> {
if (curUseItem != null) {
appendSemicolon(context, curUseItem)
} else {
val isMethodCall = context.getElementOfType<RsMethodOrField>() != null
if (!context.alreadyHasCallParens) {
document.insertString(context.selectionEndOffset, "()")
}

val charsSequence = document.charsSequence
val inUFCS = element.hasSelfParameters
&& charsSequence.getOrNull(startOffset - 1) == ':'
&& charsSequence.getOrNull(startOffset - 2) == ':'
val caretShift = if (element.valueParameters.isEmpty() && !inUFCS) 2 else 1
val caretShift = if (element.valueParameters.isEmpty() && (isMethodCall || !element.hasSelfParameters)) 2 else 1
EditorModificationUtil.moveCaretRelatively(context.editor, caretShift)
if (!element.valueParameters.isEmpty()) {
AutoPopupController.getInstance(element.project)?.autoPopupParameterInfo(context.editor, element)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import org.rust.openapiext.Testmark
object RsCommonCompletionProvider : CompletionProvider<CompletionParameters>() {
override fun addCompletions(
parameters: CompletionParameters,
_context: ProcessingContext,
processingContext: ProcessingContext,
result: CompletionResultSet
) {
// Use original position if possible to re-use caches of the real file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import com.intellij.patterns.PlatformPatterns.psiElement
import com.intellij.patterns.PsiElementPattern
import com.intellij.patterns.StandardPatterns.or
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiErrorElement
import com.intellij.psi.PsiWhiteSpace
import com.intellij.util.ProcessingContext
import org.rust.lang.core.*
Expand All @@ -27,7 +26,6 @@ import org.rust.lang.core.types.infer.lookupFutureOutputTy
import org.rust.lang.core.types.ty.Ty
import org.rust.lang.core.types.ty.TyUnknown
import org.rust.lang.core.types.type
import kotlin.or

/**
* Completes Rust keywords
Expand Down Expand Up @@ -56,7 +54,13 @@ class RsKeywordCompletionContributor : CompletionContributor(), DumbAware {
extend(CompletionType.BASIC, constParameterBeginningPattern(),
RsKeywordCompletionProvider("const"))
extend(CompletionType.BASIC, traitOrImplDeclarationPattern(),
RsKeywordCompletionProvider(*COMPLETION_KEYWORDS_IN_TRAIT_OR_IMPL))
RsKeywordCompletionProvider("const", "fn", "type", "unsafe"))
extend(CompletionType.BASIC, unsafeTraitOrImplDeclarationPattern(),
RsKeywordCompletionProvider("fn"))
extend(CompletionType.BASIC, inherentImplDeclarationPattern(),
RsKeywordCompletionProvider("pub"))
extend(CompletionType.BASIC, pubInherentImplDeclarationPattern(),
RsKeywordCompletionProvider("const", "fn", "type", "unsafe"))

extend(CompletionType.BASIC, elsePattern(), object : CompletionProvider<CompletionParameters>() {
override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) {
Expand Down Expand Up @@ -239,19 +243,42 @@ class RsKeywordCompletionContributor : CompletionContributor(), DumbAware {
return psiElement(IDENTIFIER).withParent(parent)
}

private fun baseTraitOrImplDeclaration(): PsiElementPattern.Capture<PsiElement> {
return psiElement().withParent(or(
psiElement<RsMembers>(),
psiElement().withParent(RsMembers::class.java)
))
}

private fun traitOrImplDeclarationPattern(): PsiElementPattern.Capture<PsiElement> {
return psiElement().withParent(
or(
psiElement<RsMembers>(),
psiElement<PsiErrorElement>().withParent(psiElement<RsMembers>())
)
).and(statementBeginningPattern())
return baseTraitOrImplDeclaration().and(statementBeginningPattern())
}

private fun unsafeTraitOrImplDeclarationPattern(): PsiElementPattern.Capture<PsiElement> {
return baseTraitOrImplDeclaration().and(statementBeginningPattern("unsafe"))
}

private fun baseInherentImplDeclarationPattern(): PsiElementPattern.Capture<PsiElement> {
val membersInInherentImpl = psiElement<RsMembers>().withParent(
psiElement<RsImplItem>().with("InherentImpl") { e -> e.traitRef == null }
)
return psiElement().withParent(or(
membersInInherentImpl,
psiElement().withParent(membersInInherentImpl)
))
}

private fun inherentImplDeclarationPattern(): PsiElementPattern.Capture<PsiElement> {
return baseInherentImplDeclarationPattern().and(statementBeginningPattern())
}

private fun pubInherentImplDeclarationPattern(): PsiElementPattern.Capture<PsiElement> {
return baseInherentImplDeclarationPattern().and(statementBeginningPattern("pub"))
}

companion object {
@JvmField
val CONDITION_KEYWORDS: List<String> = listOf("if", "match")
val COMPLETION_KEYWORDS_IN_TRAIT_OR_IMPL = arrayOf("const", "fn", "type")
private val AWAIT_TY: Key<Ty> = Key.create("AWAIT_TY")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ package org.rust.lang.core.completion
import org.intellij.lang.annotations.Language
import org.rust.MockEdition
import org.rust.cargo.project.workspace.CargoWorkspace
import org.rust.lang.core.completion.RsKeywordCompletionContributor.Companion.COMPLETION_KEYWORDS_IN_TRAIT_OR_IMPL
import org.rust.lang.core.completion.RsKeywordCompletionContributor.Companion.CONDITION_KEYWORDS

class RsKeywordCompletionContributorTest : RsCompletionTestBase() {
Expand Down Expand Up @@ -590,26 +589,26 @@ class RsKeywordCompletionContributorTest : RsCompletionTestBase() {
"fn foo<T /*caret*/>() {}"
""")

fun `test inside trait`() = checkCompletion(COMPLETION_KEYWORDS_IN_TRAIT_OR_IMPL.toList(), """
fun `test inside trait`() = checkCompletion(MEMBERS_KEYWORDS, """
pub trait Bar {
/*caret*/
const i: i32 = 1;
const C: i32 = 1;
}
""","""
pub trait Bar {
/*lookup*/ /*caret*/
const i: i32 = 1;
const C: i32 = 1;
}
""")

fun `test inside trait after statement`() = checkCompletion(COMPLETION_KEYWORDS_IN_TRAIT_OR_IMPL.toList(), """
fun `test inside trait after statement`() = checkCompletion(MEMBERS_KEYWORDS, """
pub trait Bar {
const i: i32 = 1;
const C: i32 = 1;
/*caret*/
}
""","""
pub trait Bar {
const i: i32 = 1;
const C: i32 = 1;
/*lookup*/ /*caret*/
}
""")
Expand All @@ -626,46 +625,78 @@ class RsKeywordCompletionContributorTest : RsCompletionTestBase() {
}
""")

fun `test inside impl`() = checkCompletion(COMPLETION_KEYWORDS_IN_TRAIT_OR_IMPL.toList(), """
struct Foo;
fun `test inside trait impl`() = checkCompletion(MEMBERS_KEYWORDS, """
impl Bar for Foo {
/*caret*/
const i: i32 = 1;
const C: i32 = 1;
}
""","""
struct Foo;
impl Bar for Foo {
/*lookup*/ /*caret*/
const i: i32 = 1;
const C: i32 = 1;
}
""")

fun `test inside impl after statement`() = checkCompletion(COMPLETION_KEYWORDS_IN_TRAIT_OR_IMPL.toList(), """
struct Foo;
fun `test inside impl after statement`() = checkCompletion(MEMBERS_KEYWORDS, """
impl Bar for Foo {
const i: i32 = 1;
const C: i32 = 1;
/*caret*/
}
""","""
struct Foo;
impl Bar for Foo {
const i: i32 = 1;
const C: i32 = 1;
/*lookup*/ /*caret*/
}
""")

fun `test impl inside impl`() = checkNoCompletion("""
struct Foo;
impl Bar for Foo {
imp/*caret*/
}
""")

fun `test unsafe fn in impl`() = checkCompletion("fn", """
impl Foo {
unsafe f/*caret*/
}
""", """
impl Foo {
unsafe fn /*caret*/
}
""")

fun `test pub member keyword in inherent impl`() = checkCompletion(MEMBERS_KEYWORDS, """
impl Foo {
pub /*caret*/
}
""", """
impl Foo {
pub /*lookup*/ /*caret*/
}
""")

fun `test pub keyword in inherent impl`() = checkCompletion("pub", """
impl Foo {
pu/*caret*/
}
""", """
impl Foo {
pub /*caret*/
}
""")

fun `test no pub keyword in trait`() = checkNoCompletion("""
trait Foo {
pu/*caret*/
}
""")

fun `test no pub keyword in trait impl`() = checkNoCompletion("""
impl Foo for Bar {
pu/*caret*/
}
""")

private fun checkCompletion(
lookupStrings: List<String>,
@Language("Rust") before: String,
Expand All @@ -687,4 +718,8 @@ class RsKeywordCompletionContributorTest : RsCompletionTestBase() {
myFixture.lookup.currentItem = lookupItem
myFixture.type('\n')
}

companion object {
private val MEMBERS_KEYWORDS = listOf("fn", "type", "const", "unsafe")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,6 @@ class RsMacroCallBodyCompletionTest : RsCompletionTestBase() {
}
struct Foo;
impl Foo { fn bar(&self) {} }
foo!(Foo, bar()/*caret*/);
foo!(Foo, bar(/*caret*/));
""")
}

0 comments on commit 3e38c84

Please sign in to comment.