Skip to content

MP-2974 Suppress class-not-found problems from transitive optional dependencies - #1550

Open
VLhsiotor wants to merge 1 commit into
JetBrains:masterfrom
VLhsiotor:MP-2974
Open

MP-2974 Suppress class-not-found problems from transitive optional dependencies#1550
VLhsiotor wants to merge 1 commit into
JetBrains:masterfrom
VLhsiotor:MP-2974

Conversation

@VLhsiotor

@VLhsiotor VLhsiotor commented Jul 16, 2026

Copy link
Copy Markdown

Problem

[MP-2974] Unresolved optional dependencies must not be highlighted as errors.

The verifier already suppresses ClassNotFoundProblems that originate from a plugin's optional parts when the triggering optional dependency is missing (this is expected — the code is only loaded when the optional dependency is present). However, this suppression only worked for directly declared, top-level optional descriptors. For transitive / nested optional dependencies the analysis silently did nothing, so those class-not-found problems leaked as errors even though the missing dependency is optional.

Root cause

buildClassReachabilityGraph (ClassReachabilityAnalysis.kt) marks the classes of the optional parts so that problems inside them can be recognized as expected. It had two limitations:

  1. Non-recursive lookup — it only inspected idePlugin.optionalDescriptors (the top level). An optional descriptor nested inside another optional descriptor (a transitive optional dependency) was never found, so its classes were not marked as optional.
  2. Matching by object equality — descriptors were matched with descriptor.dependency == missingDependency.dependency. Module dependencies are normalized by the graph builder into a proxy type that is not object-equal to the descriptor's original dependency, so module optional dependencies (e.g. com.intellij.modules.clion.cmake) never matched.

Fix

  • Search the whole optional-descriptor tree recursively.
  • Match descriptors by dependency id instead of object equality.
  • Collect referenced classes recursively from nested optional and module descriptors (PluginXmlUtil.getAllClassesReferencedFromXml does not descend into nested descriptors on its own).

Only ClassReachabilityAnalysis.kt changes; the guard in PluginVerifier is untouched, since getDirectMissingDependencies() already contains the (flattened) transitive optional dependencies.

Scope note

This addresses the case where an unresolved optional dependency produces actual compatibility errors (ClassNotFoundProblem). It does not change how a missing optional dependency is rendered in the dependency tree (the informational (failed) (optional) line), which is a separate presentation concern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant