mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
move code out of JavaSmartCompletionContributor to make it a bit more modular
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
|
||||
import com.intellij.codeInsight.lookup.TailTypeDecorator;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class CatchTypeProvider extends CompletionProvider<CompletionParameters> {
|
||||
static final ElementPattern<PsiElement> CATCH_CLAUSE_TYPE = psiElement().insideStarting(
|
||||
psiElement(PsiTypeElement.class).withParent(
|
||||
psiElement(PsiCatchSection.class)));
|
||||
|
||||
@Override
|
||||
protected void addCompletions(@NotNull final CompletionParameters parameters,
|
||||
final ProcessingContext context,
|
||||
@NotNull final CompletionResultSet result) {
|
||||
PsiTryStatement tryStatement = PsiTreeUtil.getParentOfType(parameters.getPosition(), PsiTryStatement.class);
|
||||
final PsiCodeBlock tryBlock = tryStatement == null ? null : tryStatement.getTryBlock();
|
||||
if (tryBlock == null) return;
|
||||
|
||||
final InheritorsHolder holder = new InheritorsHolder(result);
|
||||
|
||||
for (final PsiClassType type : ExceptionUtil.getThrownExceptions(tryBlock.getStatements())) {
|
||||
PsiClass typeClass = type.resolve();
|
||||
if (typeClass != null) {
|
||||
result.addElement(createCatchTypeVariant(tryBlock, type));
|
||||
holder.registerClass(typeClass);
|
||||
}
|
||||
}
|
||||
|
||||
final Collection<PsiClassType> expectedClassTypes = Collections.singletonList(JavaPsiFacade.getElementFactory(
|
||||
tryBlock.getProject()).createTypeByFQClassName(CommonClassNames.JAVA_LANG_THROWABLE));
|
||||
JavaInheritorsGetter.processInheritors(parameters, expectedClassTypes, result.getPrefixMatcher(), new Consumer<PsiType>() {
|
||||
@Override
|
||||
public void consume(PsiType type) {
|
||||
final PsiClass psiClass = type instanceof PsiClassType ? ((PsiClassType)type).resolve() : null;
|
||||
if (psiClass == null || psiClass instanceof PsiTypeParameter) return;
|
||||
|
||||
if (!holder.alreadyProcessed(psiClass)) {
|
||||
result.addElement(createCatchTypeVariant(tryBlock, (PsiClassType)type));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static LookupElement createCatchTypeVariant(PsiCodeBlock tryBlock, PsiClassType type) {
|
||||
return TailTypeDecorator.withTail(PsiTypeLookupItem.createLookupItem(type, tryBlock), TailType.HUMBLE_SPACE_BEFORE_WORD);
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.codeInsight.completion;
|
||||
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PsiJavaPatterns;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNameValuePair;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.filters.getters.ExpectedTypesGetter;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.patterns.StandardPatterns.or;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class ExpectedAnnotationsProvider extends CompletionProvider<CompletionParameters> {
|
||||
static final ElementPattern<PsiElement> ANNOTATION_ATTRIBUTE_VALUE = or(
|
||||
PsiJavaPatterns.psiElement().withParent(PsiNameValuePair.class),
|
||||
PsiJavaPatterns.psiElement().withSuperParent(2, PsiNameValuePair.class));
|
||||
|
||||
@Override
|
||||
public void addCompletions(@NotNull final CompletionParameters parameters,
|
||||
final ProcessingContext context,
|
||||
@NotNull final CompletionResultSet result) {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
|
||||
for (final PsiType type : ExpectedTypesGetter.getExpectedTypes(element, false)) {
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass != null && psiClass.isAnnotationType()) {
|
||||
result.addElement(AllClassesGetter.createLookupItem(psiClass, AnnotationInsertHandler.INSTANCE));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
-1
@@ -26,6 +26,8 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorModificationUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PatternCondition;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
@@ -43,10 +45,26 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
*/
|
||||
public class FunctionalExpressionCompletionProvider extends CompletionProvider<CompletionParameters> {
|
||||
static final ElementPattern<PsiElement> LAMBDA = psiElement().with(new PatternCondition<PsiElement>("LAMBDA_CONTEXT") {
|
||||
@Override
|
||||
public boolean accepts(@NotNull PsiElement element, ProcessingContext context) {
|
||||
return isLambdaContext(element);
|
||||
}});
|
||||
|
||||
private static boolean isLambdaContext(@NotNull PsiElement element) {
|
||||
final PsiElement rulezzRef = element.getParent();
|
||||
return rulezzRef != null &&
|
||||
rulezzRef instanceof PsiReferenceExpression &&
|
||||
((PsiReferenceExpression)rulezzRef).getQualifier() == null &&
|
||||
LambdaUtil.isValidLambdaContext(rulezzRef.getParent());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addCompletions(@NotNull CompletionParameters parameters,
|
||||
ProcessingContext context,
|
||||
@@ -55,7 +73,7 @@ public class FunctionalExpressionCompletionProvider extends CompletionProvider<C
|
||||
}
|
||||
|
||||
static List<LookupElement> getLambdaVariants(@NotNull CompletionParameters parameters, boolean prioritize) {
|
||||
if (!PsiUtil.isLanguageLevel8OrHigher(parameters.getOriginalFile())) return Collections.emptyList();
|
||||
if (!PsiUtil.isLanguageLevel8OrHigher(parameters.getOriginalFile()) || !isLambdaContext(parameters.getPosition())) return Collections.emptyList();
|
||||
|
||||
List<LookupElement> result = ContainerUtil.newArrayList();
|
||||
for (ExpectedTypeInfo expectedType : JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.getters.InstanceOfLeftPartTypeGetter;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class InstanceofTypeProvider extends CompletionProvider<CompletionParameters> {
|
||||
static final ElementPattern<PsiElement> AFTER_INSTANCEOF = psiElement().afterLeaf(PsiKeyword.INSTANCEOF);
|
||||
|
||||
@Override
|
||||
protected void addCompletions(@NotNull final CompletionParameters parameters,
|
||||
final ProcessingContext context,
|
||||
@NotNull final CompletionResultSet result) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final PsiType[] leftTypes = InstanceOfLeftPartTypeGetter.getLeftTypes(position);
|
||||
final Set<PsiClassType> expectedClassTypes = new LinkedHashSet<PsiClassType>();
|
||||
final Set<PsiClass> parameterizedTypes = new THashSet<PsiClass>();
|
||||
for (final PsiType type : leftTypes) {
|
||||
if (type instanceof PsiClassType) {
|
||||
final PsiClassType classType = (PsiClassType)type;
|
||||
if (!classType.isRaw()) {
|
||||
ContainerUtil.addIfNotNull(classType.resolve(), parameterizedTypes);
|
||||
}
|
||||
|
||||
expectedClassTypes.add(classType.rawType());
|
||||
}
|
||||
}
|
||||
|
||||
JavaInheritorsGetter
|
||||
.processInheritors(parameters, expectedClassTypes, result.getPrefixMatcher(), new Consumer<PsiType>() {
|
||||
@Override
|
||||
public void consume(PsiType type) {
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass == null || psiClass instanceof PsiTypeParameter) return;
|
||||
|
||||
//noinspection SuspiciousMethodCalls
|
||||
if (expectedClassTypes.contains(type)) return;
|
||||
|
||||
result.addElement(createInstanceofLookupElement(psiClass, parameterizedTypes));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static LookupElement createInstanceofLookupElement(PsiClass psiClass, Set<PsiClass> toWildcardInheritors) {
|
||||
final PsiTypeParameter[] typeParameters = psiClass.getTypeParameters();
|
||||
if (typeParameters.length > 0) {
|
||||
for (final PsiClass parameterizedType : toWildcardInheritors) {
|
||||
if (psiClass.isInheritor(parameterizedType, true)) {
|
||||
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
|
||||
final PsiWildcardType wildcard = PsiWildcardType.createUnbounded(psiClass.getManager());
|
||||
for (final PsiTypeParameter typeParameter : typeParameters) {
|
||||
substitutor = substitutor.put(typeParameter, wildcard);
|
||||
}
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(psiClass.getProject());
|
||||
return PsiTypeLookupItem.createLookupItem(factory.createType(psiClass, substitutor), psiClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new JavaPsiClassReferenceElement(psiClass);
|
||||
}
|
||||
}
|
||||
+3
-11
@@ -222,13 +222,11 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
final InheritorsHolder inheritors = new InheritorsHolder(result);
|
||||
if (JavaSmartCompletionContributor.IN_TYPE_ARGS.accepts(position)) {
|
||||
if (TypeArgumentCompletionProvider.IN_TYPE_ARGS.accepts(position)) {
|
||||
new TypeArgumentCompletionProvider(false, inheritors).addCompletions(parameters, new ProcessingContext(), result);
|
||||
}
|
||||
|
||||
if (JavaSmartCompletionContributor.LAMBDA.accepts(parameters.getPosition())) {
|
||||
result.addAllElements(FunctionalExpressionCompletionProvider.getLambdaVariants(parameters, true));
|
||||
}
|
||||
result.addAllElements(FunctionalExpressionCompletionProvider.getLambdaVariants(parameters, true));
|
||||
|
||||
PrefixMatcher matcher = result.getPrefixMatcher();
|
||||
if (JavaSmartCompletionContributor.AFTER_NEW.accepts(position)) {
|
||||
@@ -404,7 +402,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
return;
|
||||
}
|
||||
if (reference instanceof PsiLabelReference) {
|
||||
processLabelReference(result, (PsiLabelReference)reference);
|
||||
LabelReferenceCompletion.processLabelReference(result, (PsiLabelReference)reference);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -832,12 +830,6 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
return null;
|
||||
}
|
||||
|
||||
static void processLabelReference(CompletionResultSet result, PsiLabelReference ref) {
|
||||
for (String s : ref.getVariants()) {
|
||||
result.addElement(TailTypeDecorator.withTail(LookupElementBuilder.create(s), TailType.SEMICOLON));
|
||||
}
|
||||
}
|
||||
|
||||
private static class IndentingDecorator extends LookupElementDecorator<LookupElement> {
|
||||
public IndentingDecorator(LookupElement delegate) {
|
||||
super(delegate);
|
||||
|
||||
+23
-4
@@ -53,10 +53,10 @@ import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
import static com.intellij.patterns.StandardPatterns.string;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
@@ -132,6 +132,25 @@ public class JavaDocCompletionContributor extends CompletionContributor {
|
||||
return LookupItemUtil.objectToLookupItem(element);
|
||||
}
|
||||
});
|
||||
|
||||
extend(CompletionType.SMART, psiElement().inside(
|
||||
psiElement(PsiDocTag.class).withName(
|
||||
string().oneOf(PsiKeyword.THROWS, "exception"))), new CompletionProvider<CompletionParameters>() {
|
||||
@Override
|
||||
public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
final Set<PsiClass> throwsSet = new HashSet<PsiClass>();
|
||||
final PsiMethod method = PsiTreeUtil.getContextOfType(element, PsiMethod.class, true);
|
||||
if(method != null){
|
||||
for (PsiClassType ref : method.getThrowsList().getReferencedTypes()) {
|
||||
final PsiClass exception = ref.resolve();
|
||||
if (exception != null && throwsSet.add(exception)) {
|
||||
result.addElement(TailTypeDecorator.withTail(new JavaPsiClassReferenceElement(exception), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static PsiParameter getDocTagParam(PsiElement tag) {
|
||||
|
||||
+25
-204
@@ -15,43 +15,36 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInsight.*;
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.ExpectedTypeInfoImpl;
|
||||
import com.intellij.codeInsight.ExpectedTypesProvider;
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementDecorator;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PatternCondition;
|
||||
import com.intellij.patterns.PsiElementPattern;
|
||||
import com.intellij.patterns.PsiJavaPatterns;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.ElementExtractorFilter;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.psi.filters.OrFilter;
|
||||
import com.intellij.psi.filters.getters.ExpectedTypesGetter;
|
||||
import com.intellij.psi.filters.getters.InstanceOfLeftPartTypeGetter;
|
||||
import com.intellij.psi.filters.getters.JavaMembersGetter;
|
||||
import com.intellij.psi.filters.types.AssignableFromFilter;
|
||||
import com.intellij.psi.filters.types.AssignableToFilter;
|
||||
import com.intellij.psi.impl.source.PsiLabelReference;
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.javadoc.PsiDocTag;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiMethod;
|
||||
import static com.intellij.patterns.StandardPatterns.*;
|
||||
import static com.intellij.patterns.StandardPatterns.or;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -70,7 +63,6 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
};
|
||||
|
||||
private static final ElementExtractorFilter THROWABLES_FILTER = new ElementExtractorFilter(new AssignableFromFilter(CommonClassNames.JAVA_LANG_THROWABLE));
|
||||
@NonNls private static final String EXCEPTION_TAG = "exception";
|
||||
public static final ElementPattern<PsiElement> AFTER_NEW =
|
||||
psiElement().afterLeaf(
|
||||
psiElement().withText(PsiKeyword.NEW).andNot(
|
||||
@@ -86,32 +78,19 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
static final ElementPattern<PsiElement> INSIDE_TYPECAST_EXPRESSION = psiElement().withParent(
|
||||
psiElement(PsiReferenceExpression.class).afterLeaf(
|
||||
psiElement().withText(")").withParent(PsiTypeCastExpression.class)));
|
||||
static final PsiElementPattern.Capture<PsiElement> IN_TYPE_ARGS =
|
||||
psiElement().inside(psiElement(PsiReferenceParameterList.class));
|
||||
static final PsiElementPattern.Capture<PsiElement> LAMBDA = psiElement().with(new PatternCondition<PsiElement>("LAMBDA_CONTEXT") {
|
||||
@Override
|
||||
public boolean accepts(@NotNull PsiElement element, ProcessingContext context) {
|
||||
final PsiElement rulezzRef = element.getParent();
|
||||
return rulezzRef != null &&
|
||||
rulezzRef instanceof PsiReferenceExpression &&
|
||||
((PsiReferenceExpression)rulezzRef).getQualifier() == null &&
|
||||
LambdaUtil.isValidLambdaContext(rulezzRef.getParent());
|
||||
}});
|
||||
|
||||
static final PsiElementPattern.Capture<PsiElement> METHOD_REFERENCE = psiElement().with(new PatternCondition<PsiElement>("METHOD_REFERENCE_CONTEXT") {
|
||||
@Override
|
||||
public boolean accepts(@NotNull PsiElement element, ProcessingContext context) {
|
||||
final PsiElement rulezzRef = element.getParent();
|
||||
return rulezzRef != null &&
|
||||
LambdaUtil.isValidLambdaContext(rulezzRef.getParent());
|
||||
}});
|
||||
|
||||
@Nullable
|
||||
private static ElementFilter getReferenceFilter(PsiElement element) {
|
||||
private static ElementFilter getClassReferenceFilter(PsiElement element) {
|
||||
//throw new foo
|
||||
if (AFTER_THROW_NEW.accepts(element)) {
|
||||
return THROWABLES_FILTER;
|
||||
}
|
||||
|
||||
//throws list
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
|
||||
if (method != null && PsiTreeUtil.isAncestor(method.getThrowsList(), element, true)) {
|
||||
return THROWABLES_FILTER;
|
||||
}
|
||||
|
||||
//new xxx.yyy
|
||||
if (psiElement().afterLeaf(psiElement().withText(".")).withSuperParent(2, psiElement(PsiNewExpression.class)).accepts(element)) {
|
||||
@@ -138,39 +117,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
|
||||
extend(CompletionType.SMART, MethodReturnTypeProvider.IN_METHOD_RETURN_TYPE, new MethodReturnTypeProvider());
|
||||
|
||||
extend(CompletionType.SMART, psiElement().afterLeaf(PsiKeyword.INSTANCEOF), new CompletionProvider<CompletionParameters>() {
|
||||
@Override
|
||||
protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final PsiType[] leftTypes = InstanceOfLeftPartTypeGetter.getLeftTypes(position);
|
||||
final Set<PsiClassType> expectedClassTypes = new LinkedHashSet<PsiClassType>();
|
||||
final Set<PsiClass> parameterizedTypes = new THashSet<PsiClass>();
|
||||
for (final PsiType type : leftTypes) {
|
||||
if (type instanceof PsiClassType) {
|
||||
final PsiClassType classType = (PsiClassType)type;
|
||||
if (!classType.isRaw()) {
|
||||
ContainerUtil.addIfNotNull(classType.resolve(), parameterizedTypes);
|
||||
}
|
||||
|
||||
expectedClassTypes.add(classType.rawType());
|
||||
}
|
||||
}
|
||||
|
||||
JavaInheritorsGetter
|
||||
.processInheritors(parameters, expectedClassTypes, result.getPrefixMatcher(), new Consumer<PsiType>() {
|
||||
@Override
|
||||
public void consume(PsiType type) {
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass == null || psiClass instanceof PsiTypeParameter) return;
|
||||
|
||||
//noinspection SuspiciousMethodCalls
|
||||
if (expectedClassTypes.contains(type)) return;
|
||||
|
||||
result.addElement(createInstanceofLookupElement(psiClass, parameterizedTypes));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
extend(CompletionType.SMART, InstanceofTypeProvider.AFTER_INSTANCEOF, new InstanceofTypeProvider());
|
||||
|
||||
extend(CompletionType.SMART, psiElement(), new CompletionProvider<CompletionParameters>() {
|
||||
@Override
|
||||
@@ -180,7 +127,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
final PsiReference reference = element.getContainingFile().findReferenceAt(parameters.getOffset());
|
||||
if (reference != null) {
|
||||
ElementFilter filter = getReferenceFilter(element);
|
||||
ElementFilter filter = getClassReferenceFilter(element);
|
||||
if (filter != null) {
|
||||
final List<ExpectedTypeInfo> infos = Arrays.asList(getExpectedTypes(parameters));
|
||||
for (final LookupElement item : completeReference(element, reference, filter, true, false, parameters, result.getPrefixMatcher())) {
|
||||
@@ -203,23 +150,6 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
});
|
||||
|
||||
//method throws clause
|
||||
extend(CompletionType.SMART, psiElement().inside(
|
||||
psiElement(PsiReferenceList.class).save("refList").withParent(
|
||||
psiMethod().withThrowsList(get("refList")))), new CompletionProvider<CompletionParameters>() {
|
||||
@Override
|
||||
protected void addCompletions(@NotNull CompletionParameters parameters,
|
||||
ProcessingContext context,
|
||||
@NotNull CompletionResultSet result) {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
final PsiReference reference = element.getContainingFile().findReferenceAt(parameters.getOffset());
|
||||
assert reference != null;
|
||||
for (final LookupElement item : completeReference(element, reference, THROWABLES_FILTER, true, false, parameters, result.getPrefixMatcher())) {
|
||||
result.addElement(item);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
extend(CompletionType.SMART, INSIDE_EXPRESSION, new ExpectedTypeBasedCompletionProvider() {
|
||||
@Override
|
||||
protected void addCompletions(final CompletionParameters params, final CompletionResultSet result, final Collection<ExpectedTypeInfo> _infos) {
|
||||
@@ -245,12 +175,9 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
BasicExpressionCompletionContributor.fillCompletionVariants(new JavaSmartCompletionParameters(params, info), new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement lookupElement) {
|
||||
final TypedLookupItem typed = lookupElement.as(TypedLookupItem.CLASS_CONDITION_KEY);
|
||||
if (typed != null) {
|
||||
final PsiType psiType = typed.getType();
|
||||
if (psiType != null && info.getType().isAssignableFrom(psiType)) {
|
||||
result.addElement(decorate(lookupElement, _infos));
|
||||
}
|
||||
final PsiType psiType = JavaCompletionUtil.getLookupElementType(lookupElement);
|
||||
if (psiType != null && info.getType().isAssignableFrom(psiType)) {
|
||||
result.addElement(decorate(lookupElement, _infos));
|
||||
}
|
||||
}
|
||||
}, result.getPrefixMatcher());
|
||||
@@ -269,103 +196,18 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
});
|
||||
|
||||
extend(CompletionType.SMART, or(
|
||||
PsiJavaPatterns.psiElement().withParent(PsiNameValuePair.class),
|
||||
PsiJavaPatterns.psiElement().withSuperParent(2, PsiNameValuePair.class)), new CompletionProvider<CompletionParameters>() {
|
||||
@Override
|
||||
public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
extend(CompletionType.SMART, ExpectedAnnotationsProvider.ANNOTATION_ATTRIBUTE_VALUE, new ExpectedAnnotationsProvider());
|
||||
|
||||
for (final PsiType type : ExpectedTypesGetter.getExpectedTypes(element, false)) {
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass != null && psiClass.isAnnotationType()) {
|
||||
result.addElement(AllClassesGetter.createLookupItem(psiClass, AnnotationInsertHandler.INSTANCE));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
extend(CompletionType.SMART, psiElement().inside(
|
||||
psiElement(PsiDocTag.class).withName(
|
||||
string().oneOf(PsiKeyword.THROWS, EXCEPTION_TAG))), new CompletionProvider<CompletionParameters>() {
|
||||
@Override
|
||||
public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
final Set<PsiClass> throwsSet = new HashSet<PsiClass>();
|
||||
final PsiMethod method = PsiTreeUtil.getContextOfType(element, PsiMethod.class, true);
|
||||
if(method != null){
|
||||
for (PsiClassType ref : method.getThrowsList().getReferencedTypes()) {
|
||||
final PsiClass exception = ref.resolve();
|
||||
if (exception != null && throwsSet.add(exception)) {
|
||||
result.addElement(TailTypeDecorator.withTail(new JavaPsiClassReferenceElement(exception), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
final Key<PsiTryStatement> tryKey = Key.create("try");
|
||||
extend(CompletionType.SMART, psiElement().insideStarting(
|
||||
psiElement(PsiTypeElement.class).withParent(
|
||||
psiElement(PsiCatchSection.class).withParent(
|
||||
psiElement(PsiTryStatement.class).save(tryKey)))), new CompletionProvider<CompletionParameters>() {
|
||||
@Override
|
||||
protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
final PsiCodeBlock tryBlock = context.get(tryKey).getTryBlock();
|
||||
if (tryBlock == null) return;
|
||||
|
||||
final InheritorsHolder holder = new InheritorsHolder(result);
|
||||
|
||||
for (final PsiClassType type : ExceptionUtil.getThrownExceptions(tryBlock.getStatements())) {
|
||||
PsiClass typeClass = type.resolve();
|
||||
if (typeClass != null) {
|
||||
result.addElement(createCatchTypeVariant(tryBlock, type));
|
||||
holder.registerClass(typeClass);
|
||||
}
|
||||
}
|
||||
|
||||
final Collection<PsiClassType> expectedClassTypes = ContainerUtil.createMaybeSingletonList(JavaPsiFacade.getElementFactory(
|
||||
tryBlock.getProject()).createTypeByFQClassName(CommonClassNames.JAVA_LANG_THROWABLE));
|
||||
JavaInheritorsGetter.processInheritors(parameters, expectedClassTypes, result.getPrefixMatcher(), new Consumer<PsiType>() {
|
||||
@Override
|
||||
public void consume(PsiType type) {
|
||||
final PsiClass psiClass = type instanceof PsiClassType ? ((PsiClassType)type).resolve() : null;
|
||||
if (psiClass == null || psiClass instanceof PsiTypeParameter) return;
|
||||
|
||||
if (!holder.alreadyProcessed(psiClass)) {
|
||||
result.addElement(createCatchTypeVariant(tryBlock, (PsiClassType)type));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private LookupElement createCatchTypeVariant(PsiCodeBlock tryBlock, PsiClassType type) {
|
||||
return TailTypeDecorator.withTail(PsiTypeLookupItem.createLookupItem(type, tryBlock), TailType.HUMBLE_SPACE_BEFORE_WORD);
|
||||
}
|
||||
});
|
||||
|
||||
extend(CompletionType.SMART, IN_TYPE_ARGS, new TypeArgumentCompletionProvider(true, null));
|
||||
extend(CompletionType.SMART, CatchTypeProvider.CATCH_CLAUSE_TYPE, new CatchTypeProvider());
|
||||
|
||||
extend(CompletionType.SMART, TypeArgumentCompletionProvider.IN_TYPE_ARGS, new TypeArgumentCompletionProvider(true, null));
|
||||
|
||||
extend(CompletionType.SMART, AFTER_NEW, new JavaInheritorsGetter(ConstructorInsertHandler.SMART_INSTANCE));
|
||||
|
||||
extend(CompletionType.SMART, psiElement().afterLeaf(PsiKeyword.BREAK, PsiKeyword.CONTINUE), new CompletionProvider<CompletionParameters>() {
|
||||
@Override
|
||||
protected void addCompletions(@NotNull CompletionParameters parameters,
|
||||
ProcessingContext context,
|
||||
@NotNull CompletionResultSet result) {
|
||||
PsiReference ref = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset());
|
||||
if (ref instanceof PsiLabelReference) {
|
||||
JavaCompletionContributor.processLabelReference(result, (PsiLabelReference)ref);
|
||||
}
|
||||
}
|
||||
});
|
||||
extend(CompletionType.SMART, LabelReferenceCompletion.LABEL_REFERENCE, new LabelReferenceCompletion());
|
||||
|
||||
extend(CompletionType.SMART, LAMBDA, new FunctionalExpressionCompletionProvider());
|
||||
extend(CompletionType.SMART, METHOD_REFERENCE, new MethodReferenceCompletionProvider());
|
||||
extend(CompletionType.SMART, psiElement(), new FunctionalExpressionCompletionProvider());
|
||||
extend(CompletionType.SMART, psiElement(), new MethodReferenceCompletionProvider());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -402,27 +244,6 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
return new SmartCompletionDecorator(lookupElement, infos);
|
||||
}
|
||||
|
||||
private static LookupElement createInstanceofLookupElement(PsiClass psiClass, Set<PsiClass> toWildcardInheritors) {
|
||||
final PsiTypeParameter[] typeParameters = psiClass.getTypeParameters();
|
||||
if (typeParameters.length > 0) {
|
||||
for (final PsiClass parameterizedType : toWildcardInheritors) {
|
||||
if (psiClass.isInheritor(parameterizedType, true)) {
|
||||
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
|
||||
final PsiWildcardType wildcard = PsiWildcardType.createUnbounded(psiClass.getManager());
|
||||
for (final PsiTypeParameter typeParameter : typeParameters) {
|
||||
substitutor = substitutor.put(typeParameter, wildcard);
|
||||
}
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(psiClass.getProject());
|
||||
return PsiTypeLookupItem.createLookupItem(factory.createType(psiClass, substitutor), psiClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new JavaPsiClassReferenceElement(psiClass);
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public static ExpectedTypeInfo[] getExpectedTypes(final CompletionParameters parameters) {
|
||||
return getExpectedTypes(parameters, parameters.getCompletionType() == CompletionType.SMART);
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.codeInsight.lookup.TailTypeDecorator;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiKeyword;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.impl.source.PsiLabelReference;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class LabelReferenceCompletion extends CompletionProvider<CompletionParameters> {
|
||||
static final ElementPattern<PsiElement> LABEL_REFERENCE = psiElement().afterLeaf(PsiKeyword.BREAK, PsiKeyword.CONTINUE);
|
||||
|
||||
static void processLabelReference(CompletionResultSet result, PsiLabelReference ref) {
|
||||
for (String s : ref.getVariants()) {
|
||||
result.addElement(TailTypeDecorator.withTail(LookupElementBuilder.create(s), TailType.SEMICOLON));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addCompletions(@NotNull CompletionParameters parameters,
|
||||
ProcessingContext context,
|
||||
@NotNull CompletionResultSet result) {
|
||||
PsiReference ref = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset());
|
||||
if (ref instanceof PsiLabelReference) {
|
||||
processLabelReference(result, (PsiLabelReference)ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
@@ -40,6 +40,10 @@ public class MethodReferenceCompletionProvider extends CompletionProvider<Comple
|
||||
ProcessingContext context,
|
||||
@NotNull final CompletionResultSet result) {
|
||||
if (!PsiUtil.isLanguageLevel8OrHigher(parameters.getOriginalFile())) return;
|
||||
|
||||
final PsiElement rulezzRef = parameters.getPosition().getParent();
|
||||
if (rulezzRef == null || !LambdaUtil.isValidLambdaContext(rulezzRef.getParent())) return;
|
||||
|
||||
final ExpectedTypeInfo[] expectedTypes = JavaSmartCompletionContributor.getExpectedTypes(parameters);
|
||||
for (ExpectedTypeInfo expectedType : expectedTypes) {
|
||||
final PsiType defaultType = expectedType.getDefaultType();
|
||||
|
||||
+2
@@ -27,6 +27,7 @@ import com.intellij.codeInsight.lookup.TailTypeDecorator;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -48,6 +49,7 @@ import static com.intellij.patterns.PsiJavaPatterns.psiElement;
|
||||
* @author peter
|
||||
*/
|
||||
class TypeArgumentCompletionProvider extends CompletionProvider<CompletionParameters> {
|
||||
static final ElementPattern<PsiElement> IN_TYPE_ARGS = psiElement().inside(PsiReferenceParameterList.class);
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.TypeArgumentCompletionProvider");
|
||||
private final boolean mySmart;
|
||||
@Nullable private final InheritorsHolder myInheritors;
|
||||
|
||||
Reference in New Issue
Block a user