RecordExhaustivenessResult (@NotNull List<? extends PatternDescription> elements, @NotNull PsiType targetType, @NotNull PsiElement context) { List<PatternDeconstructionDescription> descriptions = StreamEx.of(elements).select(PatternDeconstructionDescription.class) .filter(element -> TypeConversionUtil.areTypesConvertible(element.type(), targetType)) .toList(); if (descriptions.isEmpty()) { return RecordExhaustivenessResult.createNotBeAdded(); } return CachedValuesManager.getCachedValue(context, () -> { Map<ReduceResultCacheContext, RecordExhaustivenessResult> cacheResult = ConcurrentFactoryMap.createMap(cacheContext -> { Set<? extends PatternDescription> patterns = cacheContext.currentPatterns; PsiType selectorType = cacheContext.mySelectorType; HashMap<ReduceResultCacheContext, ReduceResult> cache = new HashMap<>(); LoopReduceResult result = reduceInLoop(selectorType, context, new HashSet<>(patterns), (descriptionPatterns, type) -> coverSelectorType(descriptionPatterns, selectorType), cache); if (result.stopped()) { return RecordExhaustivenessResult.createExhaustiveResult(); } List<? extends PatternDescription> missedRecordPatterns = findMissedRecordPatterns(selectorType, result.patterns, context, cache); if (missedRecordPatterns == null) { return RecordExhaustivenessResult.createNotBeAdded(); } RecordExhaustivenessResult exhaustiveResult = RecordExhaustivenessResult.createNotExhaustiveResult(); exhaustiveResult.addBranches(missedRecordPatterns); return exhaustiveResult; }); return CachedValueProvider.Result.create(cacheResult, PsiModificationTracker.MODIFICATION_COUNT); }).get(new ReduceResultCacheContext(targetType, new HashSet<>(descriptions))); }