feat(parsers): add Dart/Flutter public API surface parser via dartdoc_json#35
Closed
grdsdev wants to merge 15 commits into
Closed
feat(parsers): add Dart/Flutter public API surface parser via dartdoc_json#35grdsdev wants to merge 15 commits into
grdsdev wants to merge 15 commits into
Conversation
Adds a line-by-line regex-based Dart parser following the same design as swift-parser.ts. Key differences from the Swift parser: Dart has no public access modifier (privacy is _prefix), so member extraction is gated to the immediate class-body brace depth to prevent method calls inside method bodies from producing false symbols. Handles: classes (abstract/final/sealed/mixin), enums, mixins, named extensions, typedefs, getters, setters, factory constructors, and regular methods/constructors. Skips build_runner generated files (*.g.dart, *.freezed.dart, etc.) and respects sdk-parse-ignore. Scans lib/ by convention (Dart public library root). Two production bugs fixed vs initial draft (verified against supabase-flutter): - @annotation(params) on its own line no longer emits false symbols - Multi-line arrow function continuations no longer emit false symbols from constructor calls in toString()/copyWith() bodies 139 tests pass (36 new + 103 existing). Linear: SDK-991
Linear: SDK-991
3 tasks
spydon
reviewed
Jun 19, 2026
spydon
left a comment
Contributor
There was a problem hiding this comment.
I don't think we should handroll this, we could use something like dartdoc_json --output api_members.json --root and just parse that file instead
dartdoc_json 0.5.0 throws AssertionError on extension type declarations (verified empirically), so "extension_type" never appears in its output and the matching branches were dead code. Removed from CLASS_LIKE and resolveTopKind, with a comment explaining why. Added "enum" to CLASS_LIKE so methods/getters on Dart 3+ enhanced enums are emitted as symbols instead of being silently dropped. supabase-flutter does not use extension types in its public API surface. Added two tests covering enum member emission (method and getter kinds).
dart pub get fails with exit 69 on Flutter packages (supabase_flutter) because they require the Flutter toolchain. Replace dart-lang/setup-dart with subosito/flutter-action and use flutter pub get universally — it works for both pure-Dart and Flutter packages in the monorepo.
dartdoc_json can emit units without a declarations array for certain Flutter package artifacts. Guard with ?? [] to skip them gracefully. Also mark the field optional in the DartdocUnit interface.
grdsdev
added a commit
to supabase/supabase-flutter
that referenced
this pull request
Jun 19, 2026
4 tasks
3 tasks
grdsdev
pushed a commit
that referenced
this pull request
Jun 22, 2026
…native to #35) (#41) * feat(parsers): add Dart public API parser via package:analyzer 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. * ci: run dart_symbol_extractor format, analyze and test in capability CI * ci: install Dart SDK via direct download instead of marketplace action 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. * fix(dart-parser): correct class-type-alias kind and directory ignores 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. * refactor: use dart-lang/setup-dart action and drop SymbolKind extension 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. * Fix alignment * docs: remove design spec doc * refactor(dart-parser): collapse container dispatch with pattern matching 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. * refactor: move dart_symbol_extractor up to scripts/ 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. * ci: invoke dart extractor directly, drop parse-dart npm script 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.
grdsdev
added a commit
to supabase/supabase-flutter
that referenced
this pull request
Jun 22, 2026
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
Adds Dart/Flutter public API surface parsing to the SDK compliance workflow, using
dartdoc_json— a tool that runs the real Dart analyzer — instead of a handrolled regex parser.Part of SDK-991. The reusable compliance workflow (
validate-sdk-compliance.yml) already supportslanguage: dart; this PR wires up the full implementation so supabase-flutter PRs are gated correctly.Approach
A thin Node.js normalizer (
normalize-dartdoc.ts) readsdartdoc_jsonJSON output and emits theParseResultshape consumed bycheck-api-symbols. The CI workflow runsdartdoc_jsonper package, merges outputs withjq, then calls the normalizer CLI. Everything downstream (check-api-symbols, compliance validation) is unchanged.Changes
Added
src/normalize-dartdoc.ts— core normalizer:DartdocUnit[]→ParseResultsrc/normalize-dartdoc-cli.ts— CLI entry point (npm run normalize-dartdoc <path>)test/normalize-dartdoc.test.ts— 20 tests (class/mixin/enum/extension kinds, constructor naming, getters/setters, privacy filter, multi-unit flattening, enum methods)test/fixtures/dartdoc-sample.json— realdartdoc_jsonoutput used as test fixturedocs/specs/2026-06-19-dart-parser-dartdoc-json.md— design specRemoved
src/dart-parser.ts,src/parse-dart.ts— handrolled regex parsertest/dart-parser.test.ts,test/fixtures/dart-sample/— regex parser testsModified
.github/workflows/validate-sdk-compliance.yml— Dart-conditional steps: Flutter SDK setup,dartdoc_jsonactivation, per-package generation withflutter pub get,jqmerge,normalize-dartdocdispatchpackage.json—normalize-dartdocreplacesparse-dartWhy dartdoc_json over the regex parser
The regex parser required depth-tracking, arrow-continuation state, annotation-line suppression, and two production bug fixes before its first real use. Root cause: regex cannot reliably parse Dart without understanding the language.
dartdoc_jsonuses the real Dart analyzer and gets it right by construction.Correctness notes:
extension type(Dart 3.3+):dartdoc_json0.5.0 does not support extension types — it throws on them. The normalizer has no deadextension_typehandling. Verified empirically; supabase-flutter does not currently use extension types in its public API."enum"is included in the set of class-like declarations whosemembersare iterated.subosito/flutter-action(notdart-lang/setup-dart) andflutter pub get(notdart pub get) to handle the mix of pure-Dart and Flutter packages in supabase-flutter.declarationsfield are skipped gracefully (some Flutter build artifacts emit incomplete units).Test plan
npm test)npm run typecheck)dartdoc_json0.5.0 output (not hand-authored)validateandcheckjobs green) against this branchCloses SDK-991