Skip to content

Resolve map-types for selectors and slice elements#109

Merged
seanogdev merged 2 commits intomasterfrom
fix/maptype-resolve-selectors-and-slices
Apr 23, 2026
Merged

Resolve map-types for selectors and slice elements#109
seanogdev merged 2 commits intomasterfrom
fix/maptype-resolve-selectors-and-slices

Conversation

@seanogdev
Copy link
Copy Markdown
Contributor

@seanogdev seanogdev commented Apr 23, 2026

What this does

map-types config entries only applied to bare-ident struct fields. Two other paths silently ignored them, so custom scalar wrappers (e.g. a view.Date that marshals as a JSON string) still rendered as $refs to an object definition in the generated spec.

  • fieldToSchema's *ast.SelectorExpr branch looked up map-types with the short package alias (view.Date) and never retried with the resolved full import path, so fully-qualified config keys never matched cross-package selector references.
  • resolveArray never called MapType at all — slice elements like []view.Date or []Date always fell through to a $ref, regardless of config.

Fix

  • In fieldToSchema's selector branch, after findType resolves the full import path, retry via applyMapType with the fully-qualified key and return early on a hit.
  • In resolveArray, thread an importPath through both the ident branch (from ref.Package) and the selector branch (from findType), then try MapType against both the short and fully-qualified keys before falling back to $ref.

Net effect: a single config entry — in either form — now consistently covers the four reference shapes (single ident, single selector, slice ident, slice selector).

Before / after

Config:

map-types:
  net/mail.Address: string
  a.bar: string

Given:

type mapped struct {
    b        bar            // ident
    bSlice   []bar          // slice of ident
    pkg      mail.Address   // selector
    pkgSlice []mail.Address // slice of selector
}

Before

b:
  type: string
bSlice:
  type: array
  items:
    $ref: '#/definitions/a.bar'
pkg:
  $ref: '#/definitions/mail.Address'
pkgSlice:
  type: array
  items:
    $ref: '#/definitions/mail.Address'

After

b:
  type: string
bSlice:
  type: array
  items:
    type: string
pkg:
  type: string
pkgSlice:
  type: array
  items:
    type: string

Tests

  • go test ./... passes.
  • New TestFieldToProperty/mapped types subtest covers both short-form and fully-qualified config keys against all four reference shapes, via a new mapped struct in testdata.

fieldToSchema's SelectorExpr branch only tried the short-alias key
(e.g. "view.Date") when looking up map-types, so fully-qualified
config entries like "github.com/foo/bar/view.Date" never matched
cross-package references. resolveArray never called MapType at all,
so []view.Date / []Date slice fields always fell through to $ref
even when the element type was configured as a primitive.

Retry MapType with the resolved full import path in fieldToSchema's
SelectorExpr branch, and add a MapType check in resolveArray for
both the pkg-qualified and fully-qualified keys before the $ref
fallback.
@coveralls
Copy link
Copy Markdown

coveralls commented Apr 23, 2026

Coverage Report for CI Build 24845660006

Coverage increased (+1.0%) to 52.998%

Details

  • Coverage increased (+1.0%) from the base build.
  • Patch coverage: 8 uncovered changes across 1 file (26 of 34 lines covered, 76.47%).
  • 1 coverage regression across 1 file.

Uncovered Changes

File Changed Covered %
docparse/jsonschema.go 34 26 76.47%

Coverage Regressions

1 previously-covered line in 1 file lost coverage.

File Lines Losing Coverage Coverage
docparse/jsonschema.go 1 44.54%

Coverage Stats

Coverage Status
Relevant Lines: 2168
Covered Lines: 1149
Line Coverage: 53.0%
Coverage Strength: 44.44 hits per line

💛 - Coveralls

The SelectorExpr case used `t == ""` / `t != ""` gating around the
canonicalType check, then re-tested `t` again afterwards. Collapsing
both into a single early-return via applyMapType keeps behaviour
identical and brings gocyclo back under the linter threshold after
adding the full-path retry.
@seanogdev seanogdev merged commit 6a53c38 into master Apr 23, 2026
3 checks passed
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.

3 participants