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.
4 tasks
grdsdev
pushed a commit
that referenced
this pull request
Aug 12, 2026
🤖 I have created a release *beep* *boop* --- ## [1.0.0](v1.0.0...v1.0.0) (2026-08-12) ### ⚠ BREAKING CHANGES * reconcile capability matrix inconsistencies from skill audit ([#74](#74)) ### Features * add capabilities based on supabase-js public methods ([#19](#19)) ([8b07e38](8b07e38)) * add capability-matrix maintenance skill ([#73](#73)) ([070e2c9](070e2c9)) * add review-spec and review-spec-compliance skills ([#6](#6)) ([b2646c1](b2646c1)) * add SDK implementation status matrix to README and skill ([#4](#4)) ([753f06c](753f06c)) * **api-check:** include file path and line number in compliance failure messages ([#45](#45)) ([2f4be47](2f4be47)) * **auth:** add sign-out reason capability ([#47](#47)) ([51a3abd](51a3abd)) * canonical SDK capability matrix ([#8](#8)) ([215bc3e](215bc3e)) * **capability-matrix:** strict cross-SDK parity score + coverage scope ([#63](#63)) ([de1abe1](de1abe1)) * CI check 1 — block PRs adding public API not in capability matrix ([#31](#31)) ([293440c](293440c)) * **compliance:** list undeclared features after validation ([#48](#48)) ([29f396a](29f396a)) * **compliance:** list undeclared features as notes after validation ([29f396a](29f396a)) * **compliance:** split symbol evidence from symbol coverage ([#75](#75)) ([abc8e71](abc8e71)) * initial SDK specs, skills, and install script ([e662b17](e662b17)) * move SDK compliance to per-repo files ([#15](#15)) ([4d32675](4d32675)) * **parsers:** add Dart public API parser via package:analyzer (alternative to [#35](#35)) ([#41](#41)) ([e3ba07a](e3ba07a)) * **parsers:** add griffe-based Python public API surface parser ([#36](#36)) ([c44f836](c44f836)) * **parsers:** replace Swift regex parser with swift-symbolgraph-extract ([#38](#38)) ([80529a7](80529a7)) * **realtime:** add multiple postgres_changes filters capability ([#70](#70)) ([825ab0c](825ab0c)) * reconcile capability matrix inconsistencies from skill audit ([#74](#74)) ([9c53a70](9c53a70)) * rename sdk-parse-ignore to .sdk-parse-ignore ([#37](#37)) ([4f4ab61](4f4ab61)) * render symbol names as clickable links in capability matrix ([#14](#14)) ([dcaf122](dcaf122)) * show feature description as visible sub-text in capability matrix ([#13](#13)) ([3a750ab](3a750ab)) * **site:** serve compliance.json with precomputed parity from GitHub Pages ([#46](#46)) ([0d9106c](0d9106c)) * **storage:** add purge_cache and purge_bucket_cache canonical capabilities ([#44](#44)) ([9a6f864](9a6f864)) * **storage:** add storage.errors.error_codes capability ([#71](#71)) ([fabb9a7](fabb9a7)) * **storage:** add the five missing Iceberg catalog capabilities ([#76](#76)) ([c3c8f9e](c3c8f9e)) ### Bug Fixes * **aggregate:** point csharp and go SDKs at correct repo slugs ([#62](#62)) ([8b7320f](8b7320f)) * **aggregate:** point kotlin SDK at supabase-community/supabase-kt ([#61](#61)) ([b1a99e9](b1a99e9)) * **capability-matrix:** correct coverage scope metric description ([#64](#64)) ([5daeaf5](5daeaf5)) * **ci:** repair python pipeline and simplify sdk-compliance workflow ([#42](#42)) ([2140f44](2140f44)) * **ci:** use nx to run docs:json so workspace deps are built first ([#56](#56)) ([9b449bb](9b449bb)) * **dart-extractor:** exclude [@internal-annotated](https://github.com/internal-annotated) symbols from the public API surface ([9bd358e](9bd358e)) * **dart-extractor:** exclude [@internal](https://github.com/internal) symbols from the public API surface ([#54](#54)) ([9bd358e](9bd358e)) * remove broken sticky thead, add scroll-margin-top and group-row borders ([#10](#10)) ([68761cd](68761cd)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: supabase-releaser[bot] <223506987+supabase-releaser[bot]@users.noreply.github.com>
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).