Skip to content

SLCORE-2242 Add embedded, unsupported and premium artifact resolvers#1924

Open
Krosovok wants to merge 1 commit intofeature/on-demand-analyzersfrom
feature/vt/SLCORE-2242-resolve-embedded-unsupported-premium-artifacts
Open

SLCORE-2242 Add embedded, unsupported and premium artifact resolvers#1924
Krosovok wants to merge 1 commit intofeature/on-demand-analyzersfrom
feature/vt/SLCORE-2242-resolve-embedded-unsupported-premium-artifacts

Conversation

@Krosovok
Copy link
Contributor

No description provided.

@Krosovok Krosovok requested a review from nquinquenel March 18, 2026 12:08
@sonar-review-alpha
Copy link

sonar-review-alpha bot commented Mar 18, 2026

Summary

Adds four new artifact resolver implementations to handle different plugin/analyzer sources and availability states. These resolvers are part of the artifact resolution system that determines which language analyzers are available (embedded, premium, unsupported, or downloadable). The changes include comprehensive test coverage for each resolver.

What reviewers should know

Start with the resolver implementations in backend/core/src/main/java/org/sonarsource/sonarlint/core/plugin/resolvers/ to understand the architecture:

  • EmbeddedArtifactResolver: The most complex — handles resolving embedded language plugins with different logic for standalone vs connected modes. Note the special handling for C# (dedicated OSS analyzer path) and the separate companion plugin resolution (non-language plugins like Omnisharp).
  • PremiumArtifactResolver: Simpler — identifies languages only available in connected mode by querying the language support repository.
  • UnsupportedArtifactResolver: Flags languages not enabled in either mode, with debug logging for connected mode sync.
  • EmbeddedExtraArtifactResolver: Handles non-language artifacts (Omnisharp distributions) keyed by type (mono, net6, net472).

The corresponding tests in backend/core/src/test/java/ provide good documentation of expected behavior, especially EmbeddedArtifactResolverTest which covers both standalone/connected modes and the C# special case.

Key architectural notes: These resolvers work with InitializeParams passed during initialization, and they implement the ArtifactResolver interface (some also CompanionPluginResolver). The resolvers return ResolvedArtifact objects with state, path, source, and version information.


  • Generate Walkthrough
  • Generate Diagram

🗣️ Give feedback

@hashicorp-vault-sonar-prod
Copy link

hashicorp-vault-sonar-prod bot commented Mar 18, 2026

SLCORE-2242

Copy link

@sonar-review-alpha sonar-review-alpha bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conclusion: The resolver logic is clean and the tests are thorough, but there are two correctness concerns worth addressing before merge — the resolveCompanionPlugins parameter that is silently ignored (ambiguous whether by design or an oversight), and a subtle behavioural dependency between UnsupportedArtifactResolver and PremiumArtifactResolver that is invisible at each call site.

🗣️ Give feedback

.collect(Collectors.toMap(
Map.Entry::getKey,
e -> PluginStatus.forCompanion(e.getKey(), ArtifactState.ACTIVE, ArtifactSource.EMBEDDED, e.getValue())));
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolveCompanionPlugins accepts connectionId but unconditionally iterates standaloneEmbeddedPathsByKey, ignoring the parameter entirely. Companion plugins are always taken from the standalone embedded set regardless of mode.

If intentional (companion plugins are always the same across modes), the parameter should be removed from the interface or at least documented. If they can differ per connection, this is a bug. The test suite only exercises this with null, leaving connected-mode behaviour unverified either way.

  • Mark as noise

@nquinquenel nquinquenel requested a review from Copilot March 19, 2026 08:44
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a set of artifact resolvers in backend/core to classify/locate analyzers (embedded plugins, embedded extra artifacts like Omnisharp distributions, and “premium/unsupported” states) and adds unit tests covering the new resolvers’ behaviors.

Changes:

  • Add EmbeddedArtifactResolver to resolve embedded plugin JARs (standalone + connected mode) and expose companion plugins.
  • Add EmbeddedExtraArtifactResolver to resolve embedded “extra” artifacts (Omnisharp distribution paths) from InitializeParams.
  • Add PremiumArtifactResolver and UnsupportedArtifactResolver plus corresponding unit tests.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
