Skip to content

feat(detect): recognize Dart and in-tree Roslyn analyzer projects - #690

Merged
theCodeDrift merged 2 commits into
mainfrom
fix/detect-dart-roslyn
Nov 12, 2026
Merged

theCodeDrift merged 2 commits into
mainfrom
fix/detect-dart-roslyn

Conversation

@theCodeDrift

Copy link
Copy Markdown
Member

detect recognizes Dart/Flutter and in-tree Roslyn analyzer projects.

  • Dart: a pubspec.yaml reports Dart. A new dart-analyzer linter is reported from analysis_options.yaml, lints/flutter_lints/very_good_analysis in (dev_)dependencies, or dart analyze/flutter analyze in CI or hooks.
  • Roslyn: a ProjectReference with OutputItemType="Analyzer" in a .csproj/.props/.targets reports a custom-analyzer linter, evidence analyzer project <path> (<declaring file>), with customRules counting [DiagnosticAnalyzer] attributes (skipping bin/obj/comments), or "unknown" if the project can't be found.
  • Detect recipe topic v6; schema descriptions updated. OpenSpec change adding two cli-detect requirements, archived (same pattern as 374a7b6).

For review:

  1. Linter name custom-analyzer is the issue's wording; the spec forbids a combined roslyn linter. Rename if you prefer.
  2. detect doesn't evaluate MSBuild, so a bare relative path in a .props/.targets is resolved only when its file name matches exactly one scanned .csproj.
  3. A Flutter repo still reports Ruby/Java from its platform folders (a non-goal in the proposal).
  4. Telemetry languageStack now reports Dart for a root pubspec.yaml.

Tests: Flutter app fixture, each Dart evidence source, comment-only lint sets, malformed pubspec, analyzer project wired three ways, duplicate and missing references, ordinary/commented-out references. typecheck, lint, tests (3178 passed), openspec validate --strict pass.

Commits are unsigned: the signing key couldn't be unlocked remotely, and the owner chose to ship unsigned.

Closes #680

@theCodeDrift

Copy link
Copy Markdown
Member Author

@claude /review

@github-actions

github-actions Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @theCodeDrift's task in 2m 54s —— View job


Review: feat(detect): recognize Dart and in-tree Roslyn analyzer projects

Review mode: incremental — read 0 prior review thread(s) before reviewing. The .prior-review.json snapshot had no review threads, no review summaries, and no comments beyond the @claude /review trigger itself — this is the first review of this PR.

  • Read prior review data (none to carry forward)
  • Fetch PR diff and metadata (gh pr diff, gh pr view)
  • Review Dart detection logic (scan.ts)
  • Review Roslyn/custom-analyzer logic (custom-rules.ts, scan.ts)
  • Review schema/spec/openspec changes
  • Review tests
  • Post findings

Summary

Solid, well-scoped change. Both new signals (dart-analyzer, custom-analyzer) follow the existing LinterSignal/CustomRuleContext patterns closely, the spec deltas and archived OpenSpec change match the implementation, and the test suite (Flutter fixture, each Dart evidence source, comment-only/malformed pubspec.yaml, all three Roslyn wiring styles, duplicate/missing references, commented-out references) covers the scenarios in the spec well.

Verified logic that looked risky but checks out:

  • resolveAnalyzerProject's three-tier resolution ($(MSBuildThisFileDirectory) → relative-to-.csproj → unique-by-basename fallback) matches the three test cases (Directory.Build.props via $(MSBuildThisFileDirectory), via another property, and child-metadata form in a .csproj) and correctly falls through when a normalized candidate isn't in projectPaths.
  • countRoslynAnalyzers's "unknown" threshold logic mirrors the existing ESLint counter's unknown && known < CUSTOM_RULE_THRESHOLD pattern.
  • Dart dependency/comment handling uses the real yaml parser (already a dependency elsewhere) rather than a regex, so a lint-set name inside a YAML comment is correctly never evidence — no regex false positive risk there.
  • analyzerReferencesFromMsbuild / nugetDepsFromMsbuild share one readAt per MSBuild file, as the proposal claims ("read in the same pass").
  • Telemetry's languageStack does pick up Dart for free via the shared LANGUAGE_MARKERS export (adoption-dimensions.ts imports it), confirming claim 4 in the PR description.

The three caveats called out in the PR description (combined-vs-split linter naming, MSBuild-property resolution being best-effort/name-based, Flutter repos still reporting Ruby/Java from platform folders) are accurately described and already documented as explicit non-goals in the proposal — not raising them as findings.

New findings (both low severity, posted inline)

  • packages/cli/src/detect/scan.ts:1237 — Analyzer evidence isn't deduped by (declaredIn, include), so a literally duplicated ProjectReference in one file produces duplicate analyzer project ... (file) evidence lines. The customRules count stays correct (deduped by directory), only the evidence array could show visible duplicates.
  • packages/cli/src/detect/custom-rules.ts:526 — Same duplication shape for an unresolved reference's "${include} (project not found)" evidence line when the same unresolvable Include appears in more than one file; no file attribution to distinguish the duplicates.

Neither is a correctness bug in the reported count/"unknown" value — both are cosmetic evidence-array noise in an edge case (accidental duplicate references) that isn't exercised by the current tests.

Comment thread packages/cli/src/detect/scan.ts Resolved
Comment thread packages/cli/src/detect/custom-rules.ts Resolved
@theCodeDrift

Copy link
Copy Markdown
Member Author

Re: @github-actions — "Claude finished @theCodeDrift's task in 2m 54s — Review: feat(detect): recognize Dart and in-tree Roslyn analyzer projects"…
#690 (comment)

Both findings are addressed in c878b73: analyzer references are deduped per MSBuild file, and unresolved-reference evidence names the file that declares it. New tests cover both.

— AI Coding Agent

…lved ones

A ProjectReference repeated within one MSBuild file now yields one evidence
line, and an unresolved reference's custom-rule evidence names the file that
declares it, so the same Include from two files no longer reads as a duplicate.
@theCodeDrift
theCodeDrift force-pushed the fix/detect-dart-roslyn branch from c878b73 to c8b6d12 Compare November 12, 2026 04:20
@theCodeDrift
theCodeDrift merged commit 0a76a92 into main Nov 12, 2026
4 checks passed
@theCodeDrift
theCodeDrift deleted the fix/detect-dart-roslyn branch November 12, 2026 04:23
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.

detect: recognize Dart/Flutter and in-tree Roslyn analyzer projects

1 participant