List<DomElementProblemDescriptor> (final GenericDomValue element, final PsiClass value, final String[] names, final boolean instantiatable, final boolean canBeDecorator, final boolean allowInterface, final boolean allowNonPublic, final boolean allowAbstract, final boolean allowEnum, final DomElementAnnotationHolder holder) { final Project project = element.getManager().getProject(); Set<PsiClass> toExtend = Arrays.stream(names) .filter(Objects::nonNull) .map(s -> JavaPsiFacade.getInstance(project).findClass(s, GlobalSearchScope.allScope(project))) .filter(Objects::nonNull) .collect(Collectors.toSet()); final SmartList<DomElementProblemDescriptor> list = new SmartList<>(); if (toExtend.size() > 0) { if (!Arrays.asList(names).contains(value.getQualifiedName()) && ContainerUtil.find(toExtend, aClass -> value.isInheritor(aClass, true)) == null) { String message = JavaBundle.message("class.is.not.a.subclass", value.getQualifiedName(), StringUtil.join(names, ",")); list.add(holder.createProblem(element, message)); } } if (instantiatable) { if (value.hasModifierProperty(PsiModifier.ABSTRACT)) { list.add(holder.createProblem(element, JavaBundle.message("class.is.not.concrete", value.getQualifiedName()))); } else if (!allowNonPublic && !value.hasModifierProperty(PsiModifier.PUBLIC)) { list.add(holder.createProblem(element, JavaBundle.message("class.is.not.public", value.getQualifiedName()))); } else if (!PsiUtil.hasDefaultConstructor(value, true, true)) { if (canBeDecorator) { boolean hasConstructor = false; for (PsiMethod method : value.getConstructors()) { final PsiParameterList psiParameterList = method.getParameterList(); if (psiParameterList.getParametersCount() != 1) continue; PsiTypeElement typeElement = psiParameterList.getParameters()[0].getTypeElement(); if (typeElement != null) { final PsiType psiType = typeElement.getType(); if (psiType instanceof PsiClassType) { final PsiClass psiClass = ((PsiClassType)psiType).resolve(); if (psiClass != null && ContainerUtil.find(toExtend, aClass -> InheritanceUtil.isInheritorOrSelf(psiClass, aClass, true)) != null) { hasConstructor = true; break; } } } } if (!hasConstructor) { list.add( holder.createProblem(element, JavaBundle.message("class.decorator.or.has.default.constructor", value.getQualifiedName()))); } } else { list.add(holder.createProblem(element, JavaBundle.message("class.has.no.default.constructor", value.getQualifiedName()))); } } } if (!allowInterface && value.isInterface()) { list.add(holder.createProblem(element, JavaBundle.message("interface.not.allowed", value.getQualifiedName()))); } if (!allowEnum && value.isEnum()) { list.add(holder.createProblem(element, JavaBundle.message("enum.not.allowed", value.getQualifiedName()))); } if (!allowAbstract && value.hasModifierProperty(PsiModifier.ABSTRACT) && !value.isInterface()) { list.add(holder.createProblem(element, JavaBundle.message("abstract.class.not.allowed", value.getQualifiedName()))); } return list; }