Skip to content

Commit cd8a3bc

Browse files
committed
Merge branch 'swagger-consumes-produces' into optional-query-params
2 parents 0e5bc00 + 056acd9 commit cd8a3bc

4 files changed

Lines changed: 44 additions & 24 deletions

File tree

ConsumePlugin/GeneratedSwaggerAnonymousTypes.fs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ type Type1 =
2323
Name : string option
2424
}
2525

26+
[<JsonParse true ; JsonSerialize true>]
27+
type Type2147483647 =
28+
{
29+
[<System.Text.Json.Serialization.JsonExtensionData>]
30+
AdditionalProperties : System.Collections.Generic.Dictionary<string, System.Text.Json.Nodes.JsonNode>
31+
[<System.Text.Json.Serialization.JsonPropertyName "wouldOverflowASeededCounter">]
32+
WouldOverflowASeededCounter : string option
33+
}
34+
2635
[<JsonParse true ; JsonSerialize true>]
2736
type Type2 =
2837
{

ConsumePlugin/swagger-anonymous-types.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@
5050
"type": "string"
5151
}
5252
}
53+
},
54+
"Type2147483647": {
55+
"type": "object",
56+
"properties": {
57+
"wouldOverflowASeededCounter": {
58+
"type": "string"
59+
}
60+
}
5361
}
5462
},
5563
"responses": {}

WoofWare.Myriad.Plugins.Test/TestSwagger/TestSwaggerTypeRender.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ module TestSwaggerTypeRender =
2323
let ``defnToType respects integer formats`` (format : string option, expected : string) : unit =
2424
let result =
2525
SwaggerClientGenerator.defnToType
26-
(ref 0)
26+
(fun () -> failwith "no anonymous types expected")
2727
(Dictionary ())
2828
(Dictionary ())
2929
"definitions"

WoofWare.Myriad.Plugins/SwaggerClientGenerator.fs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,10 @@ module internal SwaggerClientGenerator =
7070
| SwaggerV2.Definition.File -> SynType.createLongIdent' [ "System" ; "IO" ; "Stream" ] |> Some
7171

7272
/// Returns None if we lacked the information required to do this.
73+
/// nextAnonymousTypeName must return a fresh unused type name on each call.
7374
/// bigCache is a map of e.g. {"securityDefinition": {Defn : F# type}}.
7475
let rec defnToType
75-
(anonymousTypeCount : int ref)
76+
(nextAnonymousTypeName : unit -> string)
7677
(handlesMap : Dictionary<string, TypeEntry>)
7778
(bigCache : Dictionary<string, Dictionary<SwaggerV2.Definition, TypeEntry>>)
7879
(thisKey : string)
@@ -155,7 +156,7 @@ module internal SwaggerClientGenerator =
155156
|> Some
156157
| None ->
157158

158-
let defn' = defnToType anonymousTypeCount handlesMap bigCache thisKey None defn
159+
let defn' = defnToType nextAnonymousTypeName handlesMap bigCache thisKey None defn
159160

160161
match defn' with
161162
| None -> None
@@ -201,7 +202,7 @@ module internal SwaggerClientGenerator =
201202
|> Some
202203
| Some SwaggerV2.AdditionalProperties.Never -> Some []
203204
| Some (SwaggerV2.AdditionalProperties.Constrained defn) ->
204-
let defn' = defnToType anonymousTypeCount handlesMap bigCache thisKey None defn
205+
let defn' = defnToType nextAnonymousTypeName handlesMap bigCache thisKey None defn
205206

206207
match defn' with
207208
| None -> None
@@ -235,7 +236,7 @@ module internal SwaggerClientGenerator =
235236

236237
let fSharpTypeName =
237238
match typeName with
238-
| None -> $"Type%i{Interlocked.Increment anonymousTypeCount}"
239+
| None -> nextAnonymousTypeName ()
239240
| Some typeName -> typeName
240241

241242
let properties = additionalProperties @ namedProperties
@@ -279,7 +280,8 @@ module internal SwaggerClientGenerator =
279280
defn |> Some
280281

281282
| SwaggerV2.Definition.Array elt ->
282-
let child = defnToType anonymousTypeCount handlesMap bigCache thisKey None elt.Items
283+
let child =
284+
defnToType nextAnonymousTypeName handlesMap bigCache thisKey None elt.Items
283285

284286
match child with
285287
| None -> None
@@ -555,35 +557,36 @@ module internal SwaggerV2Generator =
555557
(0, bigCache) ||> Seq.fold (fun count (KeyValue (_, v)) -> count + v.Count)
556558

557559
let byHandle = Dictionary ()
558-
let anonymousTypeCount = ref 0
559560

560561
// A spec is free to define types whose (sanitised) names look like the
561-
// "Type{N}" names we invent for anonymous inline schemas; start counting
562-
// past any such name so we never collide with them.
563-
let namedTypes =
564-
seq {
565-
for KeyValue (k, _) in contents.Definitions do
566-
yield k
567-
568-
for KeyValue (k, _) in contents.Responses do
569-
yield k
570-
}
562+
// "Type{N}" names we invent for anonymous inline schemas (including
563+
// pathological ones like "Type2147483647", which would overflow a
564+
// seeded counter); skip over any name that's already taken.
565+
let takenNames = HashSet<string> ()
566+
567+
for KeyValue (k, _) in contents.Definitions do
568+
takenNames.Add (Ident.createSanitisedTypeName k).idText |> ignore<bool>
569+
570+
for KeyValue (k, _) in contents.Responses do
571+
takenNames.Add (Ident.createSanitisedTypeName k).idText |> ignore<bool>
572+
573+
let anonymousTypeCount = ref 0
574+
575+
let nextAnonymousTypeName () : string =
576+
let mutable candidate = $"Type%i{Interlocked.Increment anonymousTypeCount}"
571577

572-
for name in namedTypes do
573-
let name = (Ident.createSanitisedTypeName name).idText
578+
while takenNames.Contains candidate do
579+
candidate <- $"Type%i{Interlocked.Increment anonymousTypeCount}"
574580

575-
if name.StartsWith ("Type", System.StringComparison.Ordinal) then
576-
match System.Int32.TryParse (name.Substring "Type".Length) with
577-
| true, n -> anonymousTypeCount.Value <- max anonymousTypeCount.Value n
578-
| false, _ -> ()
581+
candidate
579582

580583
let rec go (contents : ((string option * SwaggerV2.Definition) * string) list) =
581584
let lastRound = countAll ()
582585

583586
contents
584587
|> List.filter (fun ((name, defn), defnClass) ->
585588
let doIt =
586-
SwaggerClientGenerator.defnToType anonymousTypeCount byHandle bigCache defnClass name defn
589+
SwaggerClientGenerator.defnToType nextAnonymousTypeName byHandle bigCache defnClass name defn
587590

588591
match doIt with
589592
| None -> true

0 commit comments

Comments
 (0)