backend/core/src/main/java/org/sonarsource/sonarlint/core/plugin/resolvers/UnsupportedArtifactResolver.java Adds resolver to return an UNSUPPORTED artifact when a language isn’t enabled.
backend/core/src/main/java/org/sonarsource/sonarlint/core/plugin/resolvers/PremiumArtifactResolver.java Adds resolver to return a PREMIUM artifact for connected-only languages.
backend/core/src/main/java/org/sonarsource/sonarlint/core/plugin/resolvers/EmbeddedExtraArtifactResolver.java Adds resolver for embedded extra artifacts (Omnisharp distro paths) keyed by artifact key.
backend/core/src/main/java/org/sonarsource/sonarlint/core/plugin/resolvers/EmbeddedArtifactResolver.java Adds embedded plugin resolution (standalone/connected) and companion plugin detection.
backend/core/src/test/java/org/sonarsource/sonarlint/core/plugin/UnsupportedArtifactResolverTest.java Adds tests for unsupported resolution behavior.
backend/core/src/test/java/org/sonarsource/sonarlint/core/plugin/PremiumArtifactResolverTest.java Adds tests for premium resolution behavior.
backend/core/src/test/java/org/sonarsource/sonarlint/core/plugin/EmbeddedExtraArtifactResolverTest.java Adds tests for extra-artifact path resolution.
backend/core/src/test/java/org/sonarsource/sonarlint/core/plugin/EmbeddedArtifactResolverTest.java Adds tests for embedded plugin and companion plugin resolution.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +40 to +55
// --- Disabled-keys behaviour ---

@Test
void should_return_empty_when_plugin_key_is_disabled_for_analysis_in_standalone() {
var languageSupport = mockLanguageSupport(true, true);
var resolver = new UnsupportedArtifactResolver(languageSupport);

var result = resolver.resolve(SonarLanguage.JAVA, null);

assertThat(result).isEmpty();
}

@Test
void should_return_empty_when_plugin_key_is_disabled_for_analysis_in_connected_mode() {
var languageSupport = mockLanguageSupport(true, true);
var resolver = new UnsupportedArtifactResolver(languageSupport);

private static Map<String, Path> buildPluginKeyToPathMap(Set<Path> embeddedPaths) {
return embeddedPaths.stream()
.collect(Collectors.toMap(p -> SonarPluginManifest.fromJar(p).getKey(), Function.identity()));
Comment on lines +77 to +86
@Test
void should_resolve_to_active_embedded_in_standalone_when_filename_contains_plugin_key() throws IOException {
var javaJar = createJar("sonar-java-plugin.jar");
var resolver = new EmbeddedArtifactResolver(mockParams(Set.of(javaJar), Map.of(), null));
var expected = resolved(ArtifactState.ACTIVE, javaJar, ArtifactSource.EMBEDDED);

var result = resolver.resolve(SonarLanguage.JAVA, null);

assertThat(result).contains(expected);
}
Comment on lines +39 to +40
if (languageSupportRepository.isEnabledInConnectedMode(language)
&& !languageSupportRepository.isEnabledInStandaloneMode(language)) {
Comment on lines +53 to +54
return (languageSupportRepository.isEnabledInStandaloneMode(language) && connectionId == null)
|| languageSupportRepository.isEnabledInConnectedMode(language);
Comment on lines +90 to +91
connected.forEach(lang -> when(repo.isEnabledInConnectedMode(lang)).thenReturn(true));
standalone.forEach(lang -> when(repo.isEnabledInStandaloneMode(lang)).thenReturn(true));
Comment on lines +104 to +110
private static LanguageSupportRepository mockLanguageSupport(boolean enabledInStandalone, boolean enabledInConnected) {
var repo = mock(LanguageSupportRepository.class);
when(repo.isEnabledInStandaloneMode(SonarLanguage.JAVA)).thenReturn(enabledInStandalone);
when(repo.isEnabledInConnectedMode(SonarLanguage.JAVA)).thenReturn(enabledInConnected);
when(repo.isEnabledInStandaloneMode(SonarLanguage.PYTHON)).thenReturn(enabledInStandalone);
when(repo.isEnabledInConnectedMode(SonarLanguage.PYTHON)).thenReturn(enabledInConnected);
return repo;
@Krosovok Krosovok force-pushed the feature/vt/SLCORE-2242-resolve-embedded-unsupported-premium-artifacts branch from 94327f2 to aabe95d Compare March 19, 2026 13:15
Copy link

@sonar-review-alpha sonar-review-alpha bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conclusion: Clean, well-tested PR. All four resolvers are straightforward to follow, tests cover the meaningful edge cases (C# fallback path, companion vs language plugins, null connection IDs), and the code fits the existing conventions.

🗣️ Give feedback

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.

2 participants