Skip to content

refactor: fork the URI and URL engines behind static dispatch#59

Merged
OmarAlJarrah merged 7 commits into
mainfrom
refactor/eliminate-profile-dispatchers
Jul 10, 2026
Merged

refactor: fork the URI and URL engines behind static dispatch#59
OmarAlJarrah merged 7 commits into
mainfrom
refactor/eliminate-profile-dispatchers

Conversation

@OmarAlJarrah

Copy link
Copy Markdown
Member

Three internal files — the host parser, the IPv4 parser, and the recomposition
serializer — were each a single object that took a profile argument and branched
if (profile.isWhatwg) … else … at runtime to serve both the RFC 3986 (URI) and
the WHATWG (URL) code paths. Every caller of those objects is single-profile, so
that runtime branch was hidden control flow with no benefit.

This forks each of the three into a per-spec unit and lets each caller dispatch
statically:

  • SerializerUriSerializer + UrlSerializer, with the shared authority and
    query/fragment helpers hoisted into SerializeShared.
  • Ipv4Ipv4Rfc3986 + Ipv4Whatwg; the shared serialization, octet packing,
    and endsInANumber remain on Ipv4.
  • HostParserUriHostParser + UrlHostParser, with the shared bracket helpers
    in HostParsing.

The paired spec units never reference each other — genuinely shared code lives in
the three neutral files above — so a change to the URL path can no longer silently
affect the URI path, and vice versa.

With the three dispatchers gone, the ParseProfile enum had no remaining callers
and is removed. Separately, the shared path model UrlPath — used by the URI path,
the reference resolver, and the normalizer as well as by URL parsing — is renamed
ComponentPath so its name no longer implies it is WHATWG-specific. As a small
cleanup, a duplicate private SLASH constant in UriNormalizer is dropped in favour
of the shared one introduced by the serializer split.

No behaviour change and no public API change: every moved function body is preserved
verbatim, the full existing conformance suite (URL, URI, host, IDNA, serializer,
resolver, IPv4) passes unchanged, the binary-compatibility snapshots are untouched
(apiCheck clean), and there are no generated-table or codegen edits.

The host parser and the recomposition serializer were each forked into
per-spec units (UriHostParser/UrlHostParser, UriSerializer/UrlSerializer),
but their tests stayed as single combined files still named after the
removed unified types. Split each to match the source:

- HostParserTest -> UriHostParserTest + UrlHostParserTest
- SerializerTest -> UriSerializerTest + UrlSerializerTest + SerializeSharedTest
  (the last covering the shared authority serializer)

Every test moves verbatim; the split is a clean partition since each case
exercises exactly one parser/serializer.

Also move the shared IP-literal bracket delimiters (BRACKET_OPEN/BRACKET_CLOSE)
into the neutral HostParsing file so the two host parsers reference one
definition instead of each keeping a private copy. NOT_FOUND stays file-private
per the existing per-file sentinel convention in the host package.

No behaviour change and no public API change.
@OmarAlJarrah OmarAlJarrah merged commit 05ff68e into main Jul 10, 2026
10 checks passed
@OmarAlJarrah OmarAlJarrah deleted the refactor/eliminate-profile-dispatchers branch July 10, 2026 22:55
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.

1 participant