a dedicated lookup item class for live templates in smart completion

This commit is contained in:
peter
2009-10-14 23:43:31 +01:00
parent 545a78a12f
commit 571343503d
5 changed files with 68 additions and 99 deletions
@@ -17,6 +17,9 @@ package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.guess.GuessManager;
import com.intellij.codeInsight.lookup.*;
import com.intellij.codeInsight.template.SmartCompletionContextType;
import com.intellij.codeInsight.template.impl.TemplateImpl;
import com.intellij.codeInsight.template.impl.TemplateSettings;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Computable;
import com.intellij.patterns.PsiJavaPatterns;
@@ -26,7 +29,10 @@ import static com.intellij.patterns.StandardPatterns.not;
import com.intellij.psi.*;
import com.intellij.psi.filters.ContextGetter;
import com.intellij.psi.filters.element.ExcludeDeclaredFilter;
import com.intellij.psi.filters.getters.*;
import com.intellij.psi.filters.getters.ClassLiteralGetter;
import com.intellij.psi.filters.getters.FilterGetter;
import com.intellij.psi.filters.getters.MembersGetter;
import com.intellij.psi.filters.getters.ThisGetter;
import com.intellij.psi.scope.BaseScopeProcessor;
import com.intellij.psi.scope.ElementClassFilter;
import com.intellij.psi.scope.util.PsiScopesUtil;
@@ -91,8 +97,10 @@ public class BasicExpressionCompletionContributor extends ExpressionSmartComplet
result.addElement(element);
}
for (final Object o : new TemplatesGetter().get(position, null)) {
result.addElement(LookupItemUtil.objectToLookupItem(o));
for (final TemplateImpl template : TemplateSettings.getInstance().getTemplates()) {
if (!template.isDeactivated() && template.getTemplateContext().isEnabled(new SmartCompletionContextType())) {
result.addElement(new SmartCompletionTemplateItem(template, position));
}
}
addKeyword(result, position, PsiKeyword.TRUE);
@@ -106,7 +114,7 @@ public class BasicExpressionCompletionContributor extends ExpressionSmartComplet
}
for (final PsiExpression expression : ThisGetter.getThisExpressionVariants(position)) {
result.addElement(LookupItemUtil.objectToLookupItem(expression));
result.addElement(new ExpressionLookupItem(expression));
}
}
@@ -40,7 +40,6 @@ import com.intellij.psi.filters.getters.ThrowsListGetter;
import com.intellij.psi.filters.types.AssignableFromFilter;
import com.intellij.psi.filters.types.AssignableGroupFilter;
import com.intellij.psi.filters.types.AssignableToFilter;
import com.intellij.psi.filters.types.ReturnTypeFilter;
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.javadoc.PsiDocTag;
@@ -188,8 +187,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
}
}
else if (INSIDE_TYPECAST_EXPRESSION.accepts(element)) {
final ReturnTypeFilter rfilter = new ReturnTypeFilter(new GeneratorFilter(AssignableToFilter.class, new CastTypeGetter()));
for (final LookupElement item : completeReference(element, reference, rfilter, false, parameters)) {
for (final LookupElement item : completeReference(element, reference, new GeneratorFilter(AssignableToFilter.class, new CastTypeGetter()), false, parameters)) {
result.addElement(item);
}
}
@@ -211,7 +209,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
final PsiType type = info.getType();
final boolean isVoid = PsiType.VOID.equals(type);
final AssignableFromFilter assignableFromFilter = new AssignableFromFilter(type);
final ElementFilter filter = new ReturnTypeFilter(new ElementFilter() {
final ElementFilter filter = new ElementFilter() {
public boolean isAcceptable(Object element, PsiElement context) {
if (isVoid) {
return element instanceof PsiMethod;
@@ -225,7 +223,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
}
return true;
}
});
};
final Consumer<LookupElement> consumer = new Consumer<LookupElement>() {
public void consume(final LookupElement lookupElement) {
@@ -0,0 +1,52 @@
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.lookup.LookupItem;
import com.intellij.codeInsight.lookup.TypedLookupItem;
import com.intellij.codeInsight.template.Template;
import com.intellij.codeInsight.template.impl.TemplateImpl;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiType;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
/**
* @author peter
*/
public class SmartCompletionTemplateItem extends LookupItem<Template> implements TypedLookupItem {
@NonNls private static final String PLACEHOLDER = "xxx";
private final PsiElement myContext;
public SmartCompletionTemplateItem(Template o, PsiElement context) {
super(o, o.getKey());
myContext = context;
}
public PsiType getType() {
final Template template = getObject();
String text = template.getTemplateText();
StringBuilder resultingText = new StringBuilder(text);
int segmentsCount = template.getSegmentsCount();
for (int j = segmentsCount - 1; j >= 0; j--) {
if (template.getSegmentName(j).equals(TemplateImpl.END)) {
continue;
}
int segmentOffset = template.getSegmentOffset(j);
resultingText.insert(segmentOffset, PLACEHOLDER);
}
try {
final PsiExpression templateExpression = JavaPsiFacade.getElementFactory(myContext.getProject()).createExpressionFromText(resultingText.toString(), myContext);
return templateExpression.getType();
}
catch (IncorrectOperationException e) { // can happen when text of the template does not form an expression
return null;
}
}
}
@@ -1,55 +0,0 @@
/*
* Copyright 2000-2009 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.
*/
package com.intellij.psi.filters.getters;
import com.intellij.codeInsight.completion.CompletionContext;
import com.intellij.codeInsight.template.SmartCompletionContextType;
import com.intellij.codeInsight.template.impl.TemplateContext;
import com.intellij.codeInsight.template.impl.TemplateImpl;
import com.intellij.codeInsight.template.impl.TemplateSettings;
import com.intellij.psi.PsiElement;
import com.intellij.psi.filters.ContextGetter;
import java.util.ArrayList;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: ik
* Date: 28.04.2003
* Time: 19:37:23
* To change this template use Options | File Templates.
*/
public class TemplatesGetter implements ContextGetter{
public Object[] get(PsiElement context, CompletionContext completionContext){
final List result = new ArrayList();
final TemplateSettings templateSettings = TemplateSettings.getInstance();
final TemplateImpl[] templates = templateSettings.getTemplates();
for (final TemplateImpl template : templates) {
if (template.isDeactivated()) continue;
final TemplateContext templateContext = template.getTemplateContext();
if (!templateContext.isEnabled(new SmartCompletionContextType())) {
continue;
}
result.add(template);
}
return result.toArray();
}
}
@@ -16,13 +16,10 @@
package com.intellij.psi.filters.types;
import com.intellij.codeInsight.template.Template;
import com.intellij.codeInsight.template.impl.TemplateImpl;
import com.intellij.psi.*;
import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ReflectionCache;
import org.jetbrains.annotations.NonNls;
/**
@@ -34,7 +31,7 @@ import org.jetbrains.annotations.NonNls;
*/
public class ReturnTypeFilter implements ElementFilter{
private final ElementFilter myFilter;
@NonNls private static final String PLACEHOLDER = "xxx";
public ReturnTypeFilter(ElementFilter filter){
myFilter = filter;
@@ -47,37 +44,6 @@ public class ReturnTypeFilter implements ElementFilter{
}
public boolean isAcceptable(Object element, PsiElement context){
PsiType type = null;
if(element instanceof TemplateImpl){
final TemplateImpl template = (TemplateImpl) element;
String text = template.getTemplateText();
StringBuilder resultingText = new StringBuilder(text);
int segmentsCount = template.getSegmentsCount();
for (int j = segmentsCount - 1; j >= 0; j--) {
if (template.getSegmentName(j).equals(TemplateImpl.END)) {
continue;
}
int segmentOffset = template.getSegmentOffset(j);
resultingText.insert(segmentOffset, PLACEHOLDER);
}
try {
final PsiExpression templateExpression =
JavaPsiFacade.getInstance(context.getProject()).getElementFactory().createExpressionFromText(resultingText.toString(), context);
type = templateExpression.getType();
}
catch (IncorrectOperationException e) { // can happen when text of the template does not form an expression
}
if(type == null) return false;
}
if(type != null){
return myFilter.isAcceptable(type, context);
}
return myFilter.isAcceptable(element, context);
}