Disable keyword completion in comments, strings and chars

This commit is contained in:
Nikolay Krasko
2011-12-29 15:08:42 +04:00
parent 0f6fd27bef
commit be40b01d0e
7 changed files with 158 additions and 12 deletions
@@ -3,18 +3,17 @@ package org.jetbrains.jet.plugin.completion;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.Collections2; import com.google.common.collect.Collections2;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.intellij.codeInsight.CommentUtil;
import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.patterns.ElementPattern; import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PlatformPatterns; import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.filters.AndFilter; import com.intellij.psi.filters.*;
import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.filters.NotFilter;
import com.intellij.psi.filters.TextFilter;
import com.intellij.psi.filters.position.FilterPattern; import com.intellij.psi.filters.position.FilterPattern;
import com.intellij.psi.filters.position.LeftNeighbour; import com.intellij.psi.filters.position.LeftNeighbour;
import com.intellij.psi.filters.position.PositionElementFilter;
import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ProcessingContext; import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -36,11 +35,50 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
private final static InsertHandler<LookupElement> FUNCTION_INSERT_HANDLER = new JetFunctionInsertHandler( private final static InsertHandler<LookupElement> FUNCTION_INSERT_HANDLER = new JetFunctionInsertHandler(
JetFunctionInsertHandler.CaretPosition.AFTER_BRACKETS); JetFunctionInsertHandler.CaretPosition.AFTER_BRACKETS);
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("."))
));
private final static List<String> FUNCTION_KEYWORDS = Lists.newArrayList("get", "set"); private final static List<String> FUNCTION_KEYWORDS = Lists.newArrayList("get", "set");
private static class CommentFilter implements ElementFilter {
@Override
public boolean isAcceptable(Object element, PsiElement context) {
if (!(element instanceof PsiElement)) {
return false;
}
return CommentUtil.isComment((PsiElement) element);
}
@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 implements ElementFilter { private static class InTopFilter implements ElementFilter {
@Override @Override
public boolean isAcceptable(Object element, PsiElement context) { public boolean isAcceptable(Object element, PsiElement context) {
//noinspection unchecked
return PsiTreeUtil.getParentOfType(context, JetFile.class, false, JetClass.class, JetFunction.class) != null; return PsiTreeUtil.getParentOfType(context, JetFile.class, false, JetClass.class, JetFunction.class) != null;
} }
@@ -53,8 +91,8 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
private static class InNonClassBlockFilter implements ElementFilter { private static class InNonClassBlockFilter implements ElementFilter {
@Override @Override
public boolean isAcceptable(Object element, PsiElement context) { public boolean isAcceptable(Object element, PsiElement context) {
return PsiTreeUtil.getParentOfType(context, JetFunction.class, true, JetClass.class) != null && //noinspection unchecked
PsiTreeUtil.getParentOfType(context, JetBlockExpression.class, true, JetFunction.class) != null; return PsiTreeUtil.getParentOfType(context, JetBlockExpression.class, true, JetClassBody.class) != null;
} }
@Override @Override
@@ -78,7 +116,8 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
private static class InClassBodyFilter implements ElementFilter { private static class InClassBodyFilter implements ElementFilter {
@Override @Override
public boolean isAcceptable(Object element, PsiElement context) { public boolean isAcceptable(Object element, PsiElement context) {
return PsiTreeUtil.getParentOfType(context, JetClassBody.class, true, JetFunction.class) != null; //noinspection unchecked
return PsiTreeUtil.getParentOfType(context, JetClassBody.class, true, JetBlockExpression.class) != null;
} }
@Override @Override
@@ -126,8 +165,6 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
} }
} }
public JetKeywordCompletionContributor() { public JetKeywordCompletionContributor() {
registerScopeKeywordsCompletion(new InTopFilter(), registerScopeKeywordsCompletion(new InTopFilter(),
"abstract", "class", "enum", "final", "fun", "get", "import", "inline", "abstract", "class", "enum", "final", "fun", "get", "import", "inline",
@@ -135,7 +172,7 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
"trait", "type", "val", "var"); "trait", "type", "val", "var");
registerScopeKeywordsCompletion(new InClassBodyFilter(), registerScopeKeywordsCompletion(new InClassBodyFilter(),
"abstract", "class", "enum", "final", "fun", "inline", "internal", "get", "abstract", "class", "enum", "final", "fun", "get", "inline", "internal",
"open", "override", "private", "protected", "public", "set", "trait", "open", "override", "private", "protected", "public", "set", "trait",
"type", "val", "var"); "type", "val", "var");
@@ -157,6 +194,6 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
private static ElementPattern<PsiElement> getPlacePattern(final ElementFilter placeFilter) { private static ElementPattern<PsiElement> getPlacePattern(final ElementFilter placeFilter) {
return PlatformPatterns.psiElement().and( return PlatformPatterns.psiElement().and(
new FilterPattern(new AndFilter(new NotFilter(new LeftNeighbour(new TextFilter("."))), placeFilter))); new FilterPattern(new AndFilter(GENERAL_FILTER, placeFilter)));
} }
} }
@@ -0,0 +1,12 @@
class TestClass {
/* <caret> */
fun test() {
'<caret>'
}
}
// ABSENT: abstract, annotation, as, break, by, catch, class, continue, default, do
// ABSENT: else, enum, false, final, finally, for, fun, get, if, import, in, inline
// 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
@@ -0,0 +1,11 @@
class TestClass {
fun test() {
'<caret>'
}
}
// ABSENT: abstract, annotation, as, break, by, catch, class, continue, default, do
// ABSENT: else, enum, false, final, finally, for, fun, get, if, import, in, inline
// 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
@@ -0,0 +1,59 @@
public class Test {
<caret>
fun test() {
}
}
// EXIST: abstract
// ?ABSENT: annotation
// ABSENT: as
// ABSENT: break
// ABSENT: by
// ABSENT: catch
// 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: inline
// EXIST: internal
// ABSENT: is
// ABSENT: null
// ABSENT: object
// EXIST: open
// ABSENT: out
// 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: type
// EXIST: val
// EXIST: var
// ABSENT: vararg
// ABSENT: when
// ABSENT: where
// ABSENT: while
@@ -0,0 +1,11 @@
class TestClass {
fun test() {
"<caret>"
}
}
// ABSENT: abstract, annotation, as, break, by, catch, class, continue, default, do
// ABSENT: else, enum, false, final, finally, for, fun, get, if, import, in, inline
// 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
@@ -0,0 +1,9 @@
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, inline
// 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
@@ -0,0 +1,7 @@
class Some {
val a : Int
<caret>
}
// EXIST: get
// EXIST: set