boolean (@Nullable PsiDeconstructionPattern deconstructionPattern, @NotNull Consumer<? super HighlightInfo.Builder> errorSink) { if (deconstructionPattern == null) return false; PsiTypeElement typeElement = deconstructionPattern.getTypeElement(); PsiType recordType = typeElement.getType(); ClassResolveResult resolveResult = recordType instanceof PsiClassType classType ? classType.resolveGenerics() : ClassResolveResult.EMPTY; PsiClass recordClass = resolveResult.getElement(); if (recordClass == null || !recordClass.isRecord()) { String message = JavaErrorBundle.message("deconstruction.pattern.requires.record", JavaHighlightUtil.formatType(recordType)); HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(message); errorSink.accept(info); return true; } if (resolveResult.getInferenceError() != null) { String message = JavaErrorBundle.message("error.cannot.infer.pattern.type", resolveResult.getInferenceError()); HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(message); errorSink.accept(info); return true; } PsiJavaCodeReferenceElement ref = typeElement.getInnermostComponentReferenceElement(); if (recordClass.hasTypeParameters() && ref != null && ref.getTypeParameterCount() == 0 && PsiUtil.getLanguageLevel(deconstructionPattern).isLessThan(LanguageLevel.JDK_20_PREVIEW)) { String message = JavaErrorBundle.message("error.raw.deconstruction", typeElement.getText()); HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(message); errorSink.accept(info); return true; } PsiSubstitutor substitutor = resolveResult.getSubstitutor(); PsiRecordComponent[] recordComponents = recordClass.getRecordComponents(); PsiPattern[] deconstructionComponents = deconstructionPattern.getDeconstructionList().getDeconstructionComponents(); boolean hasMismatchedPattern = false; boolean reported = false; for (int i = 0; i < Math.min(recordComponents.length, deconstructionComponents.length); i++) { PsiPattern deconstructionComponent = deconstructionComponents[i]; PsiType recordComponentType = recordComponents[i].getType(); PsiType substitutedRecordComponentType = substitutor.substitute(recordComponentType); PsiType deconstructionComponentType = JavaPsiPatternUtil.getPatternType(deconstructionComponent); if (!isApplicable(substitutedRecordComponentType, deconstructionComponentType)) { hasMismatchedPattern = true; if (recordComponents.length == deconstructionComponents.length) { HighlightInfo.Builder builder = HighlightUtil.createIncompatibleTypeHighlightInfo(substitutedRecordComponentType, deconstructionComponentType, deconstructionComponent.getTextRange(), 0); errorSink.accept(builder); reported = true; } } else { HighlightInfo.Builder info = getUncheckedPatternConversionError(deconstructionComponent); if (info != null) { hasMismatchedPattern = true; errorSink.accept(info); reported = true; } } if (recordComponents.length != deconstructionComponents.length && hasMismatchedPattern) { break; } if (deconstructionComponent instanceof PsiDeconstructionPattern deconstructionComponentPattern) { reported |= createDeconstructionErrors(deconstructionComponentPattern, errorSink); } } if (recordComponents.length != deconstructionComponents.length) { HighlightInfo.Builder info = createIncorrectNumberOfNestedPatternsError(deconstructionPattern, deconstructionComponents, recordComponents, !hasMismatchedPattern); errorSink.accept(info); return true; } return reported; }