Minor refactoring in keyword completion

This commit is contained in:
Valentin Kipyatkov
2014-10-15 13:09:28 +04:00
parent 96a5e573c3
commit 6dc17e5a03
@@ -19,7 +19,6 @@ package org.jetbrains.jet.plugin.completion
import com.intellij.psi.filters.* import com.intellij.psi.filters.*
import com.intellij.psi.filters.position.LeftNeighbour import com.intellij.psi.filters.position.LeftNeighbour
import org.jetbrains.jet.lang.psi.* import org.jetbrains.jet.lang.psi.*
import org.jetbrains.jet.lexer.JetTokens
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.filters.position.PositionElementFilter import com.intellij.psi.filters.position.PositionElementFilter
import com.intellij.codeInsight.completion.* import com.intellij.codeInsight.completion.*
@@ -35,15 +34,17 @@ import org.jetbrains.jet.lang.psi.psiUtil.siblings
import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.PsiComment import com.intellij.psi.PsiComment
import org.jetbrains.jet.lexer.JetTokens.*
class KeywordLookupObject(val keyword: String) class KeywordLookupObject(val keyword: String)
object KeywordCompletion { object KeywordCompletion {
private val NON_ACTUAL_KEYWORDS = setOf(JetTokens.REIFIED_KEYWORD.getValue(), private val NON_ACTUAL_KEYWORDS = setOf(REIFIED_KEYWORD,
JetTokens.CAPITALIZED_THIS_KEYWORD.getValue(), CAPITALIZED_THIS_KEYWORD,
JetTokens.TYPE_ALIAS_KEYWORD.getValue()) TYPE_ALIAS_KEYWORD)
private val ALL_KEYWORDS = (JetTokens.KEYWORDS.getTypes() + JetTokens.SOFT_KEYWORDS.getTypes()) private val ALL_KEYWORDS = (KEYWORDS.getTypes() + SOFT_KEYWORDS.getTypes())
.map { (it as JetKeywordToken).getValue() }
.filter { it !in NON_ACTUAL_KEYWORDS } .filter { it !in NON_ACTUAL_KEYWORDS }
.map { it as JetKeywordToken }
public fun complete(parameters: CompletionParameters, prefixMatcher: PrefixMatcher, collector: LookupElementsCollector) { public fun complete(parameters: CompletionParameters, prefixMatcher: PrefixMatcher, collector: LookupElementsCollector) {
val position = parameters.getPosition() val position = parameters.getPosition()
@@ -51,11 +52,12 @@ object KeywordCompletion {
if (!GENERAL_FILTER.isAcceptable(position, position)) return if (!GENERAL_FILTER.isAcceptable(position, position)) return
val parserFilter = buildFilter(position) val parserFilter = buildFilter(position)
for (keyword in ALL_KEYWORDS) { for (keywordToken in ALL_KEYWORDS) {
if (prefixMatcher.prefixMatches(keyword) && parserFilter(keyword)) { val keyword = keywordToken.getValue()
if (prefixMatcher.prefixMatches(keyword) && parserFilter(keywordToken)) {
val element = LookupElementBuilder.create(KeywordLookupObject(keyword), keyword) val element = LookupElementBuilder.create(KeywordLookupObject(keyword), keyword)
.bold() .bold()
.withInsertHandler(if (keyword !in FUNCTION_KEYWORDS) .withInsertHandler(if (keywordToken !in FUNCTION_KEYWORDS)
KotlinKeywordInsertHandler KotlinKeywordInsertHandler
else else
JetFunctionInsertHandler.NO_PARAMETERS_HANDLER) JetFunctionInsertHandler.NO_PARAMETERS_HANDLER)
@@ -64,7 +66,7 @@ object KeywordCompletion {
} }
} }
private val FUNCTION_KEYWORDS = listOf(JetTokens.GET_KEYWORD.toString(), JetTokens.SET_KEYWORD.toString()) private val FUNCTION_KEYWORDS = listOf(GET_KEYWORD, SET_KEYWORD)
private val GENERAL_FILTER = NotFilter(OrFilter( private val GENERAL_FILTER = NotFilter(OrFilter(
CommentFilter(), CommentFilter(),
@@ -93,7 +95,7 @@ object KeywordCompletion {
} }
} }
private fun buildFilter(position: PsiElement): (String) -> Boolean { private fun buildFilter(position: PsiElement): (JetKeywordToken) -> Boolean {
var parent = position.getParent() var parent = position.getParent()
var prevParent = position var prevParent = position
while (parent != null) { while (parent != null) {
@@ -135,7 +137,7 @@ object KeywordCompletion {
private fun buildFilterWithContext(prefixText: String, private fun buildFilterWithContext(prefixText: String,
contextElement: PsiElement, contextElement: PsiElement,
position: PsiElement): (String) -> Boolean { position: PsiElement): (JetKeywordToken) -> Boolean {
val offset = position.getStartOffsetInAncestor(contextElement) val offset = position.getStartOffsetInAncestor(contextElement)
val truncatedContext = contextElement.getText()!!.substring(0, offset) val truncatedContext = contextElement.getText()!!.substring(0, offset)
return buildFilterByText(prefixText + truncatedContext, contextElement.getProject()) return buildFilterByText(prefixText + truncatedContext, contextElement.getProject())
@@ -143,21 +145,21 @@ object KeywordCompletion {
private fun buildFilterWithReducedContext(prefixText: String, private fun buildFilterWithReducedContext(prefixText: String,
contextElement: PsiElement?, contextElement: PsiElement?,
position: PsiElement): (String) -> Boolean { position: PsiElement): (JetKeywordToken) -> Boolean {
val builder = StringBuilder() val builder = StringBuilder()
buildReducedContextBefore(builder, position, contextElement) buildReducedContextBefore(builder, position, contextElement)
return buildFilterByText(prefixText + builder.toString(), position.getProject()) return buildFilterByText(prefixText + builder.toString(), position.getProject())
} }
private fun buildFilterByText(prefixText: String, project: Project): (String) -> Boolean { private fun buildFilterByText(prefixText: String, project: Project): (JetKeywordToken) -> Boolean {
val psiFactory = JetPsiFactory(project) val psiFactory = JetPsiFactory(project)
return { keyword -> return { keywordTokenType ->
val file = psiFactory.createFile(prefixText + keyword) val file = psiFactory.createFile(prefixText + keywordTokenType.getValue())
val elementAt = file.findElementAt(prefixText.length)!! val elementAt = file.findElementAt(prefixText.length)!!
val nodeType = elementAt.getNode()!!.getElementType() val nodeType = elementAt.getNode()!!.getElementType()
when { when {
nodeType !in JetTokens.KEYWORDS && nodeType !in JetTokens.SOFT_KEYWORDS -> false nodeType != keywordTokenType -> false
elementAt.getParentByType(javaClass<PsiErrorElement>(), strict = false) != null -> false elementAt.getParentByType(javaClass<PsiErrorElement>(), strict = false) != null -> false