diff --git a/annotations/com/intellij/codeInsight/lookup/annotations.xml b/annotations/com/intellij/codeInsight/lookup/annotations.xml
index 8ad65130b35..200c723282b 100644
--- a/annotations/com/intellij/codeInsight/lookup/annotations.xml
+++ b/annotations/com/intellij/codeInsight/lookup/annotations.xml
@@ -17,6 +17,9 @@
name='com.intellij.codeInsight.lookup.LookupElementBuilder com.intellij.codeInsight.lookup.LookupElement withAutoCompletionPolicy(com.intellij.codeInsight.lookup.AutoCompletionPolicy)'>
+ -
+
+
-
diff --git a/annotations/com/intellij/patterns/annotations.xml b/annotations/com/intellij/patterns/annotations.xml
new file mode 100644
index 00000000000..7a2165d4dcf
--- /dev/null
+++ b/annotations/com/intellij/patterns/annotations.xml
@@ -0,0 +1,6 @@
+
+
-
+
+
+
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.kt b/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.kt
index fe1c8026a4d..d8cdd9d75a9 100644
--- a/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.kt
+++ b/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.kt
@@ -14,324 +14,282 @@
* limitations under the License.
*/
-package org.jetbrains.jet.plugin.completion;
+package org.jetbrains.jet.plugin.completion
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Ordering;
-import com.google.common.collect.Sets;
-import com.intellij.codeInsight.completion.*;
-import com.intellij.codeInsight.lookup.LookupElement;
-import com.intellij.codeInsight.lookup.LookupElementBuilder;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.patterns.ElementPattern;
-import com.intellij.patterns.PlatformPatterns;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiWhiteSpace;
-import com.intellij.psi.filters.*;
-import com.intellij.psi.filters.position.FilterPattern;
-import com.intellij.psi.filters.position.LeftNeighbour;
-import com.intellij.psi.filters.position.PositionElementFilter;
-import com.intellij.psi.filters.position.SuperParentFilter;
-import com.intellij.psi.impl.source.tree.LeafPsiElement;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.ProcessingContext;
-import com.intellij.util.containers.MultiMap;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.jet.lang.psi.*;
-import org.jetbrains.jet.lexer.JetToken;
-import org.jetbrains.jet.lexer.JetTokens;
-import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler;
-import org.jetbrains.jet.plugin.completion.handlers.JetKeywordInsertHandler;
-import org.jetbrains.jet.plugin.completion.weigher.WeigherPackage;
+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.codeInsight.completion.CompletionContributor
+import com.intellij.codeInsight.completion.CompletionType
+import com.intellij.codeInsight.lookup.LookupElement
+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.openapi.util.text.StringUtil
+import com.intellij.codeInsight.completion.PrefixMatcher
+import com.intellij.codeInsight.completion.CompletionProvider
+import com.intellij.codeInsight.completion.CompletionParameters
+import com.intellij.codeInsight.completion.CompletionResultSet
+import com.intellij.util.ProcessingContext
+import com.intellij.codeInsight.lookup.LookupElementBuilder
+import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler
+import com.intellij.psi.filters.position.FilterPattern
+import com.intellij.patterns.PlatformPatterns
+import org.jetbrains.jet.plugin.completion.handlers.JetKeywordInsertHandler
+import org.jetbrains.jet.plugin.completion.weigher.addJetSorting
-import java.util.*;
-import java.util.List;
+public open class JetKeywordCompletionContributor() : CompletionContributor() {
+ {
+ val inTopLevel = notIdentifier(InTopFilter())
+ val inTypeParameterFirstChildFilter = InTypeParameterFirstChildFilter()
+ val inClassBody = notIdentifier(InClassBodyFilter())
+ val inNonClassBlock = notIdentifier(InNonClassBlockFilter())
+ val inAfterClassInClassBody = AfterClassInClassBodyFilter()
+ val inPropertyBody = notIdentifier(InPropertyBodyFilter())
-import static org.jetbrains.jet.lexer.JetTokens.*;
+ val inNonParameterModifier = notIdentifier(AndFilter(
+ SuperParentFilter(ClassFilter(javaClass())),
+ NotFilter(inTypeParameterFirstChildFilter)
+ ))
-/**
- * A keyword contributor for Kotlin
- */
-public class JetKeywordCompletionContributor extends CompletionContributor {
- private final static InsertHandler KEYWORDS_INSERT_HANDLER = new JetKeywordInsertHandler();
+ BunchKeywordRegister()
+ .add(JetTokens.ABSTRACT_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody)
+ .add(JetTokens.FINAL_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody)
+ .add(JetTokens.OPEN_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody)
- private final static ElementFilter GENERAL_FILTER = new NotFilter(new OrFilter(
- new CommentFilter(), // or
- new ParentFilter(new ClassFilter(JetLiteralStringTemplateEntry.class)), // or
- new ParentFilter(new ClassFilter(JetConstantExpression.class)), // or
- new LeftNeighbour(new TextFilter("."))
- ));
+ .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)
- private final static ElementFilter NOT_IDENTIFIER_FILTER = new NotFilter(new AndFilter(
- new LeafElementFilter(JetTokens.IDENTIFIER),
- new NotFilter(new ParentFilter(new ClassFilter(JetReferenceExpression.class))))
- );
+ .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_KEYWORD, inTopLevel, inClassBody, inNonClassBlock)
- private final static List FUNCTION_KEYWORDS = Lists.newArrayList(GET_KEYWORD.toString(), SET_KEYWORD.toString());
+ .add(JetTokens.IMPORT_KEYWORD, inTopLevel)
+ .add(JetTokens.PACKAGE_KEYWORD, inTopLevel)
- public JetKeywordCompletionContributor() {
- ElementFilter inTopLevel = notIdentifier(new InTopFilter());
- ElementFilter inTypeParameterFirstChildFilter = new InTypeParameterFirstChildFilter();
- ElementFilter inClassBody = notIdentifier(new InClassBodyFilter());
- ElementFilter inNonClassBlock = notIdentifier(new InNonClassBlockFilter());
- ElementFilter inAfterClassInClassBody = new AfterClassInClassBodyFilter();
- ElementFilter inPropertyBody = notIdentifier(new InPropertyBodyFilter());
- ElementFilter inNonParameterModifier = notIdentifier(new AndFilter(
- new SuperParentFilter(new ClassFilter(JetModifierList.class)),
- new NotFilter(inTypeParameterFirstChildFilter)));
+ .add(JetTokens.OVERRIDE_KEYWORD, inClassBody)
- BunchKeywordRegister register = new BunchKeywordRegister();
+ .add(JetTokens.IN_KEYWORD, inNonClassBlock, inTypeParameterFirstChildFilter)
- register.add(ABSTRACT_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody);
- register.add(FINAL_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody);
- register.add(OPEN_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody);
+ .add(JetTokens.OUT_KEYWORD, inTypeParameterFirstChildFilter)
- register.add(INTERNAL_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody, inNonClassBlock);
- register.add(PRIVATE_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody, inNonClassBlock);
- register.add(PROTECTED_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody, inNonClassBlock);
- register.add(PUBLIC_KEYWORD, inTopLevel, inNonParameterModifier, inClassBody, inNonClassBlock);
+ .add(JetTokens.OBJECT_KEYWORD, inNonClassBlock, inAfterClassInClassBody)
- register.add(CLASS_KEYWORD, inTopLevel, inClassBody, inNonClassBlock);
- register.add(ENUM_KEYWORD, inTopLevel, inClassBody, inNonClassBlock);
- register.add(FUN_KEYWORD, inTopLevel, inClassBody, inNonClassBlock);
- register.add(GET_KEYWORD, inTopLevel, inClassBody, inNonClassBlock);
- register.add(SET_KEYWORD, inTopLevel, inClassBody, inNonClassBlock);
- register.add(TRAIT_KEYWORD, inTopLevel, inClassBody, inNonClassBlock);
- register.add(VAL_KEYWORD, inTopLevel, inClassBody, inNonClassBlock);
- register.add(VAR_KEYWORD, inTopLevel, inClassBody, inNonClassBlock);
- register.add(TYPE_KEYWORD, inTopLevel, inClassBody, inNonClassBlock);
+ .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)
- register.add(IMPORT_KEYWORD, inTopLevel);
- register.add(PACKAGE_KEYWORD, inTopLevel);
-
- register.add(OVERRIDE_KEYWORD, inClassBody);
-
- register.add(IN_KEYWORD, inNonClassBlock, inTypeParameterFirstChildFilter);
- register.add(OUT_KEYWORD, inTypeParameterFirstChildFilter);
- register.add(OBJECT_KEYWORD, inNonClassBlock, inAfterClassInClassBody);
-
- register.add(ELSE_KEYWORD, inNonClassBlock, inPropertyBody);
- register.add(IF_KEYWORD, inNonClassBlock, inPropertyBody);
- register.add(TRUE_KEYWORD, inNonClassBlock, inPropertyBody);
- register.add(FALSE_KEYWORD, inNonClassBlock, inPropertyBody);
- register.add(NULL_KEYWORD, inNonClassBlock, inPropertyBody);
- register.add(THIS_KEYWORD, inNonClassBlock, inPropertyBody);
- register.add(WHEN_KEYWORD, inNonClassBlock, inPropertyBody);
-
- register.add(AS_KEYWORD, inNonClassBlock);
- register.add(BREAK_KEYWORD, inNonClassBlock);
- register.add(BY_KEYWORD, inNonClassBlock);
- register.add(CATCH_KEYWORD, inNonClassBlock);
- register.add(CONTINUE_KEYWORD, inNonClassBlock);
- register.add(DO_KEYWORD, inNonClassBlock);
- register.add(FINALLY_KEYWORD, inNonClassBlock);
- register.add(FOR_KEYWORD, inNonClassBlock);
- register.add(IS_KEYWORD, inNonClassBlock);
- register.add(RETURN_KEYWORD, inNonClassBlock);
- register.add(SUPER_KEYWORD, inNonClassBlock);
- register.add(CAPITALIZED_THIS_KEYWORD, inNonClassBlock);
- register.add(THROW_KEYWORD, inNonClassBlock);
- register.add(TRY_KEYWORD, inNonClassBlock);
- register.add(VARARG_KEYWORD, inNonClassBlock);
- register.add(WHERE_KEYWORD, inNonClassBlock);
- register.add(WHILE_KEYWORD, inNonClassBlock);
-
- register.registerAll();
+ .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)
+ .registerAll()
}
- private static ElementFilter notIdentifier(ElementFilter filter) {
- return new AndFilter(NOT_IDENTIFIER_FILTER, filter);
+ private fun registerScopeKeywordsCompletion(placeFilter : ElementFilter, keywords : Collection) {
+ extend(CompletionType.BASIC, getPlacePattern(placeFilter), KeywordsCompletionProvider(keywords.map { it.toString()!! }))
}
- private static ElementPattern getPlacePattern(ElementFilter placeFilter) {
- return PlatformPatterns.psiElement().and(new FilterPattern(new AndFilter(GENERAL_FILTER, placeFilter)));
+ private inner class BunchKeywordRegister() {
+ private val orFiltersToKeywords : MultiMap, JetToken> = MultiMap.create()
+
+ fun add(keyword: JetToken, vararg filters: ElementFilter): BunchKeywordRegister {
+ orFiltersToKeywords.putValue(hashSetOf(*filters), keyword)
+ return this
+ }
+
+ fun registerAll() {
+ for (entry in orFiltersToKeywords.entrySet()!!) {
+ val orFilter = OrFilter()
+ entry.key.forEach { filter -> orFilter.addFilter(filter) }
+
+ registerScopeKeywordsCompletion(orFilter, entry.value)
+ }
+ }
}
- private void registerScopeKeywordsCompletion(ElementFilter placeFilter, Collection keywords) {
- extend(CompletionType.BASIC, getPlacePattern(placeFilter),
- new KeywordsCompletionProvider(Collections2.transform(keywords, Functions.toStringFunction())));
- }
+ class object {
+ private val KEYWORDS_INSERT_HANDLER = JetKeywordInsertHandler()
+ private val FUNCTION_KEYWORDS = listOf(JetTokens.GET_KEYWORD.toString(), JetTokens.SET_KEYWORD.toString())
- private static class CommentFilter implements ElementFilter {
- @Override
- public boolean isAcceptable(Object element, PsiElement context) {
- if (!(element instanceof PsiElement)) {
- return false;
+ private val NOT_IDENTIFIER_FILTER = NotFilter(AndFilter(
+ LeafElementFilter(JetTokens.IDENTIFIER),
+ NotFilter(ParentFilter(ClassFilter(javaClass())))
+ ))
+
+ private val GENERAL_FILTER : ElementFilter = NotFilter(OrFilter(
+ CommentFilter(),
+ ParentFilter(ClassFilter(javaClass())),
+ ParentFilter(ClassFilter(javaClass())),
+ LeftNeighbour(TextFilter("."))
+ ))
+
+ private fun notIdentifier(filter : ElementFilter) = AndFilter(NOT_IDENTIFIER_FILTER, filter)
+
+ private fun getPlacePattern(placeFilter : ElementFilter) =
+ PlatformPatterns.psiElement().and(FilterPattern(AndFilter(GENERAL_FILTER, placeFilter)))
+
+ private open class CommentFilter() : ElementFilter {
+ override fun isAcceptable(element : Any?, context : PsiElement?) : Boolean {
+ return (element is PsiElement) && JetPsiUtil.isInComment(element as PsiElement)
}
- return JetPsiUtil.isInComment((PsiElement) element);
+ override fun isClassAcceptable(hintClass: Class?): Boolean = true
}
- @Override
- public boolean isClassAcceptable(Class hintClass) {
- return true;
- }
- }
-
- private static class ParentFilter extends PositionElementFilter {
- public ParentFilter(ElementFilter filter) {
- setFilter(filter);
- }
-
- @Override
- public boolean isAcceptable(Object element, PsiElement context) {
- if (!(element instanceof PsiElement)) {
- return false;
- }
- PsiElement parent = ((PsiElement) element).getParent();
- return parent != null && getFilter().isAcceptable(parent, context);
- }
- }
-
- private static class InTopFilter extends PositionElementFilter {
- @Override
- public boolean isAcceptable(Object element, PsiElement context) {
- //noinspection unchecked
- return PsiTreeUtil.getParentOfType(context, JetFile.class, false, JetClass.class, JetClassBody.class, JetBlockExpression.class,
- JetFunction.class) != null &&
- PsiTreeUtil.getParentOfType(context, JetParameterList.class, JetTypeParameterList.class, JetClass.class) == null;
- }
- }
-
- private static class InNonClassBlockFilter extends PositionElementFilter {
- @Override
- public boolean isAcceptable(Object element, PsiElement context) {
- //noinspection unchecked
- return PsiTreeUtil.getParentOfType(context, JetBlockExpression.class, true, JetClassBody.class) != null;
- }
- }
-
- private static class InTypeParameterFirstChildFilter extends PositionElementFilter {
- @Override
- public boolean isAcceptable(Object element, PsiElement context) {
- JetTypeParameter typeParameterElement = PsiTreeUtil.getParentOfType(context, JetTypeParameter.class, true);
- if (typeParameterElement != null && PsiTreeUtil.isAncestor(typeParameterElement.getFirstChild(), context, false)) {
- return true;
+ private open class ParentFilter(filter : ElementFilter) : PositionElementFilter() {
+ {
+ setFilter(filter)
}
- return false;
- }
- }
-
- private static class InClassBodyFilter extends PositionElementFilter {
- @Override
- public boolean isAcceptable(Object element, PsiElement context) {
- //noinspection unchecked
- return PsiTreeUtil.getParentOfType(context, JetClassBody.class, true,
- JetBlockExpression.class, JetProperty.class, JetParameterList.class) != null;
- }
- }
-
- private static class AfterClassInClassBodyFilter extends InClassBodyFilter {
- @Override
- public boolean isAcceptable(Object element, PsiElement context) {
- if (super.isAcceptable(element, context)) {
- PsiElement ps = context.getPrevSibling();
- if (ps instanceof PsiWhiteSpace) {
- ps = ps.getPrevSibling();
- }
- if (ps instanceof LeafPsiElement) {
- return ((LeafPsiElement) ps).getElementType() == JetTokens.CLASS_KEYWORD;
- }
+ override fun isAcceptable(element : Any?, context : PsiElement?) : Boolean {
+ val parent = (element as? PsiElement)?.getParent()
+ return parent != null && (getFilter()?.isAcceptable(parent, context) ?: true)
}
- return false;
}
- }
- private static class InPropertyBodyFilter extends PositionElementFilter {
- private static boolean isAfterName(@NotNull JetProperty property, @NotNull PsiElement element) {
- for (PsiElement child = property.getFirstChild(); child != null; child = child.getNextSibling()) {
- if (PsiTreeUtil.isAncestor(child, element, false)) {
- break;
+ private open class InTopFilter() : PositionElementFilter() {
+ override fun isAcceptable(element : Any?, context : PsiElement?) : Boolean {
+ val underFile = PsiTreeUtil.getParentOfType(context, javaClass(), false,
+ javaClass(), javaClass(), javaClass(), javaClass()) != null
+
+ val notInDeclarationElement = PsiTreeUtil.getParentOfType(
+ context,
+ javaClass(), javaClass(), javaClass()) == null
+
+ return underFile && notInDeclarationElement
+ }
+ }
+
+ private open class InNonClassBlockFilter() : PositionElementFilter() {
+ override fun isAcceptable(element : Any?, context : PsiElement?) : Boolean {
+ return PsiTreeUtil.getParentOfType(context, javaClass(), true, javaClass()) != null
+ }
+ }
+
+ private open class InTypeParameterFirstChildFilter() : PositionElementFilter() {
+ override fun isAcceptable(element : Any?, context : PsiElement?) : Boolean {
+ val typeParameterElement = PsiTreeUtil.getParentOfType(context, javaClass(), 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(), true,
+ javaClass(),
+ javaClass(),
+ javaClass()) != null
+ }
+ }
+
+ private open class 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)
}
- if (child.getNode().getElementType() == IDENTIFIER) {
- return true;
- }
+ return false
+ }
+ }
+
+ private open class InPropertyBodyFilter() : PositionElementFilter() {
+ override fun isAcceptable(element: Any?, context: PsiElement?): Boolean {
+ if (!(element is PsiElement))
+ return false
+
+ val property = PsiTreeUtil.getParentOfType(context, javaClass(), false)
+ return property != null && isAfterName(property, (element as PsiElement))
}
- return false;
- }
+ private fun isAfterName(property : JetProperty, element : PsiElement) : Boolean {
+ var iterableChild = property.getFirstChild()
+ while (iterableChild != null) {
+ val child = iterableChild!!
- @Override
- public boolean isAcceptable(Object element, PsiElement context) {
- if (!(element instanceof PsiElement)) return false;
- JetProperty property = PsiTreeUtil.getParentOfType(context, JetProperty.class, false);
- return property != null && isAfterName(property, (PsiElement) element);
- }
- }
-
- private static class SimplePrefixMatcher extends PrefixMatcher {
- protected SimplePrefixMatcher(String prefix) {
- super(prefix);
- }
-
- @Override
- public boolean prefixMatches(@NotNull String name) {
- return StringUtil.startsWith(name, getPrefix());
- }
-
- @NotNull
- @Override
- public PrefixMatcher cloneWithPrefix(@NotNull String prefix) {
- return new SimplePrefixMatcher(prefix);
- }
- }
-
- private static class KeywordsCompletionProvider extends CompletionProvider {
- private final Collection elements;
- private final String debugName;
-
- public KeywordsCompletionProvider(Collection keywords) {
- debugName = StringUtil.join(Ordering.natural().sortedCopy(keywords), ", ");
- elements = Collections2.transform(keywords, new Function() {
- @Override
- public LookupElement apply(String keyword) {
- LookupElementBuilder lookupElementBuilder = LookupElementBuilder.create(keyword).bold();
-
- if (!FUNCTION_KEYWORDS.contains(keyword)) {
- return lookupElementBuilder.withInsertHandler(KEYWORDS_INSERT_HANDLER);
+ if (PsiTreeUtil.isAncestor(child, element, false)) {
+ break
}
- return lookupElementBuilder.withInsertHandler(JetFunctionInsertHandler.EMPTY_FUNCTION_HANDLER);
+ if (child.getNode()?.getElementType() == JetTokens.IDENTIFIER) {
+ return true
+ }
+
+ iterableChild = child.getNextSibling()
}
- });
- }
- @Override
- protected void addCompletions(
- @NotNull CompletionParameters parameters, ProcessingContext context,
- @NotNull CompletionResultSet result
- ) {
- WeigherPackage.addJetSorting(result, parameters)
- .withPrefixMatcher(new SimplePrefixMatcher(result.getPrefixMatcher().getPrefix()))
- .addAllElements(elements);
- }
-
- @Override
- public String toString() {
- return debugName;
- }
- }
-
- private class BunchKeywordRegister {
- private final MultiMap, JetToken> orFiltersToKeywords = MultiMap.create();
-
- void add(JetToken keyword, ElementFilter... filters) {
- HashSet filtersSet = Sets.newHashSet(filters);
- orFiltersToKeywords.putValue(filtersSet, keyword);
- }
-
- void registerAll() {
- for (Map.Entry, Collection> entry : orFiltersToKeywords.entrySet()) {
- ElementFilter[] filters = ArrayUtil.toObjectArray(entry.getKey(), ElementFilter.class);
- Collection tokens = entry.getValue();
- registerScopeKeywordsCompletion(new OrFilter(filters), tokens);
+ return false
}
}
+
+ private open class SimplePrefixMatcher(prefix : String) : PrefixMatcher(prefix) {
+ override fun prefixMatches(name : String) : Boolean = StringUtil.startsWith(name, getPrefix())
+ override fun cloneWithPrefix(prefix : String) : PrefixMatcher = SimplePrefixMatcher(prefix)
+ }
+
+ private inner class KeywordsCompletionProvider(keywords : Collection) : CompletionProvider() {
+ private val elements : Collection
+ private val debugName : String
+
+ {
+ debugName = keywords.sort().makeString(separator = ", ")
+
+ elements = keywords.map { keyword ->
+ val lookupElementBuilder = LookupElementBuilder.create(keyword).bold()
+
+ if (!JetKeywordCompletionContributor.FUNCTION_KEYWORDS.contains(keyword)) {
+ lookupElementBuilder.withInsertHandler(JetKeywordCompletionContributor.KEYWORDS_INSERT_HANDLER)
+ }
+ else {
+ lookupElementBuilder.withInsertHandler(JetFunctionInsertHandler.EMPTY_FUNCTION_HANDLER)
+ }
+ }
+ }
+
+ override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext?, result: CompletionResultSet) {
+ result.addJetSorting(parameters).withPrefixMatcher(SimplePrefixMatcher(result.getPrefixMatcher().getPrefix())).addAllElements(elements)
+ }
+
+ override fun toString() : String = debugName
+ }
}
}