@@ -69,9 +69,10 @@ module internal SwaggerClientGenerator =
6969 | SwaggerV2.Definition.File -> SynType.createLongIdent' [ " System" ; " IO" ; " Stream" ] |> Some
7070
7171 /// Returns None if we lacked the information required to do this.
72+ /// nextAnonymousTypeName must return a fresh unused type name on each call.
7273 /// bigCache is a map of e.g. {"securityDefinition": {Defn : F# type}}.
7374 let rec defnToType
74- ( anonymousTypeCount : int ref )
75+ ( nextAnonymousTypeName : unit -> string )
7576 ( handlesMap : Dictionary < string , TypeEntry >)
7677 ( bigCache : Dictionary < string , Dictionary < SwaggerV2.Definition , TypeEntry >>)
7778 ( thisKey : string )
@@ -154,7 +155,7 @@ module internal SwaggerClientGenerator =
154155 |> Some
155156 | None ->
156157
157- let defn ' = defnToType anonymousTypeCount handlesMap bigCache thisKey None defn
158+ let defn ' = defnToType nextAnonymousTypeName handlesMap bigCache thisKey None defn
158159
159160 match defn' with
160161 | None -> None
@@ -200,7 +201,7 @@ module internal SwaggerClientGenerator =
200201 |> Some
201202 | Some SwaggerV2.AdditionalProperties.Never -> Some []
202203 | Some ( SwaggerV2.AdditionalProperties.Constrained defn) ->
203- let defn ' = defnToType anonymousTypeCount handlesMap bigCache thisKey None defn
204+ let defn ' = defnToType nextAnonymousTypeName handlesMap bigCache thisKey None defn
204205
205206 match defn' with
206207 | None -> None
@@ -234,7 +235,7 @@ module internal SwaggerClientGenerator =
234235
235236 let fSharpTypeName =
236237 match typeName with
237- | None -> $ " Type %i {Interlocked.Increment anonymousTypeCount} "
238+ | None -> nextAnonymousTypeName ()
238239 | Some typeName -> typeName
239240
240241 let properties = additionalProperties @ namedProperties
@@ -278,7 +279,8 @@ module internal SwaggerClientGenerator =
278279 defn |> Some
279280
280281 | SwaggerV2.Definition.Array elt ->
281- let child = defnToType anonymousTypeCount handlesMap bigCache thisKey None elt.Items
282+ let child =
283+ defnToType nextAnonymousTypeName handlesMap bigCache thisKey None elt.Items
282284
283285 match child with
284286 | None -> None
@@ -540,35 +542,36 @@ module internal SwaggerV2Generator =
540542 ( 0 , bigCache) ||> Seq.fold ( fun count ( KeyValue ( _ , v )) -> count + v.Count)
541543
542544 let byHandle = Dictionary ()
543- let anonymousTypeCount = ref 0
544545
545546 // A spec is free to define types whose (sanitised) names look like the
546- // "Type{N}" names we invent for anonymous inline schemas; start counting
547- // past any such name so we never collide with them.
548- let namedTypes =
549- seq {
550- for KeyValue ( k, _) in contents.Definitions do
551- yield k
552-
553- for KeyValue ( k, _) in contents.Responses do
554- yield k
555- }
547+ // "Type{N}" names we invent for anonymous inline schemas (including
548+ // pathological ones like "Type2147483647", which would overflow a
549+ // seeded counter); skip over any name that's already taken.
550+ let takenNames = HashSet< string> ()
551+
552+ for KeyValue ( k, _) in contents.Definitions do
553+ takenNames.Add ( Ident.createSanitisedTypeName k) .idText |> ignore< bool>
554+
555+ for KeyValue ( k, _) in contents.Responses do
556+ takenNames.Add ( Ident.createSanitisedTypeName k) .idText |> ignore< bool>
557+
558+ let anonymousTypeCount = ref 0
559+
560+ let nextAnonymousTypeName () : string =
561+ let mutable candidate = $" Type%i {Interlocked.Increment anonymousTypeCount}"
556562
557- for name in namedTypes do
558- let name = ( Ident.createSanitisedTypeName name ) .idText
563+ while takenNames.Contains candidate do
564+ candidate <- $ " Type %i {Interlocked.Increment anonymousTypeCount} "
559565
560- if name.StartsWith ( " Type" , System.StringComparison.Ordinal) then
561- match System.Int32.TryParse ( name.Substring " Type" .Length) with
562- | true , n -> anonymousTypeCount.Value <- max anonymousTypeCount.Value n
563- | false , _ -> ()
566+ candidate
564567
565568 let rec go ( contents : (( string option * SwaggerV2.Definition ) * string ) list ) =
566569 let lastRound = countAll ()
567570
568571 contents
569572 |> List.filter ( fun (( name , defn ), defnClass ) ->
570573 let doIt =
571- SwaggerClientGenerator.defnToType anonymousTypeCount byHandle bigCache defnClass name defn
574+ SwaggerClientGenerator.defnToType nextAnonymousTypeName byHandle bigCache defnClass name defn
572575
573576 match doIt with
574577 | None -> true
0 commit comments