mirror of
https://github.com/Smaug123/WoofWare.Myriad
synced 2025-10-06 20:48:40 +00:00
Compare commits
4 Commits
WoofWare.M
...
WoofWare.M
Author | SHA1 | Date | |
---|---|---|---|
|
e3081c3136 | ||
|
232d2ba5ec | ||
|
f7458f521e | ||
|
bfc25a672b |
@@ -3,7 +3,7 @@
|
|||||||
"isRoot": true,
|
"isRoot": true,
|
||||||
"tools": {
|
"tools": {
|
||||||
"fantomas": {
|
"fantomas": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.3",
|
||||||
"commands": [
|
"commands": [
|
||||||
"fantomas"
|
"fantomas"
|
||||||
]
|
]
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
namespace SomeNamespace
|
namespace SomeNamespace
|
||||||
|
|
||||||
|
open System
|
||||||
open WoofWare.Myriad.Plugins
|
open WoofWare.Myriad.Plugins
|
||||||
|
|
||||||
/// Mock record type for an interface
|
/// Mock record type for an interface
|
||||||
@@ -25,10 +26,11 @@ type internal PublicTypeMock =
|
|||||||
|
|
||||||
interface IPublicType with
|
interface IPublicType with
|
||||||
member this.Mem1 (arg_0_0, arg_0_1) = this.Mem1 (arg_0_0, arg_0_1)
|
member this.Mem1 (arg_0_0, arg_0_1) = this.Mem1 (arg_0_0, arg_0_1)
|
||||||
member this.Mem2 (arg_0_0) = this.Mem2 (arg_0_0)
|
member this.Mem2 arg_0_0 = this.Mem2 (arg_0_0)
|
||||||
member this.Mem3 (arg_0_0, arg_0_1) = this.Mem3 (arg_0_0, arg_0_1)
|
member this.Mem3 (arg_0_0, arg_0_1) = this.Mem3 (arg_0_0, arg_0_1)
|
||||||
namespace SomeNamespace
|
namespace SomeNamespace
|
||||||
|
|
||||||
|
open System
|
||||||
open WoofWare.Myriad.Plugins
|
open WoofWare.Myriad.Plugins
|
||||||
|
|
||||||
/// Mock record type for an interface
|
/// Mock record type for an interface
|
||||||
@@ -49,10 +51,11 @@ type public PublicTypeInternalFalseMock =
|
|||||||
|
|
||||||
interface IPublicTypeInternalFalse with
|
interface IPublicTypeInternalFalse with
|
||||||
member this.Mem1 (arg_0_0, arg_0_1) = this.Mem1 (arg_0_0, arg_0_1)
|
member this.Mem1 (arg_0_0, arg_0_1) = this.Mem1 (arg_0_0, arg_0_1)
|
||||||
member this.Mem2 (arg_0_0) = this.Mem2 (arg_0_0)
|
member this.Mem2 arg_0_0 = this.Mem2 (arg_0_0)
|
||||||
member this.Mem3 (arg_0_0, arg_0_1) = this.Mem3 (arg_0_0, arg_0_1)
|
member this.Mem3 (arg_0_0, arg_0_1) = this.Mem3 (arg_0_0, arg_0_1)
|
||||||
namespace SomeNamespace
|
namespace SomeNamespace
|
||||||
|
|
||||||
|
open System
|
||||||
open WoofWare.Myriad.Plugins
|
open WoofWare.Myriad.Plugins
|
||||||
|
|
||||||
/// Mock record type for an interface
|
/// Mock record type for an interface
|
||||||
@@ -71,9 +74,10 @@ type internal InternalTypeMock =
|
|||||||
|
|
||||||
interface InternalType with
|
interface InternalType with
|
||||||
member this.Mem1 (arg_0_0, arg_0_1) = this.Mem1 (arg_0_0, arg_0_1)
|
member this.Mem1 (arg_0_0, arg_0_1) = this.Mem1 (arg_0_0, arg_0_1)
|
||||||
member this.Mem2 (arg_0_0) = this.Mem2 (arg_0_0)
|
member this.Mem2 arg_0_0 = this.Mem2 (arg_0_0)
|
||||||
namespace SomeNamespace
|
namespace SomeNamespace
|
||||||
|
|
||||||
|
open System
|
||||||
open WoofWare.Myriad.Plugins
|
open WoofWare.Myriad.Plugins
|
||||||
|
|
||||||
/// Mock record type for an interface
|
/// Mock record type for an interface
|
||||||
@@ -92,9 +96,10 @@ type private PrivateTypeMock =
|
|||||||
|
|
||||||
interface PrivateType with
|
interface PrivateType with
|
||||||
member this.Mem1 (arg_0_0, arg_0_1) = this.Mem1 (arg_0_0, arg_0_1)
|
member this.Mem1 (arg_0_0, arg_0_1) = this.Mem1 (arg_0_0, arg_0_1)
|
||||||
member this.Mem2 (arg_0_0) = this.Mem2 (arg_0_0)
|
member this.Mem2 arg_0_0 = this.Mem2 (arg_0_0)
|
||||||
namespace SomeNamespace
|
namespace SomeNamespace
|
||||||
|
|
||||||
|
open System
|
||||||
open WoofWare.Myriad.Plugins
|
open WoofWare.Myriad.Plugins
|
||||||
|
|
||||||
/// Mock record type for an interface
|
/// Mock record type for an interface
|
||||||
@@ -113,9 +118,10 @@ type private PrivateTypeInternalFalseMock =
|
|||||||
|
|
||||||
interface PrivateTypeInternalFalse with
|
interface PrivateTypeInternalFalse with
|
||||||
member this.Mem1 (arg_0_0, arg_0_1) = this.Mem1 (arg_0_0, arg_0_1)
|
member this.Mem1 (arg_0_0, arg_0_1) = this.Mem1 (arg_0_0, arg_0_1)
|
||||||
member this.Mem2 (arg_0_0) = this.Mem2 (arg_0_0)
|
member this.Mem2 arg_0_0 = this.Mem2 (arg_0_0)
|
||||||
namespace SomeNamespace
|
namespace SomeNamespace
|
||||||
|
|
||||||
|
open System
|
||||||
open WoofWare.Myriad.Plugins
|
open WoofWare.Myriad.Plugins
|
||||||
|
|
||||||
/// Mock record type for an interface
|
/// Mock record type for an interface
|
||||||
@@ -131,9 +137,10 @@ type internal VeryPublicTypeMock<'a, 'b> =
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface VeryPublicType<'a, 'b> with
|
interface VeryPublicType<'a, 'b> with
|
||||||
member this.Mem1 (arg_0_0) = this.Mem1 (arg_0_0)
|
member this.Mem1 arg_0_0 = this.Mem1 (arg_0_0)
|
||||||
namespace SomeNamespace
|
namespace SomeNamespace
|
||||||
|
|
||||||
|
open System
|
||||||
open WoofWare.Myriad.Plugins
|
open WoofWare.Myriad.Plugins
|
||||||
|
|
||||||
/// Mock record type for an interface
|
/// Mock record type for an interface
|
||||||
@@ -159,9 +166,9 @@ type internal CurriedMock<'a> =
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Curried<'a> with
|
interface Curried<'a> with
|
||||||
member this.Mem1 (arg_0_0) (arg_1_0) = this.Mem1 (arg_0_0) (arg_1_0)
|
member this.Mem1 arg_0_0 arg_1_0 = this.Mem1 (arg_0_0) (arg_1_0)
|
||||||
member this.Mem2 (arg_0_0, arg_0_1) (arg_1_0) = this.Mem2 (arg_0_0, arg_0_1) (arg_1_0)
|
member this.Mem2 (arg_0_0, arg_0_1) arg_1_0 = this.Mem2 (arg_0_0, arg_0_1) (arg_1_0)
|
||||||
member this.Mem3 ((arg_0_0, arg_0_1)) (arg_1_0) = this.Mem3 (arg_0_0, arg_0_1) (arg_1_0)
|
member this.Mem3 ((arg_0_0, arg_0_1)) arg_1_0 = this.Mem3 (arg_0_0, arg_0_1) (arg_1_0)
|
||||||
|
|
||||||
member this.Mem4 ((arg_0_0, arg_0_1)) ((arg_1_0, arg_1_1)) =
|
member this.Mem4 ((arg_0_0, arg_0_1)) ((arg_1_0, arg_1_1)) =
|
||||||
this.Mem4 (arg_0_0, arg_0_1) (arg_1_0, arg_1_1)
|
this.Mem4 (arg_0_0, arg_0_1) (arg_1_0, arg_1_1)
|
||||||
@@ -171,3 +178,31 @@ type internal CurriedMock<'a> =
|
|||||||
|
|
||||||
member this.Mem6 (arg_0_0, arg_0_1) (arg_1_0, arg_1_1) =
|
member this.Mem6 (arg_0_0, arg_0_1) (arg_1_0, arg_1_1) =
|
||||||
this.Mem6 (arg_0_0, arg_0_1) (arg_1_0, arg_1_1)
|
this.Mem6 (arg_0_0, arg_0_1) (arg_1_0, arg_1_1)
|
||||||
|
namespace SomeNamespace
|
||||||
|
|
||||||
|
open System
|
||||||
|
open WoofWare.Myriad.Plugins
|
||||||
|
|
||||||
|
/// Mock record type for an interface
|
||||||
|
type internal TypeWithInterfaceMock =
|
||||||
|
{
|
||||||
|
/// Implementation of IDisposable.Dispose
|
||||||
|
Dispose : unit -> unit
|
||||||
|
Mem1 : string option -> string[] Async
|
||||||
|
Mem2 : unit -> string[] Async
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An implementation where every method throws.
|
||||||
|
static member Empty : TypeWithInterfaceMock =
|
||||||
|
{
|
||||||
|
Dispose = (fun _ -> ())
|
||||||
|
Mem1 = (fun x -> raise (System.NotImplementedException "Unimplemented mock function"))
|
||||||
|
Mem2 = (fun x -> raise (System.NotImplementedException "Unimplemented mock function"))
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TypeWithInterface with
|
||||||
|
member this.Mem1 arg_0_0 = this.Mem1 (arg_0_0)
|
||||||
|
member this.Mem2 () = this.Mem2 (())
|
||||||
|
|
||||||
|
interface System.IDisposable with
|
||||||
|
member this.Dispose () : unit = this.Dispose ()
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
namespace SomeNamespace
|
namespace SomeNamespace
|
||||||
|
|
||||||
|
open System
|
||||||
open WoofWare.Myriad.Plugins
|
open WoofWare.Myriad.Plugins
|
||||||
|
|
||||||
[<GenerateMock>]
|
[<GenerateMock>]
|
||||||
@@ -41,3 +42,9 @@ type Curried<'a> =
|
|||||||
abstract Mem4 : (int * string) -> ('a * int) -> string
|
abstract Mem4 : (int * string) -> ('a * int) -> string
|
||||||
abstract Mem5 : x : int * string -> ('a * int) -> string
|
abstract Mem5 : x : int * string -> ('a * int) -> string
|
||||||
abstract Mem6 : int * string -> y : 'a * int -> string
|
abstract Mem6 : int * string -> y : 'a * int -> string
|
||||||
|
|
||||||
|
[<GenerateMock>]
|
||||||
|
type TypeWithInterface =
|
||||||
|
inherit IDisposable
|
||||||
|
abstract Mem1 : string option -> string[] Async
|
||||||
|
abstract Mem2 : unit -> string[] Async
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
namespace WoofWare.Myriad.Plugins
|
namespace WoofWare.Myriad.Plugins
|
||||||
|
|
||||||
|
open System.IO
|
||||||
open Fantomas.FCS.Syntax
|
open Fantomas.FCS.Syntax
|
||||||
open Fantomas.FCS.SyntaxTrivia
|
open Fantomas.FCS.SyntaxTrivia
|
||||||
open Fantomas.FCS.Text.Range
|
open Fantomas.FCS.Text.Range
|
||||||
@@ -54,6 +55,7 @@ type internal InterfaceType =
|
|||||||
{
|
{
|
||||||
Attributes : SynAttribute list
|
Attributes : SynAttribute list
|
||||||
Name : LongIdent
|
Name : LongIdent
|
||||||
|
Inherits : SynType list
|
||||||
Members : MemberInfo list
|
Members : MemberInfo list
|
||||||
Properties : PropertyInfo list
|
Properties : PropertyInfo list
|
||||||
Generics : SynTyparDecls option
|
Generics : SynTyparDecls option
|
||||||
@@ -131,6 +133,11 @@ module internal AstHelper =
|
|||||||
// TODO: consider Microsoft.FSharp.Option or whatever it is
|
// TODO: consider Microsoft.FSharp.Option or whatever it is
|
||||||
| _ -> false
|
| _ -> false
|
||||||
|
|
||||||
|
let isUnitIdent (ident : SynLongIdent) : bool =
|
||||||
|
match ident.LongIdent with
|
||||||
|
| [ i ] when System.String.Equals (i.idText, "unit", System.StringComparison.OrdinalIgnoreCase) -> true
|
||||||
|
| _ -> false
|
||||||
|
|
||||||
let isListIdent (ident : SynLongIdent) : bool =
|
let isListIdent (ident : SynLongIdent) : bool =
|
||||||
match ident.LongIdent with
|
match ident.LongIdent with
|
||||||
| [ i ] when System.String.Equals (i.idText, "list", System.StringComparison.OrdinalIgnoreCase) -> true
|
| [ i ] when System.String.Equals (i.idText, "list", System.StringComparison.OrdinalIgnoreCase) -> true
|
||||||
@@ -342,7 +349,18 @@ module internal AstHelper =
|
|||||||
}
|
}
|
||||||
|> List.singleton
|
|> List.singleton
|
||||||
}
|
}
|
||||||
| _ -> failwith $"Unrecognised args in interface method declaration: %+A{args}"
|
| arg ->
|
||||||
|
{
|
||||||
|
HasParen = false
|
||||||
|
Args =
|
||||||
|
{
|
||||||
|
Attributes = []
|
||||||
|
IsOptional = false
|
||||||
|
Id = None
|
||||||
|
Type = arg
|
||||||
|
}
|
||||||
|
|> List.singleton
|
||||||
|
}
|
||||||
|> fun ty ->
|
|> fun ty ->
|
||||||
{ ty with
|
{ ty with
|
||||||
HasParen = ty.HasParen || hasParen
|
HasParen = ty.HasParen || hasParen
|
||||||
@@ -386,22 +404,26 @@ module internal AstHelper =
|
|||||||
|
|
||||||
let attrs = attrs |> List.collect (fun s -> s.Attributes)
|
let attrs = attrs |> List.collect (fun s -> s.Attributes)
|
||||||
|
|
||||||
let members, properties =
|
let members, inherits =
|
||||||
match synTypeDefnRepr with
|
match synTypeDefnRepr with
|
||||||
| SynTypeDefnRepr.ObjectModel (_kind, members, _) ->
|
| SynTypeDefnRepr.ObjectModel (_kind, members, _) ->
|
||||||
members
|
members
|
||||||
|> List.map (fun defn ->
|
|> List.map (fun defn ->
|
||||||
match defn with
|
match defn with
|
||||||
| SynMemberDefn.AbstractSlot (slotSig, flags, _, _) -> parseMember slotSig flags
|
| SynMemberDefn.AbstractSlot (slotSig, flags, _, _) -> Choice1Of2 (parseMember slotSig flags)
|
||||||
|
| SynMemberDefn.Inherit (baseType, _asIdent, _) -> Choice2Of2 baseType
|
||||||
| _ -> failwith $"Unrecognised member definition: %+A{defn}"
|
| _ -> failwith $"Unrecognised member definition: %+A{defn}"
|
||||||
)
|
)
|
||||||
| _ -> failwith $"Unrecognised SynTypeDefnRepr for an interface type: %+A{synTypeDefnRepr}"
|
| _ -> failwith $"Unrecognised SynTypeDefnRepr for an interface type: %+A{synTypeDefnRepr}"
|
||||||
|> List.partitionChoice
|
|> List.partitionChoice
|
||||||
|
|
||||||
|
let members, properties = members |> List.partitionChoice
|
||||||
|
|
||||||
{
|
{
|
||||||
Members = members
|
Members = members
|
||||||
Properties = properties
|
Properties = properties
|
||||||
Name = interfaceName
|
Name = interfaceName
|
||||||
|
Inherits = inherits
|
||||||
Attributes = attrs
|
Attributes = attrs
|
||||||
Generics = typars
|
Generics = typars
|
||||||
Accessibility = accessibility
|
Accessibility = accessibility
|
||||||
@@ -486,6 +508,11 @@ module internal SynTypePatterns =
|
|||||||
Some innerType
|
Some innerType
|
||||||
| _ -> None
|
| _ -> None
|
||||||
|
|
||||||
|
let (|UnitType|_|) (fieldType : SynType) : unit option =
|
||||||
|
match fieldType with
|
||||||
|
| SynType.LongIdent ident when AstHelper.isUnitIdent ident -> Some ()
|
||||||
|
| _ -> None
|
||||||
|
|
||||||
let (|ListType|_|) (fieldType : SynType) =
|
let (|ListType|_|) (fieldType : SynType) =
|
||||||
match fieldType with
|
match fieldType with
|
||||||
| SynType.App (SynType.LongIdent ident, _, [ innerType ], _, _, _, _) when AstHelper.isListIdent ident ->
|
| SynType.App (SynType.LongIdent ident, _, [ innerType ], _, _, _, _) when AstHelper.isListIdent ident ->
|
||||||
|
@@ -764,6 +764,10 @@ module internal HttpClientGenerator =
|
|||||||
=
|
=
|
||||||
let interfaceType = AstHelper.parseInterface interfaceType
|
let interfaceType = AstHelper.parseInterface interfaceType
|
||||||
|
|
||||||
|
if not (List.isEmpty interfaceType.Inherits) then
|
||||||
|
failwith
|
||||||
|
"HttpClientGenerator does not support inheritance. Remove the `inherit` keyword if you want to use this generator."
|
||||||
|
|
||||||
let constantHeaders =
|
let constantHeaders =
|
||||||
interfaceType.Attributes
|
interfaceType.Attributes
|
||||||
|> extractHeaderInformation
|
|> extractHeaderInformation
|
||||||
|
@@ -21,6 +21,9 @@ module internal InterfaceMockGenerator =
|
|||||||
| None -> failwith "Expected record field to have a name, but it was somehow anonymous"
|
| None -> failwith "Expected record field to have a name, but it was somehow anonymous"
|
||||||
| Some id -> id
|
| Some id -> id
|
||||||
|
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
type private KnownInheritance = | IDisposable
|
||||||
|
|
||||||
let createType
|
let createType
|
||||||
(spec : GenerateMockOutputSpec)
|
(spec : GenerateMockOutputSpec)
|
||||||
(name : string)
|
(name : string)
|
||||||
@@ -29,6 +32,20 @@ module internal InterfaceMockGenerator =
|
|||||||
(fields : SynField list)
|
(fields : SynField list)
|
||||||
: SynModuleDecl
|
: SynModuleDecl
|
||||||
=
|
=
|
||||||
|
let inherits =
|
||||||
|
interfaceType.Inherits
|
||||||
|
|> Seq.map (fun ty ->
|
||||||
|
match ty with
|
||||||
|
| SynType.LongIdent (SynLongIdent.SynLongIdent (name, _, _)) ->
|
||||||
|
match name |> List.map _.idText with
|
||||||
|
| [] -> failwith "Unexpected empty identifier in inheritance declaration"
|
||||||
|
| [ "IDisposable" ]
|
||||||
|
| [ "System" ; "IDisposable" ] -> KnownInheritance.IDisposable
|
||||||
|
| _ -> failwithf "Unrecognised inheritance identifier: %+A" name
|
||||||
|
| x -> failwithf "Unrecognised type in inheritance: %+A" x
|
||||||
|
)
|
||||||
|
|> Set.ofSeq
|
||||||
|
|
||||||
let synValData =
|
let synValData =
|
||||||
{
|
{
|
||||||
SynMemberFlags.IsInstance = false
|
SynMemberFlags.IsInstance = false
|
||||||
@@ -90,6 +107,23 @@ module internal InterfaceMockGenerator =
|
|||||||
)
|
)
|
||||||
|> SynBindingReturnInfo.Create
|
|> SynBindingReturnInfo.Create
|
||||||
|
|
||||||
|
let constructorFields =
|
||||||
|
let extras =
|
||||||
|
if inherits.Contains KnownInheritance.IDisposable then
|
||||||
|
let unitFun = SynExpr.createLambda "_" SynExpr.CreateUnit
|
||||||
|
|
||||||
|
[
|
||||||
|
(SynLongIdent.CreateFromLongIdent [ Ident.Create "Dispose" ], true), Some unitFun
|
||||||
|
]
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
|
||||||
|
let nonExtras =
|
||||||
|
fields
|
||||||
|
|> List.map (fun field -> (SynLongIdent.CreateFromLongIdent [ getName field ], true), Some failwithFun)
|
||||||
|
|
||||||
|
extras @ nonExtras
|
||||||
|
|
||||||
let constructor =
|
let constructor =
|
||||||
SynMemberDefn.Member (
|
SynMemberDefn.Member (
|
||||||
SynBinding.SynBinding (
|
SynBinding.SynBinding (
|
||||||
@@ -102,12 +136,7 @@ module internal InterfaceMockGenerator =
|
|||||||
SynValData.SynValData (Some synValData, SynValInfo.Empty, None),
|
SynValData.SynValData (Some synValData, SynValInfo.Empty, None),
|
||||||
constructorIdent,
|
constructorIdent,
|
||||||
Some constructorReturnType,
|
Some constructorReturnType,
|
||||||
AstHelper.instantiateRecord (
|
AstHelper.instantiateRecord constructorFields,
|
||||||
fields
|
|
||||||
|> List.map (fun field ->
|
|
||||||
((SynLongIdent.CreateFromLongIdent [ getName field ], true), Some failwithFun)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
range0,
|
range0,
|
||||||
DebugPointAtBinding.Yes range0,
|
DebugPointAtBinding.Yes range0,
|
||||||
{ SynExpr.synBindingTriviaZero true with
|
{ SynExpr.synBindingTriviaZero true with
|
||||||
@@ -117,6 +146,21 @@ module internal InterfaceMockGenerator =
|
|||||||
range0
|
range0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let fields =
|
||||||
|
let extras =
|
||||||
|
if inherits.Contains KnownInheritance.IDisposable then
|
||||||
|
[
|
||||||
|
SynField.Create (
|
||||||
|
SynType.CreateFun (SynType.CreateUnit, SynType.CreateUnit),
|
||||||
|
Ident.Create "Dispose",
|
||||||
|
xmldoc = PreXmlDoc.Create " Implementation of IDisposable.Dispose"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
|
||||||
|
extras @ fields
|
||||||
|
|
||||||
let interfaceMembers =
|
let interfaceMembers =
|
||||||
let members =
|
let members =
|
||||||
interfaceType.Members
|
interfaceType.Members
|
||||||
@@ -150,7 +194,9 @@ module internal InterfaceMockGenerator =
|
|||||||
|> List.mapi (fun i arg ->
|
|> List.mapi (fun i arg ->
|
||||||
arg.Args
|
arg.Args
|
||||||
|> List.mapi (fun j arg ->
|
|> List.mapi (fun j arg ->
|
||||||
SynArgInfo.CreateIdString $"arg_%i{i}_%i{j}"
|
match arg.Type with
|
||||||
|
| UnitType -> SynArgInfo.SynArgInfo ([], false, None)
|
||||||
|
| _ -> SynArgInfo.CreateIdString $"arg_%i{i}_%i{j}"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@@ -165,10 +211,18 @@ module internal InterfaceMockGenerator =
|
|||||||
|> List.mapi (fun i tupledArgs ->
|
|> List.mapi (fun i tupledArgs ->
|
||||||
let args =
|
let args =
|
||||||
tupledArgs.Args
|
tupledArgs.Args
|
||||||
|> List.mapi (fun j _ -> SynPat.CreateNamed (Ident.Create $"arg_%i{i}_%i{j}"))
|
|> List.mapi (fun j ty ->
|
||||||
|
match ty.Type with
|
||||||
|
| UnitType -> SynPat.Const (SynConst.Unit, range0)
|
||||||
|
| _ -> SynPat.CreateNamed (Ident.Create $"arg_%i{i}_%i{j}")
|
||||||
|
)
|
||||||
|
|
||||||
SynPat.Tuple (false, args, List.replicate (args.Length - 1) range0, range0)
|
match args with
|
||||||
|> SynPat.CreateParen
|
| [] -> failwith "somehow got no args at all"
|
||||||
|
| [ arg ] -> arg
|
||||||
|
| args ->
|
||||||
|
SynPat.Tuple (false, args, List.replicate (args.Length - 1) range0, range0)
|
||||||
|
|> SynPat.CreateParen
|
||||||
|> fun i -> if tupledArgs.HasParen then SynPat.Paren (i, range0) else i
|
|> fun i -> if tupledArgs.HasParen then SynPat.Paren (i, range0) else i
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -187,7 +241,11 @@ module internal InterfaceMockGenerator =
|
|||||||
memberInfo.Args
|
memberInfo.Args
|
||||||
|> List.mapi (fun i args ->
|
|> List.mapi (fun i args ->
|
||||||
args.Args
|
args.Args
|
||||||
|> List.mapi (fun j args -> SynExpr.CreateIdentString $"arg_%i{i}_%i{j}")
|
|> List.mapi (fun j arg ->
|
||||||
|
match arg.Type with
|
||||||
|
| UnitType -> SynExpr.CreateConst SynConst.Unit
|
||||||
|
| _ -> SynExpr.CreateIdentString $"arg_%i{i}_%i{j}"
|
||||||
|
)
|
||||||
|> SynExpr.CreateParenedTuple
|
|> SynExpr.CreateParenedTuple
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -264,11 +322,100 @@ module internal InterfaceMockGenerator =
|
|||||||
| Some (SynAccess.Internal _), _ -> SynAccess.Internal range0
|
| Some (SynAccess.Internal _), _ -> SynAccess.Internal range0
|
||||||
| Some (SynAccess.Private _), _ -> SynAccess.Private range0
|
| Some (SynAccess.Private _), _ -> SynAccess.Private range0
|
||||||
|
|
||||||
|
let extraInterfaces =
|
||||||
|
inherits
|
||||||
|
|> Seq.map (fun inheritance ->
|
||||||
|
match inheritance with
|
||||||
|
| KnownInheritance.IDisposable ->
|
||||||
|
let valData =
|
||||||
|
SynValData.SynValData (
|
||||||
|
Some
|
||||||
|
{
|
||||||
|
IsInstance = true
|
||||||
|
IsDispatchSlot = false
|
||||||
|
IsOverrideOrExplicitImpl = true
|
||||||
|
IsFinal = false
|
||||||
|
GetterOrSetterIsCompilerGenerated = false
|
||||||
|
MemberKind = SynMemberKind.Member
|
||||||
|
},
|
||||||
|
valInfo =
|
||||||
|
SynValInfo.SynValInfo (
|
||||||
|
curriedArgInfos =
|
||||||
|
[
|
||||||
|
yield
|
||||||
|
[
|
||||||
|
SynArgInfo.SynArgInfo (
|
||||||
|
attributes = [],
|
||||||
|
optional = false,
|
||||||
|
ident = None
|
||||||
|
)
|
||||||
|
]
|
||||||
|
],
|
||||||
|
returnInfo =
|
||||||
|
SynArgInfo.SynArgInfo (attributes = [], optional = false, ident = None)
|
||||||
|
),
|
||||||
|
thisIdOpt = None
|
||||||
|
)
|
||||||
|
|
||||||
|
let headArgs = [ SynPat.Const (SynConst.Unit, range0) ]
|
||||||
|
|
||||||
|
let headPat =
|
||||||
|
SynPat.LongIdent (
|
||||||
|
SynLongIdent.CreateFromLongIdent [ Ident.Create "this" ; Ident.Create "Dispose" ],
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
SynArgPats.Pats headArgs,
|
||||||
|
None,
|
||||||
|
range0
|
||||||
|
)
|
||||||
|
|
||||||
|
let binding =
|
||||||
|
SynBinding.SynBinding (
|
||||||
|
None,
|
||||||
|
SynBindingKind.Normal,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
[],
|
||||||
|
PreXmlDoc.Empty,
|
||||||
|
valData,
|
||||||
|
headPat,
|
||||||
|
Some (
|
||||||
|
SynBindingReturnInfo.SynBindingReturnInfo (
|
||||||
|
SynType.Unit (),
|
||||||
|
range0,
|
||||||
|
[],
|
||||||
|
SynBindingReturnInfoTrivia.Zero
|
||||||
|
)
|
||||||
|
),
|
||||||
|
SynExpr.CreateApp (
|
||||||
|
SynExpr.CreateLongIdent (SynLongIdent.Create [ "this" ; "Dispose" ]),
|
||||||
|
SynExpr.CreateUnit
|
||||||
|
),
|
||||||
|
range0,
|
||||||
|
DebugPointAtBinding.Yes range0,
|
||||||
|
{
|
||||||
|
LeadingKeyword = SynLeadingKeyword.Member range0
|
||||||
|
InlineKeyword = None
|
||||||
|
EqualsRange = Some range0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
let mem = SynMemberDefn.Member (binding, range0)
|
||||||
|
|
||||||
|
SynMemberDefn.Interface (
|
||||||
|
SynType.CreateLongIdent (SynLongIdent.Create [ "System" ; "IDisposable" ]),
|
||||||
|
Some range0,
|
||||||
|
Some [ mem ],
|
||||||
|
range0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|> Seq.toList
|
||||||
|
|
||||||
let record =
|
let record =
|
||||||
{
|
{
|
||||||
Name = Ident.Create name
|
Name = Ident.Create name
|
||||||
Fields = fields
|
Fields = fields
|
||||||
Members = Some [ constructor ; interfaceMembers ]
|
Members = Some ([ constructor ; interfaceMembers ] @ extraInterfaces)
|
||||||
XmlDoc = Some xmlDoc
|
XmlDoc = Some xmlDoc
|
||||||
Generics = interfaceType.Generics
|
Generics = interfaceType.Generics
|
||||||
Accessibility = Some access
|
Accessibility = Some access
|
||||||
@@ -333,7 +480,6 @@ module internal InterfaceMockGenerator =
|
|||||||
|
|
||||||
let typeDecl = createType spec name interfaceType docString fields
|
let typeDecl = createType spec name interfaceType docString fields
|
||||||
|
|
||||||
|
|
||||||
SynModuleOrNamespace.CreateNamespace (
|
SynModuleOrNamespace.CreateNamespace (
|
||||||
namespaceId,
|
namespaceId,
|
||||||
decls = (opens |> List.map SynModuleDecl.CreateOpen) @ [ typeDecl ]
|
decls = (opens |> List.map SynModuleDecl.CreateOpen) @ [ typeDecl ]
|
||||||
|
@@ -8,8 +8,8 @@
|
|||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "fantomas";
|
pname = "fantomas";
|
||||||
version = "6.3.0";
|
version = "6.3.3";
|
||||||
sha256 = "sha256-PWiyzkiDL8LBE/fwClS0d6PrE0D5pKYYZiMDZmyk9Y0=";
|
sha256 = "sha256-02uTwRPJkRZtjJ7fOJdHSvc17DszkXjT5X9jGuRZlA4=";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "ApiSurface";
|
pname = "ApiSurface";
|
||||||
|
Reference in New Issue
Block a user