boolean (@NotNull PsiElement patternType, PsiElement matchedType) { PsiElement patternElement = getInnermostComponent(patternType); PsiElement matchedElement = patternElement instanceof PsiTypeElement && ((PsiTypeElement)patternElement).isInferredType() ? matchedType : getInnermostComponent(matchedType); PsiElement[] typeParameters = null; if (matchedElement instanceof PsiJavaCodeReferenceElement) { final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)matchedElement; typeParameters = getTypeParameters(referenceElement, shouldReplaceDiamondWithExplicitTypes(patternElement)); } else if (matchedElement instanceof PsiTypeParameter) { matchedElement = ((PsiTypeParameter)matchedElement).getNameIdentifier(); } else if (matchedElement instanceof PsiClass && ((PsiClass)matchedElement).hasTypeParameters()) { typeParameters = ((PsiClass)matchedElement).getTypeParameters(); matchedElement = ((PsiClass)matchedElement).getNameIdentifier(); } else if (matchedElement instanceof PsiMethod && ((PsiMethod)matchedElement).hasTypeParameters()) { typeParameters = ((PsiMethod)matchedElement).getTypeParameters(); matchedElement = ((PsiMethod)matchedElement).getNameIdentifier(); } if (patternElement instanceof PsiTypeElement && matchedElement instanceof PsiTypeElement) { final PsiType type1 = ((PsiTypeElement)patternElement).getType(); final PsiType type2 = ((PsiTypeElement)matchedElement).getType(); if (type1 instanceof PsiWildcardType wildcardType1 && type2 instanceof PsiWildcardType wildcardType2) { if (wildcardType1.equals(wildcardType2)) return true; if (wildcardType1.isExtends() && (wildcardType2.isExtends() || !wildcardType2.isBounded())) { if (wildcardType2.isExtends()) { return myMatchingVisitor.match(patternElement.getLastChild(), matchedElement.getLastChild()); } else { return myMatchingVisitor.matchOptionally(patternElement.getLastChild(), null); } } else if (wildcardType1.isSuper() && wildcardType2.isSuper()) { return myMatchingVisitor.match(patternElement.getLastChild(), matchedElement.getLastChild()); } } } if (patternElement instanceof PsiJavaCodeReferenceElement) { final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)patternElement; final PsiReferenceParameterList list = referenceElement.getParameterList(); boolean typeParametersMatched = false; if (list != null) { final PsiTypeElement[] elements = list.getTypeParameterElements(); if (elements.length > 0) { typeParametersMatched = true; if (!myMatchingVisitor.matchSequentially(elements, (typeParameters == null) ? PsiElement.EMPTY_ARRAY : typeParameters)) { return false; } } } patternElement = referenceElement.getReferenceNameElement(); if (typeParametersMatched && matchedElement instanceof PsiJavaCodeReferenceElement) { matchedElement = ((PsiJavaCodeReferenceElement)matchedElement).getReferenceNameElement(); } } final int matchedArrayDimensions = getArrayDimensions(matchedType); final int patternArrayDimensions = getArrayDimensions(patternType); if (myMatchingVisitor.getMatchContext().getPattern().isTypedVar(patternElement)) { final SubstitutionHandler handler = (SubstitutionHandler)myMatchingVisitor.getMatchContext().getPattern().getHandler(patternElement); RegExpPredicate regExpPredicate = null; boolean fullTypeResult = false; if (patternArrayDimensions != 0) { if (patternArrayDimensions != matchedArrayDimensions) { return false; } } else if (matchedArrayDimensions != 0) { regExpPredicate = handler.findPredicate(RegExpPredicate.class); if (regExpPredicate != null) { regExpPredicate.setNodeTextGenerator( element -> StructuralSearchUtil.getMeaningfulText(element) + "[]".repeat(matchedArrayDimensions)); } fullTypeResult = true; } try { final boolean result = (handler.isSubtype() || handler.isStrictSubtype()) ? matchWithinHierarchy(patternElement, matchedElement, handler) : handler.validate(matchedElement, myMatchingVisitor.getMatchContext()); if (result) handler.addResult(fullTypeResult ? matchedType : matchedElement, myMatchingVisitor.getMatchContext()); return result; } finally { if (regExpPredicate != null) regExpPredicate.setNodeTextGenerator(null); } } if (matchedArrayDimensions != patternArrayDimensions) { return false; } if (patternElement instanceof PsiIdentifier) { final PsiElement parent = patternElement.getParent(); if (parent instanceof PsiJavaCodeReferenceElement) { patternElement = parent; } } if (matchedElement instanceof PsiIdentifier) { final PsiElement parent = matchedElement.getParent(); if (parent instanceof PsiJavaCodeReferenceElement) { matchedElement = parent; } } final String text = getText(patternElement); final String text2 = getText(matchedElement); final boolean caseSensitive = myMatchingVisitor.getMatchContext().getOptions().isCaseSensitiveMatch(); final boolean equalsIgnorePackage = MatchUtils.compareWithNoDifferenceToPackage(text, text2, !caseSensitive); if (equalsIgnorePackage || !(matchedElement instanceof PsiJavaReference)) { return equalsIgnorePackage; } else { final PsiElement element2 = ((PsiJavaReference)matchedElement).resolve(); if (!(element2 instanceof PsiClass)) { return false; } final String name = ((PsiClass)element2).getQualifiedName(); return caseSensitive ? text.equals(name) : text.equalsIgnoreCase(name); } }