@Nullable static ElementFilter recursionFilter(PsiElement element) { if (PsiJavaPatterns.psiElement().afterLeaf(PsiKeyword.RETURN).inside(PsiReturnStatement.class).accepts(element)) { return new ExcludeDeclaredFilter(ElementClassFilter.METHOD); } if (PsiJavaPatterns.psiElement().inside( StandardPatterns.or( PsiJavaPatterns.psiElement(PsiAssignmentExpression.class), PsiJavaPatterns.psiElement(PsiVariable.class))). andNot(PsiJavaPatterns.psiElement().afterLeaf(".")).accepts(element)) { return new AndFilter(new ExcludeSillyAssignment(), new ExcludeDeclaredFilter(new ClassFilter(PsiVariable.class))); } return null; }
private static ElementFilter createAnnotationFilter(PsiElement position) { OrFilter orFilter = new OrFilter(ElementClassFilter.CLASS, ElementClassFilter.PACKAGE_FILTER, new AndFilter(new ClassFilter(PsiField.class), new ModifierFilter(PsiModifier.STATIC, PsiModifier.FINAL))); if(psiElement().insideStarting(psiNameValuePair()).accepts(position)) { orFilter.addFilter(new ClassFilter(PsiAnnotationMethod.class) { @Override public boolean isAcceptable(Object element, PsiElement context) { return element instanceof PsiAnnotationMethod && PsiUtil.isAnnotationMethod((PsiElement) element); } }); } return orFilter; }
@Override @NotNull public Object[] getVariants() { final ElementFilter filter; switch (getKind(getContainingFile())) { case CLASS_OR_PACKAGE_NAME_KIND: filter = new OrFilter(); ((OrFilter)filter).addFilter(ElementClassFilter.CLASS); ((OrFilter)filter).addFilter(ElementClassFilter.PACKAGE_FILTER); break; case CLASS_NAME_KIND: filter = ElementClassFilter.CLASS; break; case PACKAGE_NAME_KIND: filter = ElementClassFilter.PACKAGE_FILTER; break; case CLASS_FQ_NAME_KIND: case CLASS_FQ_OR_PACKAGE_NAME_KIND: filter = new OrFilter(); ((OrFilter)filter).addFilter(ElementClassFilter.PACKAGE_FILTER); if (isQualified()) { ((OrFilter)filter).addFilter(ElementClassFilter.CLASS); } break; case CLASS_IN_QUALIFIED_NEW_KIND: filter = ElementClassFilter.CLASS; break; default: throw new RuntimeException("Unknown reference type"); } return PsiImplUtil.getReferenceVariantsByFilter(this, filter); }
@Override public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent, @NotNull PsiElement place) { if (lastParent == null) return true; final PsiSwitchStatement switchStatement = getEnclosingSwitchStatement(); if (switchStatement != null) { final PsiExpression expression = switchStatement.getExpression(); if (expression != null && expression.getType() instanceof PsiClassType) { final PsiClass aClass = ((PsiClassType)expression.getType()).resolve(); if(aClass != null) aClass.processDeclarations(new FilterScopeProcessor(ElementClassFilter.ENUM_CONST, processor), state, this, place); } } return true; }
private static ElementFilter createAnnotationFilter(PsiElement position) { OrFilter orFilter = new OrFilter(ElementClassFilter.CLASS, ElementClassFilter.PACKAGE_FILTER, new AndFilter(new ClassFilter(PsiField.class), new ModifierFilter(PsiModifier.STATIC, PsiModifier.FINAL))); if (psiElement().insideStarting(psiNameValuePair()).accepts(position)) { orFilter.addFilter(new ClassFilter(PsiAnnotationMethod.class) { @Override public boolean isAcceptable(Object element, PsiElement context) { return element instanceof PsiAnnotationMethod && PsiUtil.isAnnotationMethod((PsiElement)element); } }); } return orFilter; }
@NotNull private static MembersMap buildAllMaps(@NotNull PsiClass psiClass) { final List<Pair<PsiMember, PsiSubstitutor>> classes = new ArrayList<Pair<PsiMember, PsiSubstitutor>>(); final List<Pair<PsiMember, PsiSubstitutor>> fields = new ArrayList<Pair<PsiMember, PsiSubstitutor>>(); final List<Pair<PsiMember, PsiSubstitutor>> methods = new ArrayList<Pair<PsiMember, PsiSubstitutor>>(); FilterScopeProcessor<MethodCandidateInfo> processor = new FilterScopeProcessor<MethodCandidateInfo>( new OrFilter(ElementClassFilter.METHOD, ElementClassFilter.FIELD, ElementClassFilter.CLASS)) { @Override protected void add(PsiElement element, PsiSubstitutor substitutor) { if (element instanceof PsiMethod) { methods.add(Pair.create((PsiMember)element, substitutor)); } else if (element instanceof PsiField) { fields.add(Pair.create((PsiMember)element, substitutor)); } else if (element instanceof PsiClass) { classes.add(Pair.create((PsiMember)element, substitutor)); } } }; processDeclarationsInClassNotCached(psiClass, processor, ResolveState.initial(), null, null, psiClass, false, PsiUtil.getLanguageLevel(psiClass)); MembersMap result = new MembersMap(MemberType.class); result.put(MemberType.CLASS, generateMapByList(classes)); result.put(MemberType.METHOD, generateMapByList(methods)); result.put(MemberType.FIELD, generateMapByList(fields)); return result; }
@Override @NotNull public Object[] getVariants() { final ElementFilter filter; switch (getKind()) { case CLASS_OR_PACKAGE_NAME_KIND: filter = new OrFilter(); ((OrFilter)filter).addFilter(ElementClassFilter.CLASS); ((OrFilter)filter).addFilter(ElementClassFilter.PACKAGE_FILTER); break; case CLASS_NAME_KIND: filter = ElementClassFilter.CLASS; break; case PACKAGE_NAME_KIND: filter = ElementClassFilter.PACKAGE_FILTER; break; case CLASS_FQ_NAME_KIND: case CLASS_FQ_OR_PACKAGE_NAME_KIND: filter = new OrFilter(); ((OrFilter)filter).addFilter(ElementClassFilter.PACKAGE_FILTER); if (isQualified()) { ((OrFilter)filter).addFilter(ElementClassFilter.CLASS); } break; case CLASS_IN_QUALIFIED_NEW_KIND: filter = ElementClassFilter.CLASS; break; default: throw new RuntimeException("Unknown reference type"); } return PsiImplUtil.getReferenceVariantsByFilter(this, filter); }
@Nullable static ElementFilter recursionFilter(PsiElement element) { if(PsiJavaPatterns.psiElement().afterLeaf(PsiKeyword.RETURN).inside(PsiReturnStatement.class).accepts(element)) { return new ExcludeDeclaredFilter(ElementClassFilter.METHOD); } if(PsiJavaPatterns.psiElement().inside(StandardPatterns.or(PsiJavaPatterns.psiElement(PsiAssignmentExpression.class), PsiJavaPatterns.psiElement(PsiVariable.class))). andNot(PsiJavaPatterns.psiElement().afterLeaf(".")).accepts(element)) { return new AndFilter(new ExcludeSillyAssignment(), new ExcludeDeclaredFilter(new ClassFilter(PsiVariable.class))); } return null; }
@Nullable @Override protected Map<String, List<Pair<PsiMember, PsiSubstitutor>>> create(final MemberType key) { final Map<String, List<Pair<PsiMember, PsiSubstitutor>>> map = new THashMap<String, List<Pair<PsiMember, PsiSubstitutor>>>(); final List<Pair<PsiMember, PsiSubstitutor>> allMembers = new ArrayList<Pair<PsiMember, PsiSubstitutor>>(); map.put(ALL, allMembers); ElementClassFilter filter = key == MemberType.CLASS ? ElementClassFilter.CLASS : key == MemberType.METHOD ? ElementClassFilter.METHOD : ElementClassFilter.FIELD; final ElementClassHint classHint = new ElementClassHint() { @Override public boolean shouldProcess(DeclarationKind kind) { return key == MemberType.CLASS && kind == DeclarationKind.CLASS || key == MemberType.FIELD && (kind == DeclarationKind.FIELD || kind == DeclarationKind.ENUM_CONST) || key == MemberType.METHOD && kind == DeclarationKind.METHOD; } }; FilterScopeProcessor<MethodCandidateInfo> processor = new FilterScopeProcessor<MethodCandidateInfo>(filter) { @Override protected void add(@NotNull PsiElement element, @NotNull PsiSubstitutor substitutor) { if (key == MemberType.CLASS && element instanceof PsiClass || key == MemberType.METHOD && element instanceof PsiMethod || key == MemberType.FIELD && element instanceof PsiField) { Pair<PsiMember, PsiSubstitutor> info = Pair.create((PsiMember)element, substitutor); allMembers.add(info); String currentName = ((PsiMember)element).getName(); List<Pair<PsiMember, PsiSubstitutor>> listByName = map.get(currentName); if (listByName == null) { listByName = new ArrayList<Pair<PsiMember, PsiSubstitutor>>(1); map.put(currentName, listByName); } listByName.add(info); } } @Override public <K> K getHint(@NotNull Key<K> hintKey) { //noinspection unchecked return ElementClassHint.KEY == hintKey ? (K)classHint : super.getHint(hintKey); } }; processDeclarationsInClassNotCached(myPsiClass, processor, ResolveState.initial(), null, null, myPsiClass, false, PsiUtil.getLanguageLevel(myPsiClass), myResolveScope); return map; }
@Override public void processVariants(@NotNull final PsiScopeProcessor processor) { final FilterScopeProcessor proc = new FilterScopeProcessor(ElementClassFilter.METHOD, processor); PsiScopesUtil.resolveAndWalk(proc, this, null, true); }
public static PsiVariable[] getAllVariables(PsiElement scope, PsiElement place) { final SmartList<PsiVariable> result = new SmartList<PsiVariable>(); scope.processDeclarations(new FilterScopeProcessor<PsiVariable>(ElementClassFilter.VARIABLE, result), ResolveState.initial(), null, place); return result.toArray(new PsiVariable[result.size()]); }
public static PsiMethod[] getAllMethods(PsiElement scope, PsiElement place) { final SmartList<PsiMethod> result = new SmartList<PsiMethod>(); scope.processDeclarations(new FilterScopeProcessor<PsiMethod>(ElementClassFilter.METHOD, result), ResolveState.initial(), null, place); return result.toArray(new PsiMethod[result.size()]); }
@Nullable public static ElementFilter getReferenceFilter(PsiElement position) { // Completion after extends in interface, type parameter and implements in class final PsiClass containingClass = PsiTreeUtil.getParentOfType(position, PsiClass.class, false, PsiCodeBlock.class, PsiMethod.class, PsiExpressionList.class, PsiVariable.class, PsiAnnotation.class); if (containingClass != null && psiElement().afterLeaf(PsiKeyword.EXTENDS, PsiKeyword.IMPLEMENTS, ",", "&").accepts(position)) { return new AndFilter(ElementClassFilter.CLASS, new NotFilter(new AssignableFromContextFilter())); } if (ANNOTATION_NAME.accepts(position)) { return new AnnotationTypeFilter(); } if (JavaKeywordCompletion.DECLARATION_START.getValue().accepts(position) || JavaKeywordCompletion.isInsideParameterList(position) || isInsideAnnotationName(position)) { return new OrFilter(ElementClassFilter.CLASS, ElementClassFilter.PACKAGE_FILTER); } if (psiElement().afterLeaf(PsiKeyword.INSTANCEOF).accepts(position)) { return new ElementExtractorFilter(ElementClassFilter.CLASS); } if (JavaKeywordCompletion.VARIABLE_AFTER_FINAL.accepts(position)) { return ElementClassFilter.CLASS; } if (isCatchFinallyPosition(position) || JavaKeywordCompletion.START_SWITCH.accepts(position) || JavaKeywordCompletion.isInstanceofPlace(position) || JavaKeywordCompletion.isAfterPrimitiveOrArrayType(position)) { return null; } if (JavaKeywordCompletion.START_FOR.accepts(position)) { return new OrFilter(ElementClassFilter.CLASS, ElementClassFilter.VARIABLE); } if (JavaSmartCompletionContributor.AFTER_NEW.accepts(position)) { return ElementClassFilter.CLASS; } if (psiElement().inside(PsiReferenceParameterList.class).accepts(position)) { return ElementClassFilter.CLASS; } if (psiElement().inside(PsiAnnotationParameterList.class).accepts(position)) { return createAnnotationFilter(position); } PsiVariable var = PsiTreeUtil.getParentOfType(position, PsiVariable.class, false, PsiClass.class); if (var != null && PsiTreeUtil.isAncestor(var.getInitializer(), position, false)) { return new ExcludeDeclaredFilter(new ClassFilter(PsiVariable.class)); } if (SWITCH_LABEL.accepts(position)) { return new ClassFilter(PsiField.class) { @Override public boolean isAcceptable(Object element, PsiElement context) { return element instanceof PsiEnumConstant; } }; } return TrueFilter.INSTANCE; }
@Nullable public static ElementFilter getReferenceFilter(PsiElement position) { // Completion after extends in interface, type parameter and implements in class final PsiClass containingClass = PsiTreeUtil.getParentOfType(position, PsiClass.class, false, PsiCodeBlock.class, PsiMethod.class, PsiExpressionList.class, PsiVariable.class, PsiAnnotation.class); if (containingClass != null && psiElement().afterLeaf(PsiKeyword.EXTENDS, PsiKeyword.IMPLEMENTS, ",", "&").accepts(position)) { return new AndFilter(ElementClassFilter.CLASS, new NotFilter(new AssignableFromContextFilter())); } if (ANNOTATION_NAME.accepts(position)) { return new AnnotationTypeFilter(); } if (JavaCompletionData.DECLARATION_START.accepts(position) || JavaCompletionData.isInsideParameterList(position) || psiElement().inside(psiElement(PsiJavaCodeReferenceElement.class).withParent(psiAnnotation())).accepts(position)) { return new OrFilter(ElementClassFilter.CLASS, ElementClassFilter.PACKAGE_FILTER); } if (psiElement().afterLeaf(PsiKeyword.INSTANCEOF).accepts(position)) { return new ElementExtractorFilter(ElementClassFilter.CLASS); } if (JavaCompletionData.VARIABLE_AFTER_FINAL.accepts(position)) { return ElementClassFilter.CLASS; } if (JavaCompletionData.AFTER_TRY_BLOCK.isAcceptable(position, position) || JavaCompletionData.START_SWITCH.accepts(position) || JavaCompletionData.isInstanceofPlace(position) || JavaCompletionData.isAfterPrimitiveOrArrayType(position)) { return null; } if (JavaCompletionData.START_FOR.accepts(position)) { return new OrFilter(ElementClassFilter.CLASS, ElementClassFilter.VARIABLE); } if (JavaSmartCompletionContributor.AFTER_NEW.accepts(position)) { return ElementClassFilter.CLASS; } if (psiElement().inside(PsiReferenceParameterList.class).accepts(position)) { return ElementClassFilter.CLASS; } if (psiElement().inside(PsiAnnotationParameterList.class).accepts(position)) { return createAnnotationFilter(position); } if (psiElement().afterLeaf("=").inside(PsiVariable.class).accepts(position)) { return new OrFilter( new ClassFilter(PsiVariable.class, false), new ExcludeDeclaredFilter(new ClassFilter(PsiVariable.class))); } if (SWITCH_LABEL.accepts(position)) { return new ClassFilter(PsiField.class) { @Override public boolean isAcceptable(Object element, PsiElement context) { return element instanceof PsiEnumConstant; } }; } return TrueFilter.INSTANCE; }
@Nullable @Override protected Map<String, PsiMember[]> create(final MemberType key) { final Map<String, List<PsiMember>> map = ContainerUtil.newTroveMap(); final List<PsiMember> allMembers = ContainerUtil.newArrayList(); map.put(ALL, allMembers); ElementClassFilter filter = key == MemberType.CLASS ? ElementClassFilter.CLASS : key == MemberType.METHOD ? ElementClassFilter.METHOD : ElementClassFilter.FIELD; final ElementClassHint classHint = new ElementClassHint() { @Override public boolean shouldProcess(DeclarationKind kind) { return key == MemberType.CLASS && kind == DeclarationKind.CLASS || key == MemberType.FIELD && (kind == DeclarationKind.FIELD || kind == DeclarationKind.ENUM_CONST) || key == MemberType.METHOD && kind == DeclarationKind.METHOD; } }; FilterScopeProcessor<MethodCandidateInfo> processor = new FilterScopeProcessor<MethodCandidateInfo>(filter) { @Override protected void add(@NotNull PsiElement element, @NotNull PsiSubstitutor substitutor) { if(key == MemberType.CLASS && element instanceof PsiClass || key == MemberType.METHOD && element instanceof PsiMethod || key == MemberType.FIELD && element instanceof PsiField) { allMembers.add((PsiMember) element); String currentName = ((PsiMember) element).getName(); List<PsiMember> listByName = map.get(currentName); if(listByName == null) { listByName = ContainerUtil.newSmartList(); map.put(currentName, listByName); } listByName.add((PsiMember) element); } } @Override public <K> K getHint(@NotNull Key<K> hintKey) { //noinspection unchecked return ElementClassHint.KEY == hintKey ? (K) classHint : super.getHint(hintKey); } }; processDeclarationsInClassNotCached(myPsiClass, processor, ResolveState.initial(), null, null, myPsiClass, false, PsiUtil.getLanguageLevel(myPsiClass), myResolveScope); Map<String, PsiMember[]> result = ContainerUtil.newTroveMap(); for(String name : map.keySet()) { result.put(name, map.get(name).toArray(PsiMember.EMPTY_ARRAY)); } return result; }