@@ -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