feat(parsers): add Dart public API parser via package:analyzer (alternative to #35)#41
Merged
Conversation
Alternative to #35: extract the Dart/Flutter public API surface with a small package:analyzer tool instead of the dartdoc_json CLI plus a Node normalizer. The tool parses lib/**.dart syntactically (no pub get, no network), emits the existing ParseResult shape, and is invoked via a parse-dart npm script so the reusable workflow's generic parse step is unchanged. It handles extension types and enhanced enums by construction, and honors .sdk-parse-ignore for parity with the TypeScript and Swift parsers. Removes the need for dartdoc_json activation, per-package flutter pub get, the jq merge, and the Node normalizer.
The supabase/sdk Actions policy only permits GitHub-owned and verified-creator actions, so dart-lang/setup-dart caused a workflow startup failure. Install the SDK with a plain download instead, which also keeps the reusable workflow independent of each calling repo's allowed-actions policy.
Self-review found three issues: - A class-type alias (class C = A with B;) was emitted with kind variable instead of class, because ClassTypeAlias is a subtype of TypeAlias. - Directory ignore patterns (build/, examples/) excluded only the directory entry itself, not the files nested beneath it, so contents leaked into the surface. - A single unreadable or unparseable lib file aborted the whole extraction; it is now skipped with a stderr warning. Adds regression tests for each.
Install the Dart SDK with the dart-lang/setup-dart action instead of a manual download. Replace the SymbolKindJson extension with SymbolKind.name, special casing only classKind since 'class' is a reserved word.
Replace the if-else type ladder in _visitTopLevel with a switch on Dart 3 patterns: the five class-like containers share one case, and a small _emit helper centralizes the private-name guard for simple symbols. Output is unchanged.
grdsdev
reviewed
Jun 22, 2026
grdsdev
left a comment
Collaborator
There was a problem hiding this comment.
parsing AST directly is fine for me, I'd just move the dart_symbol_extractor dart package out of the capability-matrix, to not mix different languages in the same folder, what do you think?
Relocate the package from scripts/capability-matrix/dart_symbol_extractor to scripts/dart_symbol_extractor as a sibling of the Node validator. Update the parse-dart npm script path, both workflows' working directories, the validate-capabilities paths filter, and the CLAUDE.md reference.
grdsdev
approved these changes
Jun 22, 2026
The reusable workflow now runs 'dart run bin/extract.dart' from the extractor package for the dart language, instead of dispatching through an npm script. Removes the parse-dart entry from package.json.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Alternative to #35. Adds Dart/Flutter public API surface parsing to the SDK compliance workflow using a small
package:analyzertool (dart_symbol_extractor) instead of thedartdoc_jsonCLI plus a Node.js normalizer.Same goal as #35 (gate supabase-flutter PRs via
validate-sdk-compliance.ymlwithlanguage: dart), sameParseResultoutput contract, but a different implementation. Pick one.Design spec:
docs/specs/2026-06-22-dart-parser-analyzer.md.Approach
A Dart tool parses each package's
lib/**.dartfiles syntactically with the real analyzer front end and emits the existingParseResultshape directly. It is invoked via aparse-dartnpm script, exactly likeparse-ts/parse-swift, so the reusable workflow's generic parse step is unchanged.Why this instead of
dartdoc_json(#35)pubspec.lock.dartdoc_json0.5.0 was last published ~18 months ago.extension type(Dart 3.3+) by construction.dartdoc_json0.5.0 throws on it, which is why feat(parsers): add Dart/Flutter public API surface parser via dartdoc_json #35 has to assert supabase-flutter never uses one.flutter pub get, the per-package JSON files, thejq -smerge, and the Node normalizer. The workflow diff is correspondingly smaller.pub geton the target packages, no network, no resolvable dependency graph. Only the Dart SDK and the tool's own deps are needed..sdk-parse-ignore(the feat(parsers): add Dart/Flutter public API surface parser via dartdoc_json #35 Dart path bypasses it), matching the TypeScript and Swift parsers.Symbol model
Matches the mapping used by the other parsers and #35's normalizer, so it is a drop-in at the
ParseResultboundary: classes/mixins/enums/extension-types/named-extensions →class; methods/operators →method; getters/setters/fields →property; constructors →Owner.name(unnamed →Owner.Owner); top-level functions →function; top-level variables/typedefs →variable. Name-based privacy (_-prefixed excluded). Enum constants are not emitted (matching #35).Changes
Added
scripts/capability-matrix/dart_symbol_extractor/— the Dart tool (lib/src/extractor.dart,parsed_symbol.dart,ignore_matcher.dart,bin/extract.dart)test/extractor_test.dart+ a fixture package — unit tests for the symbol model and ignore matcher, plus discovery/exclusion/relative-path integration testsdocs/specs/2026-06-22-dart-parser-analyzer.md— design specModified
.github/workflows/validate-sdk-compliance.yml—dartcase plus two dart-only setup steps (dart-lang/setup-dart,dart pub get)scripts/capability-matrix/package.json— addsparse-dartCLAUDE.md,README.md— document the Dart parser andlanguage: dartTest plan
dart test(9) anddart analyzeclean;dart formatappliednpm test(99) andnpm run typecheckpassSupabaseClientand members, correct constructor/getter/field kinds)Trade-offs
.sdk-parse-ignorematcher reimplements a documented subset of gitignore rather than reusing the npmignorepackage.exportdirectives, so a public-named declaration inlib/srccounts even if never exported (same altitude as the existing parsers).