Completely rewritten keyword completion implementation using another approach

#KT-2816 Fixed
This commit is contained in:
Valentin Kipyatkov
2014-10-08 22:28:04 +04:00
parent 6a4fe52e51
commit 549171d043
41 changed files with 528 additions and 582 deletions
@@ -350,4 +350,10 @@ public fun PsiElement.parents(withItself: Boolean = true): Stream<PsiElement> {
public fun JetExpression.getAssignmentByLHS(): JetBinaryExpression? {
val parent = getParent() as? JetBinaryExpression ?: return null
return if (JetPsiUtil.isAssignment(parent) && parent.getLeft() == this) parent else null
}
}
public fun PsiElement.prevLeaf(skipEmptyElements: Boolean = false): PsiElement?
= PsiTreeUtil.prevLeaf(this, skipEmptyElements)
public fun PsiElement.nextLeaf(skipEmptyElements: Boolean = false): PsiElement?
= PsiTreeUtil.nextLeaf(this, skipEmptyElements)
@@ -139,7 +139,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
}
}
KeywordCompletion().complete(parameters, collector)
KeywordCompletion.complete(parameters, prefixMatcher, collector)
if (completeReference && !shouldRunOnlyTypeCompletion()) {
flushToResultSet()
@@ -17,55 +17,52 @@
package org.jetbrains.jet.plugin.completion
import com.intellij.psi.filters.*
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.filters.position.LeftNeighbour
import org.jetbrains.jet.lang.psi.*
import org.jetbrains.jet.lexer.JetToken
import org.jetbrains.jet.lexer.JetTokens
import com.intellij.psi.filters.position.SuperParentFilter
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.PsiElement
import com.intellij.psi.filters.position.PositionElementFilter
import com.intellij.util.containers.MultiMap
import java.util.HashSet
import com.intellij.codeInsight.completion.*
import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler
import org.jetbrains.jet.plugin.completion.handlers.KotlinKeywordInsertHandler
import com.intellij.codeInsight.lookup.LookupElementBuilder
import java.util.ArrayList
import com.intellij.psi.PsiErrorElement
import org.jetbrains.jet.lexer.JetKeywordToken
import com.intellij.openapi.project.Project
import org.jetbrains.jet.lang.psi.psiUtil.getParentByType
import org.jetbrains.jet.lang.psi.psiUtil.prevLeaf
import org.jetbrains.jet.plugin.completion.handlers.KotlinKeywordInsertHandler
class KeywordLookupObject(val keyword: String)
//TODO: it should be object, it's class because of KT-5582
class KeywordCompletion {
public fun complete(parameters: CompletionParameters, collector: LookupElementsCollector) {
object KeywordCompletion {
private val NON_ACTUAL_KEYWORDS = setOf(JetTokens.REIFIED_KEYWORD.getValue(),
JetTokens.CAPITALIZED_THIS_KEYWORD.getValue(),
JetTokens.TYPE_ALIAS_KEYWORD.getValue())
private val ALL_KEYWORDS = (JetTokens.KEYWORDS.getTypes() + JetTokens.SOFT_KEYWORDS.getTypes())
.map { (it as JetKeywordToken).getValue() }
.filter { it !in NON_ACTUAL_KEYWORDS }
public fun complete(parameters: CompletionParameters, prefixMatcher: PrefixMatcher, collector: LookupElementsCollector) {
val position = parameters.getPosition()
if (!GENERAL_FILTER.isAcceptable(position, position)) return
for ((filter, keywords) in filterToKeyword) {
if (filter.isAcceptable(position, position)) {
for (keyword in keywords) {
val element = LookupElementBuilder.create(KeywordLookupObject(keyword), keyword)
.bold()
.withInsertHandler(if (keyword !in FUNCTION_KEYWORDS)
KotlinKeywordInsertHandler
else
JetFunctionInsertHandler.NO_PARAMETERS_HANDLER)
collector.addElement(element)
}
val parserFilter = buildParserFilter(position)
for (keyword in ALL_KEYWORDS) {
if (prefixMatcher.prefixMatches(keyword) && parserFilter(keyword)) {
val element = LookupElementBuilder.create(KeywordLookupObject(keyword), keyword)
.bold()
.withInsertHandler(if (keyword !in FUNCTION_KEYWORDS)
KotlinKeywordInsertHandler
else
JetFunctionInsertHandler.NO_PARAMETERS_HANDLER)
collector.addElement(element)
}
}
}
private val FUNCTION_KEYWORDS = listOf(JetTokens.GET_KEYWORD.toString(), JetTokens.SET_KEYWORD.toString())
private val NOT_IDENTIFIER_FILTER = NotFilter(AndFilter(
LeafElementFilter(JetTokens.IDENTIFIER),
NotFilter(ParentFilter(ClassFilter(javaClass<JetReferenceExpression>())))
))
private val GENERAL_FILTER = NotFilter(OrFilter(
CommentFilter(),
ParentFilter(ClassFilter(javaClass<JetLiteralStringTemplateEntry>())),
@@ -73,91 +70,6 @@ class KeywordCompletion {
LeftNeighbour(TextFilter("."))
))
private fun notIdentifier(filter: ElementFilter) = AndFilter(NOT_IDENTIFIER_FILTER, filter)
private val filterToKeyword: List<Pair<ElementFilter, Collection<String>>> = run {
val inTopLevel = notIdentifier(InTopFilter)
val inClassBody = notIdentifier(InClassBodyFilter())
val inNonClassBlock = notIdentifier(InNonClassBlockFilter)
val inPropertyBody = notIdentifier(InPropertyBodyFilter)
val inNonParameterModifier = notIdentifier(AndFilter(
SuperParentFilter(ClassFilter(javaClass<JetModifierList>())),
NotFilter(InTypeParameterFirstChildFilter)
))
val filtersToKeywords : MultiMap<HashSet<ElementFilter>, String> = MultiMap.create()
fun add(keyword: JetToken, vararg filters: ElementFilter) {
filtersToKeywords.putValue(hashSetOf(*filters), keyword.toString())
}
add(JetTokens.ABSTRACT_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody)
add(JetTokens.FINAL_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody)
add(JetTokens.OPEN_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody)
add(JetTokens.INTERNAL_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody, inNonClassBlock)
add(JetTokens.PRIVATE_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody, inNonClassBlock)
add(JetTokens.PROTECTED_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody, inNonClassBlock)
add(JetTokens.PUBLIC_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody, inNonClassBlock)
add(JetTokens.CLASS_KEYWORD, inTopLevel, inClassBody, inNonClassBlock)
add(JetTokens.ENUM_KEYWORD, inTopLevel, inClassBody, inNonClassBlock)
add(JetTokens.FUN_KEYWORD, inTopLevel, inClassBody, inNonClassBlock)
add(JetTokens.GET_KEYWORD, inTopLevel, inClassBody, inNonClassBlock)
add(JetTokens.SET_KEYWORD, inTopLevel, inClassBody, inNonClassBlock)
add(JetTokens.TRAIT_KEYWORD, inTopLevel, inClassBody, inNonClassBlock)
add(JetTokens.VAL_KEYWORD, inTopLevel, inClassBody, inNonClassBlock)
add(JetTokens.VAR_KEYWORD, inTopLevel, inClassBody, inNonClassBlock)
add(JetTokens.TYPE_ALIAS_KEYWORD, inTopLevel, inClassBody, inNonClassBlock)
add(JetTokens.IMPORT_KEYWORD, inTopLevel)
add(JetTokens.PACKAGE_KEYWORD, inTopLevel)
add(JetTokens.OVERRIDE_KEYWORD, inClassBody)
add(JetTokens.IN_KEYWORD, inNonClassBlock, InTypeParameterFirstChildFilter)
add(JetTokens.OUT_KEYWORD, InTypeParameterFirstChildFilter)
add(JetTokens.OBJECT_KEYWORD, inNonClassBlock, inClassBody, AfterClassInClassBodyFilter)
add(JetTokens.ELSE_KEYWORD, inNonClassBlock, inPropertyBody)
add(JetTokens.IF_KEYWORD, inNonClassBlock, inPropertyBody)
add(JetTokens.TRUE_KEYWORD, inNonClassBlock, inPropertyBody)
add(JetTokens.FALSE_KEYWORD, inNonClassBlock, inPropertyBody)
add(JetTokens.NULL_KEYWORD, inNonClassBlock, inPropertyBody)
add(JetTokens.THIS_KEYWORD, inNonClassBlock, inPropertyBody)
add(JetTokens.WHEN_KEYWORD, inNonClassBlock, inPropertyBody)
add(JetTokens.AS_KEYWORD, inNonClassBlock)
add(JetTokens.BREAK_KEYWORD, inNonClassBlock)
add(JetTokens.BY_KEYWORD, inNonClassBlock)
add(JetTokens.CATCH_KEYWORD, inNonClassBlock)
add(JetTokens.CONTINUE_KEYWORD, inNonClassBlock)
add(JetTokens.DO_KEYWORD, inNonClassBlock)
add(JetTokens.FINALLY_KEYWORD, inNonClassBlock)
add(JetTokens.FOR_KEYWORD, inNonClassBlock)
add(JetTokens.IS_KEYWORD, inNonClassBlock)
add(JetTokens.RETURN_KEYWORD, inNonClassBlock)
add(JetTokens.SUPER_KEYWORD, inNonClassBlock)
add(JetTokens.CAPITALIZED_THIS_KEYWORD, inNonClassBlock)
add(JetTokens.THROW_KEYWORD, inNonClassBlock)
add(JetTokens.TRY_KEYWORD, inNonClassBlock)
add(JetTokens.VARARG_KEYWORD, inNonClassBlock)
add(JetTokens.WHERE_KEYWORD, inNonClassBlock)
add(JetTokens.WHILE_KEYWORD, inNonClassBlock)
val result = ArrayList<Pair<ElementFilter, Collection<String>>>()
for ((filters, tokens) in filtersToKeywords.entrySet()) {
val orFilter = OrFilter()
filters.forEach { filter -> orFilter.addFilter(filter) }
result.add(orFilter to tokens)
}
result
}
private class CommentFilter() : ElementFilter {
override fun isAcceptable(element : Any?, context : PsiElement?)
= (element is PsiElement) && JetPsiUtil.isInComment(element as PsiElement)
@@ -177,82 +89,94 @@ class KeywordCompletion {
}
}
private object InTopFilter : PositionElementFilter() {
override fun isAcceptable(element : Any?, context : PsiElement?) : Boolean {
val underFile = PsiTreeUtil.getParentOfType(context, javaClass<JetFile>(), false,
javaClass<JetClass>(), javaClass<JetClassBody>(), javaClass<JetBlockExpression>(), javaClass<JetFunction>()) != null
val notInDeclarationElement = PsiTreeUtil.getParentOfType(
context,
javaClass<JetParameterList>(), javaClass<JetTypeParameterList>(), javaClass<JetClass>()) == null
return underFile && notInDeclarationElement
}
}
private object InNonClassBlockFilter : PositionElementFilter() {
override fun isAcceptable(element : Any?, context : PsiElement?)
= PsiTreeUtil.getParentOfType(context, javaClass<JetBlockExpression>(), true, javaClass<JetClassBody>()) != null
}
private object InTypeParameterFirstChildFilter : PositionElementFilter() {
override fun isAcceptable(element : Any?, context : PsiElement?) : Boolean {
val typeParameterElement = PsiTreeUtil.getParentOfType(context, javaClass<JetTypeParameter>(), true)
return typeParameterElement != null &&
context != null &&
PsiTreeUtil.isAncestor(typeParameterElement.getFirstChild(), context, false)
}
}
private open class InClassBodyFilter() : PositionElementFilter() {
override fun isAcceptable(element : Any?, context : PsiElement?) : Boolean {
return PsiTreeUtil.getParentOfType(
context, javaClass<JetClassBody>(), true,
javaClass<JetBlockExpression>(),
javaClass<JetProperty>(),
javaClass<JetParameterList>()) != null
}
}
private object AfterClassInClassBodyFilter : InClassBodyFilter() {
override fun isAcceptable(element : Any?, context : PsiElement?) : Boolean {
if (super.isAcceptable(element, context)) {
fun isLeafAndClass(psiElement: PsiElement?) =
psiElement is LeafPsiElement && psiElement.getElementType() == JetTokens.CLASS_KEYWORD
val ps = context?.getPrevSibling()
return isLeafAndClass(if (ps is PsiWhiteSpace) ps.getPrevSibling() else ps)
}
return false
}
}
private object InPropertyBodyFilter : PositionElementFilter() {
override fun isAcceptable(element: Any?, context: PsiElement?): Boolean {
if (element !is PsiElement) return false
val property = PsiTreeUtil.getParentOfType(context, javaClass<JetProperty>(), false)
return property != null && isAfterName(property, (element as PsiElement))
}
private fun isAfterName(property : JetProperty, element : PsiElement) : Boolean {
var iterableChild = property.getFirstChild()
while (iterableChild != null) {
val child = iterableChild!!
if (PsiTreeUtil.isAncestor(child, element, false)) {
break
private fun buildParserFilter(position: PsiElement): (String) -> Boolean {
var parent = position.getParent()
var prevParent = position
while (parent != null) {
val _parent = parent
when (_parent) {
is JetBlockExpression -> {
return buildParserFilterWithContextElement("fun foo() { ", prevParent, position)
}
if (child.getNode()?.getElementType() == JetTokens.IDENTIFIER) {
return true
is JetWithExpressionInitializer -> {
val initializer = _parent.getInitializer()
if (prevParent == initializer) {
return buildParserFilterWithContextElement("val v = ", initializer, position)
}
}
iterableChild = child.getNextSibling()
is JetParameter -> {
val default = _parent.getDefaultValue()
if (prevParent == default) {
return buildParserFilterWithContextElement("val v = ", default, position)
}
}
}
return false
if (_parent is JetDeclaration) {
val scope = _parent.getParent()
when (scope) {
is JetClassOrObject -> return buildParserFilterWithContextElement("class X { ", _parent, position)
is JetFile -> return buildParserFilterWithContextElement("", _parent, position)
}
}
prevParent = parent!!
parent = parent!!.getParent()
}
val builder = StringBuilder()
buildReducedContextBefore(builder, position)
return buildParserFilterByText(builder.toString(), position.getProject())
}
private fun buildParserFilterWithContextElement(prefixText: String,
contextElement: PsiElement,
position: PsiElement): (String) -> Boolean {
val offset = position.getStartOffsetInAncestor(contextElement)
val truncatedContext = contextElement.getText()!!.substring(0, offset)
return buildParserFilterByText(prefixText + truncatedContext, contextElement.getProject())
}
private fun buildParserFilterByText(prefixText: String, project: Project): (String) -> Boolean {
val psiFactory = JetPsiFactory(project)
return { keyword ->
val file = psiFactory.createFile(prefixText + keyword)
val elementAt = file.findElementAt(prefixText.length)!!
val nodeType = elementAt.getNode()!!.getElementType()
when {
nodeType !in JetTokens.KEYWORDS && nodeType !in JetTokens.SOFT_KEYWORDS -> false
elementAt.getParentByType(javaClass<PsiErrorElement>(), strict = false) != null -> false
elementAt.prevLeaf() is PsiErrorElement -> false
else -> true
}
}
}
// builds text before position element excluding declarations
private fun buildReducedContextBefore(builder: StringBuilder, position: PsiElement) {
val parent = position.getParent() ?: return
buildReducedContextBefore(builder, parent)
var child = parent.getFirstChild()
while (child != position) {
if (child !is JetDeclaration) {
builder.append(child!!.getText())
}
child = child!!.getNextSibling()
}
}
private fun PsiElement.getStartOffsetInAncestor(ancestor: PsiElement): Int {
val parent = getParent()!!
return if (parent == ancestor)
getStartOffsetInParent()
else
parent.getStartOffsetInAncestor(ancestor) + getStartOffsetInParent()
}
}
@@ -0,0 +1,11 @@
class Test {
class <caret>
}
/*TODO: should be only 'object'*/
// EXIST: class
// EXIST: fun
// EXIST: object
// EXIST: trait
// EXIST: val
// NUMBER: 5
@@ -1,7 +1,33 @@
class MouseMovedEventArgs
{
public val X : int = 0
in<caret>
<caret>
}
// EXIST: internal
// EXIST: abstract
// EXIST: annotation
// EXIST: as
// EXIST: class
// EXIST: enum
// EXIST: final
// EXIST: fun
// EXIST: get
// EXIST: in
/*why?*/
// EXIST: inner
// EXIST: internal
// EXIST: object
// EXIST: open
// EXIST: out
/*why?*/
// EXIST: override
// EXIST: private
// EXIST: protected
// EXIST: public
// EXIST: set
// EXIST: trait
// EXIST: val
// EXIST: var
// EXIST: vararg
/*why?*/
// NUMBER: 23
@@ -3,7 +3,4 @@ fun foo() {
str.<caret>
}
// ABSENT: package, as, type, class, this, super, val, var, fun, for, null, true
// ABSENT: false, is, in, throw, return, break, continue, object, if, try, else, while
// ABSENT: do, when, trait, This
// NUMBER: 0
@@ -3,4 +3,4 @@ fun foo() {
str. <caret>
}
// ABSENT: public, val, in, if, when, this
// NUMBER: 0
@@ -0,0 +1,25 @@
fun foo(p: Int) {
x()
y()
val edge = a.b(<caret>)
z()
}
// EXIST: break
// EXIST: continue
// EXIST: do
// EXIST: false
// EXIST: for
// EXIST: if
// EXIST: null
// EXIST: object
// EXIST: package
// EXIST: return
// EXIST: super
// EXIST: this
// EXIST: throw
// EXIST: true
// EXIST: try
// EXIST: when
// EXIST: while
// NUMBER: 17
@@ -4,8 +4,4 @@ class TestClass {
}
}
// ABSENT: abstract, annotation, as, break, by, catch, class, continue, default, do
// ABSENT: else, enum, false, final, finally, for, fun, get, if, import, in
// ABSENT: internal, is, null, object, open, out, override, package, private, protected, public
// ABSENT: ref, return, set, super, This, this, throw, trait, true, try, type, val, var
// ABSENT: vararg, when, where, while
// NUMBER: 0
+1 -5
View File
@@ -4,8 +4,4 @@ class TestClass {
}
}
// ABSENT: abstract, annotation, as, break, by, catch, class, continue, default, do
// ABSENT: else, enum, false, final, finally, for, fun, get, if, import, in
// ABSENT: internal, is, null, object, open, out, override, package, private, protected, public
// ABSENT: ref, return, set, super, This, this, throw, trait, true, try, type, val, var
// ABSENT: vararg, when, where, while
// NUMBER: 0
@@ -7,52 +7,28 @@ public class Test {
}
}
// EXIST: abstract
/* // ABSENT: annotation */
// ABSENT: as
// ABSENT: break
// ABSENT: by
// ABSENT: catch
// EXIST: annotation
// EXIST: class
// ABSENT: continue
// ABSENT: default
// ABSENT: do
// ABSENT: else
// EXIST: enum
// ABSENT: false
// EXIST: final
// ABSENT: finally
// ABSENT: for
// EXIST: fun
// EXIST: get
// ABSENT: if
// ABSENT: import
// ABSENT: in
// EXIST: in
/*why?*/
// EXIST: inner
// EXIST: internal
// ABSENT: is
// ABSENT: null
// EXIST: object
// EXIST: open
// ABSENT: out
// EXIST: out
/*why?*/
// EXIST: override
// ABSENT: package
// EXIST: private
// EXIST: protected
// EXIST: public
// ABSENT: ref
// ABSENT: return
// EXIST: set
// ABSENT: super
// ABSENT: This
// ABSENT: this
// ABSENT: throw
// EXIST: trait
// ABSENT: true
// ABSENT: try
// EXIST: typealias
// EXIST: val
// EXIST: var
// ABSENT: vararg
// ABSENT: when
// ABSENT: where
// ABSENT: while
// EXIST: vararg
/*why?*/
// NUMBER: 20
@@ -3,51 +3,26 @@ class TestClass {
}
// EXIST: abstract
// ABSENT: annotation
// ABSENT: as
// ABSENT: break
// ABSENT: by
// ABSENT: catch
// EXIST: annotation
// EXIST: class
// ABSENT: continue
// ABSENT: default
// ABSENT: do
// ABSENT: else
// EXIST: enum
// ABSENT: false
// EXIST: final
// ABSENT: finally
// ABSENT: for
// EXIST: fun
// EXIST: get
// ABSENT: if
// ABSENT: import
// ABSENT: in
// EXIST: in
/*why?*/
// EXIST: inner
// EXIST: internal
// ABSENT: is
// ABSENT: null
// EXIST: object
// EXIST: open
// ABSENT: out
// EXIST: out
/*why?*/
// EXIST: override
// ABSENT: package
// EXIST: private
// EXIST: protected
// EXIST: public
// ABSENT: ref
// ABSENT: return
// EXIST: set
// ABSENT: super
// ABSENT: This
// ABSENT: this
// ABSENT: throw
// EXIST: trait
// ABSENT: true
// ABSENT: try
// EXIST: typealias
// EXIST: val
// EXIST: var
// ABSENT: vararg
// ABSENT: when
// ABSENT: where
// ABSENT: while
// EXIST: vararg
/*why?*/
// NUMBER: 20
@@ -1,4 +1,5 @@
class T<<caret>>
// EXIST: in, out
// ABSENT: private
// EXIST: in
/*TODO: // EXIST: out*/
// NUMBER: 1
@@ -0,0 +1,27 @@
fun foo() {
<caret>
}
// EXIST: break
// EXIST: class
// EXIST: continue
// EXIST: do
// EXIST: false
// EXIST: for
// EXIST: fun
// EXIST: if
// EXIST: null
// EXIST: object
// EXIST: package
// EXIST: return
// EXIST: super
// EXIST: this
// EXIST: throw
// EXIST: trait
// EXIST: true
// EXIST: try
// EXIST: val
// EXIST: var
// EXIST: when
// EXIST: while
// NUMBER: 22
@@ -0,0 +1,20 @@
fun foo() = <caret>
// EXIST: break
// EXIST: continue
// EXIST: do
// EXIST: false
// EXIST: for
// EXIST: if
// EXIST: null
// EXIST: object
// EXIST: package
// EXIST: return
// EXIST: super
// EXIST: this
// EXIST: throw
// EXIST: true
// EXIST: try
// EXIST: when
// EXIST: while
// NUMBER: 17
@@ -0,0 +1,5 @@
fun <caret>.
// NUMBER: 0
// For KT-1894
@@ -1,51 +0,0 @@
fun foo() {
<caret>
}
// ABSENT: abstract
/* // ABSENT: annotation */
// EXIST: as
// EXIST: break
// EXIST: by
// EXIST: catch
// EXIST: class
// EXIST: continue
// EXIST: do
// EXIST: else
// EXIST: enum
// EXIST: false
// ABSENT: final
// EXIST: finally
// EXIST: for
// EXIST: fun
// EXIST: get
// EXIST: if
// ABSENT: import
// EXIST: in
// EXIST: internal
// EXIST: is
// EXIST: null
// EXIST: object
// ABSENT: open
// ABSENT: out
// ABSENT: override
// ABSENT: package
// EXIST: private
// EXIST: protected
// EXIST: public
// EXIST: return
// EXIST: set
// EXIST: super
// EXIST: This
// EXIST: this
// EXIST: throw
// EXIST: trait
// EXIST: true
// EXIST: try
// EXIST: typealias
// EXIST: val
// EXIST: var
// EXIST: vararg
// EXIST: when
// EXIST: where
// EXIST: while
@@ -0,0 +1,7 @@
fun foo() {
val test : <caret>
}
/*TODO: Is 'package' type qualifier syntax correct?*/
// EXIST: package
// NUMBER: 1
@@ -1,5 +0,0 @@
fun f<caret>.
// ABSENT: final
// For KT-1894
@@ -0,0 +1,21 @@
val prop: Int
get() = <caret>
// EXIST: break
// EXIST: continue
// EXIST: do
// EXIST: false
// EXIST: for
// EXIST: if
// EXIST: null
// EXIST: object
// EXIST: package
// EXIST: return
// EXIST: super
// EXIST: this
// EXIST: throw
// EXIST: true
// EXIST: try
// EXIST: when
// EXIST: while
// NUMBER: 17
@@ -0,0 +1,12 @@
package TestData
class TestSample() {
fun test(<caret>) {
}
}
/* TODO: they all are not correct */
// EXIST: val
// EXIST: var
// EXIST: in
// NUMBER: 3
@@ -1,54 +0,0 @@
package TestData
class TestSample() {
fun test(<caret>) {
}
}
// ABSENT: abstract
// ABSENT: annotation
// ABSENT: as
// ABSENT: break
// ABSENT: by
// ABSENT: catch
// ABSENT: class
// ABSENT: continue
// ABSENT: do
// ABSENT: else
// ABSENT: enum
// ABSENT: false
// ABSENT: final
// ABSENT: finally
// ABSENT: for
// ABSENT: fun
// ABSENT: get
// ABSENT: if
// ABSENT: import
// ABSENT: in
// ABSENT: internal
// ABSENT: is
// ABSENT: null
// ABSENT: object
// ABSENT: open
// ABSENT: out
// ABSENT: override
// ABSENT: package
// ABSENT: private
// ABSENT: protected
// ABSENT: public
// ABSENT: return
// ABSENT: set
// ABSENT: super
// ABSENT: This
// ABSENT: this
// ABSENT: throw
// ABSENT: trait
// ABSENT: true
// ABSENT: try
// ABSENT: type
// ABSENT: val
// ABSENT: var
// ABSENT: vararg
// ABSENT: when
// ABSENT: where
// ABSENT: while
@@ -3,4 +3,5 @@ open class Foo {
p<caret> val foo = 1
}
// EXIST: private, public, protected
// EXIST: private, public, protected, open
// NUMBER: 4
@@ -2,5 +2,6 @@ class Test<<caret>
fun testing() {}
// ABSENT: private, public, protected, abstract
// EXIST: in, out
// EXIST: in
/*TODO: // EXIST: out*/
// NUMBER: 1
@@ -0,0 +1,20 @@
fun foo(p: Int = <caret>)
// EXIST: break
// EXIST: continue
// EXIST: do
// EXIST: false
// EXIST: for
// EXIST: if
// EXIST: null
// EXIST: object
// EXIST: package
// EXIST: return
// EXIST: super
// EXIST: this
// EXIST: throw
// EXIST: true
// EXIST: try
// EXIST: when
// EXIST: while
// NUMBER: 17
@@ -1,51 +0,0 @@
fun test(<caret>) {
}
// ABSENT: abstract
// ABSENT: annotation
// ABSENT: as
// ABSENT: break
// ABSENT: by
// ABSENT: catch
// ABSENT: class
// ABSENT: continue
// ABSENT: do
// ABSENT: else
// ABSENT: enum
// ABSENT: false
// ABSENT: final
// ABSENT: finally
// ABSENT: for
// ABSENT: fun
// ABSENT: get
// ABSENT: if
// ABSENT: import
// ABSENT: in
// ABSENT: internal
// ABSENT: is
// ABSENT: null
// ABSENT: object
// ABSENT: open
// ABSENT: out
// ABSENT: override
// ABSENT: package
// ABSENT: private
// ABSENT: protected
// ABSENT: public
// ABSENT: return
// ABSENT: set
// ABSENT: super
// ABSENT: This
// ABSENT: this
// ABSENT: throw
// ABSENT: trait
// ABSENT: true
// ABSENT: try
// ABSENT: type
// ABSENT: val
// ABSENT: var
// ABSENT: vararg
// ABSENT: when
// ABSENT: where
// ABSENT: while
@@ -0,0 +1,20 @@
var a : Int = <caret>
// EXIST: break
// EXIST: continue
// EXIST: do
// EXIST: false
// EXIST: for
// EXIST: if
// EXIST: null
// EXIST: object
// EXIST: package
// EXIST: return
// EXIST: super
// EXIST: this
// EXIST: throw
// EXIST: true
// EXIST: try
// EXIST: when
// EXIST: while
// NUMBER: 17
@@ -1,5 +1,5 @@
val e.<caret>
// ABSENT: else
// NUMBER: 0
// For KT-1950
@@ -4,8 +4,4 @@ class TestClass {
}
}
// ABSENT: abstract, annotation, as, break, by, catch, class, continue, default, do
// ABSENT: else, enum, false, final, finally, for, fun, get, if, import, in
// ABSENT: internal, is, null, object, open, out, override, package, private, protected, public
// ABSENT: ref, return, set, super, This, this, throw, trait, true, try, type, val, var
// ABSENT: vararg, when, where, while
// NUMBER: 0
@@ -0,0 +1,9 @@
fun test(<caret>) {
}
/* TODO: they all are not correct */
// EXIST: val
// EXIST: var
// EXIST: in
// NUMBER: 3
@@ -1,8 +0,0 @@
var a : Int = <caret>
// EXIST: else
// EXIST: false
// EXIST: if
// EXIST: null
// EXIST: this
// EXIST: true
@@ -2,8 +2,28 @@ package Test
<caret>
// EXIST: enum
// EXIST: trait
// EXIST: abstract
// EXIST: annotation
// EXIST: class
// EXIST: enum
// EXIST: final
// EXIST: fun
// EXIST: import
// EXIST: in
/*why?*/
// EXIST: inner
// EXIST: internal
// EXIST: object
// EXIST: open
// EXIST: out
/*why?*/
// EXIST: override
// EXIST: private
// EXIST: protected
// EXIST: public
// EXIST: trait
// EXIST: val
// EXIST: var
// EXIST: vararg
/*why?*/
// NUMBER: 21
@@ -1,51 +0,0 @@
fun foo() {
val test : <caret>
}
// ABSENT: abstract
/* // ABSENT: annotation */
// EXIST: as
// EXIST: break
// EXIST: by
// EXIST: catch
// EXIST: class
// EXIST: continue
// EXIST: do
// EXIST: else
// EXIST: enum
// EXIST: false
// ABSENT: final
// EXIST: finally
// EXIST: for
// EXIST: fun
// EXIST: get
// EXIST: if
// ABSENT: import
// EXIST: in
// EXIST: internal
// EXIST: is
// EXIST: null
// EXIST: object
// ABSENT: open
// ABSENT: out
// ABSENT: override
// ABSENT: package
// EXIST: private
// EXIST: protected
// EXIST: public
// EXIST: return
// EXIST: set
// EXIST: super
// EXIST: This
// EXIST: this
// EXIST: throw
// EXIST: trait
// EXIST: true
// EXIST: try
// EXIST: typealias
// EXIST: val
// EXIST: var
// EXIST: vararg
// EXIST: when
// EXIST: where
// EXIST: while
@@ -2,8 +2,4 @@ class TestClass {
// <caret>
}
// ABSENT: abstract, annotation, as, break, by, catch, class, continue, default, do
// ABSENT: else, enum, false, final, finally, for, fun, get, if, import, in
// ABSENT: internal, is, null, object, open, out, override, package, private, protected, public
// ABSENT: ref, return, set, super, This, this, throw, trait, true, try, type, val, var
// ABSENT: vararg, when, where, while
// NUMBER: 0
@@ -1,3 +1,3 @@
P<caret>
// ABSENT: public, private, protected
// NUMBER: 0
@@ -0,0 +1,32 @@
class Some {
var a : Int
<caret>
}
// EXIST: abstract
// EXIST: annotation
// EXIST: by
// EXIST: class
// EXIST: enum
// EXIST: final
// EXIST: fun
// EXIST: get
// EXIST: in
/*why?*/
// EXIST: inner
// EXIST: internal
// EXIST: object
// EXIST: open
// EXIST: out
/*why?*/
// EXIST: override
// EXIST: private
// EXIST: protected
// EXIST: public
// EXIST: set
// EXIST: trait
// EXIST: val
// EXIST: var
// EXIST: vararg
/*why?*/
// NUMBER: 23
@@ -0,0 +1,50 @@
/*
* 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.
*/
class Some {
var a : Int
get() = 0
<caret>
}
// EXIST: abstract
// EXIST: annotation
// EXIST: as
// EXIST: class
// EXIST: enum
// EXIST: final
// EXIST: fun
// EXIST: get
/*TODO*/
// EXIST: in
/*why?*/
// EXIST: inner
// EXIST: internal
// EXIST: object
// EXIST: open
// EXIST: out
/*why?*/
// EXIST: override
// EXIST: private
// EXIST: protected
// EXIST: public
// EXIST: set
// EXIST: trait
// EXIST: val
// EXIST: var
// EXIST: vararg
/*why?*/
// NUMBER: 23
@@ -1,7 +0,0 @@
class Some {
val a : Int
<caret>
}
// EXIST: get
// EXIST: set
+11 -33
View File
@@ -1,50 +1,28 @@
<caret>
// EXIST: abstract
// ABSENT: annotation
// ABSENT: as
// ABSENT: break
// ABSENT: by
// ABSENT: catch
// EXIST: annotation
// EXIST: class
// ABSENT: continue
// ABSENT: default
// ABSENT: do
// ABSENT: else
// EXIST: enum
// ABSENT: false
// EXIST: final
// ABSENT: finally
// ABSENT: for
// EXIST: fun
// EXIST: get
// ABSENT: if
// EXIST: import
// ABSENT: in
// EXIST: in
/*why?*/
// EXIST: inner
// EXIST: internal
// ABSENT: is
// ABSENT: null
// EXIST: object
// EXIST: open
// ABSENT: out
// ABSENT: override
// EXIST: out
/*why?*/
// EXIST: override
// EXIST: package
// EXIST: private
// EXIST: protected
// EXIST: public
// ABSENT: ref
// ABSENT: return
// EXIST: set
// ABSENT: super
// ABSENT: This
// ABSENT: this
// ABSENT: throw
// EXIST: trait
// ABSENT: true
// ABSENT: try
// EXIST: typealias
// EXIST: val
// EXIST: var
// ABSENT: vararg
// ABSENT: when
// ABSENT: where
// ABSENT: while
// EXIST: vararg
/*why?*/
// NUMBER: 22
@@ -1,5 +0,0 @@
class Test {
class <caret>
}
// EXIST: object
@@ -34,6 +34,12 @@ import java.util.regex.Pattern;
@TestDataPath("$PROJECT_ROOT")
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTest {
@TestMetadata("AfterClassKeyword.kt")
public void testAfterClassKeyword() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/AfterClassKeyword.kt");
doTest(fileName);
}
@TestMetadata("AfterClassProperty.kt")
public void testAfterClassProperty() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/AfterClassProperty.kt");
@@ -56,9 +62,9 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/completion/keywords"), Pattern.compile("^(.+)\\.kt$"), false);
}
@TestMetadata("classObject.kt")
public void testClassObject() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/classObject.kt");
@TestMetadata("InArgumentList.kt")
public void testInArgumentList() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InArgumentList.kt");
doTest(fileName);
}
@@ -104,27 +110,45 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
doTest(fileName);
}
@TestMetadata("InCodeBlock.kt")
public void testInCodeBlock() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InCodeBlock.kt");
doTest(fileName);
}
@TestMetadata("InFunctionExpressionBody.kt")
public void testInFunctionExpressionBody() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InFunctionExpressionBody.kt");
doTest(fileName);
}
@TestMetadata("InFunctionName.kt")
public void testInFunctionName() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InFunctionName.kt");
doTest(fileName);
}
@TestMetadata("InFunctionScope.kt")
public void testInFunctionScope() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InFunctionScope.kt");
@TestMetadata("InFunctionRecieverType.kt")
public void testInFunctionRecieverType() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InFunctionRecieverType.kt");
doTest(fileName);
}
@TestMetadata("InFunctionTypeReference.kt")
public void testInFunctionTypeReference() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InFunctionTypeReference.kt");
@TestMetadata("InFunctionTypePosition.kt")
public void testInFunctionTypePosition() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InFunctionTypePosition.kt");
doTest(fileName);
}
@TestMetadata("InMethodParametersList.kt")
public void testInMethodParametersList() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InMethodParametersList.kt");
@TestMetadata("InGetterExpressionBody.kt")
public void testInGetterExpressionBody() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InGetterExpressionBody.kt");
doTest(fileName);
}
@TestMetadata("InMemberFunParametersList.kt")
public void testInMemberFunParametersList() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InMemberFunParametersList.kt");
doTest(fileName);
}
@@ -140,9 +164,15 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
doTest(fileName);
}
@TestMetadata("InParametersList.kt")
public void testInParametersList() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InParametersList.kt");
@TestMetadata("InParameterDefaultValue.kt")
public void testInParameterDefaultValue() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InParameterDefaultValue.kt");
doTest(fileName);
}
@TestMetadata("InPropertyInitializer.kt")
public void testInPropertyInitializer() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InPropertyInitializer.kt");
doTest(fileName);
}
@@ -158,9 +188,9 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
doTest(fileName);
}
@TestMetadata("InTopProperty.kt")
public void testInTopProperty() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InTopProperty.kt");
@TestMetadata("InTopFunParametersList.kt")
public void testInTopFunParametersList() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InTopFunParametersList.kt");
doTest(fileName);
}
@@ -170,12 +200,6 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
doTest(fileName);
}
@TestMetadata("InTypeScope.kt")
public void testInTypeScope() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/InTypeScope.kt");
doTest(fileName);
}
@TestMetadata("LineComment.kt")
public void testLineComment() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/LineComment.kt");
@@ -188,9 +212,15 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
doTest(fileName);
}
@TestMetadata("PropertySetterGetter.kt")
public void testPropertySetterGetter() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/PropertySetterGetter.kt");
@TestMetadata("PropertyAccessors.kt")
public void testPropertyAccessors() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/PropertyAccessors.kt");
doTest(fileName);
}
@TestMetadata("PropertySetter.kt")
public void testPropertySetter() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/PropertySetter.kt");
doTest(fileName);
}