mirror of
https://github.com/Smaug123/WoofWare.Myriad
synced 2025-10-27 14:48:59 +00:00
Compare commits
2 Commits
WoofWare.M
...
d86bd743af
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d86bd743af | ||
|
|
dff2431bc8 |
@@ -3,13 +3,13 @@
|
|||||||
"isRoot": true,
|
"isRoot": true,
|
||||||
"tools": {
|
"tools": {
|
||||||
"fantomas": {
|
"fantomas": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.0-alpha-007",
|
||||||
"commands": [
|
"commands": [
|
||||||
"fantomas"
|
"fantomas"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"fsharp-analyzers": {
|
"fsharp-analyzers": {
|
||||||
"version": "0.25.0",
|
"version": "0.24.0",
|
||||||
"commands": [
|
"commands": [
|
||||||
"fsharp-analyzers"
|
"fsharp-analyzers"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ root=true
|
|||||||
|
|
||||||
[*]
|
[*]
|
||||||
charset=utf-8
|
charset=utf-8
|
||||||
|
end_of_line=crlf
|
||||||
trim_trailing_whitespace=true
|
trim_trailing_whitespace=true
|
||||||
insert_final_newline=true
|
insert_final_newline=true
|
||||||
indent_style=space
|
indent_style=space
|
||||||
|
|||||||
42
.github/workflows/dotnet.yaml
vendored
42
.github/workflows/dotnet.yaml
vendored
@@ -28,7 +28,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v26
|
uses: cachix/install-nix-action@v25
|
||||||
with:
|
with:
|
||||||
extra_nix_config: |
|
extra_nix_config: |
|
||||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -49,7 +49,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v26
|
uses: cachix/install-nix-action@v25
|
||||||
with:
|
with:
|
||||||
extra_nix_config: |
|
extra_nix_config: |
|
||||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -58,7 +58,7 @@ jobs:
|
|||||||
- name: Build project
|
- name: Build project
|
||||||
run: nix develop --command dotnet build ./WoofWare.Myriad.Plugins/WoofWare.Myriad.Plugins.fsproj
|
run: nix develop --command dotnet build ./WoofWare.Myriad.Plugins/WoofWare.Myriad.Plugins.fsproj
|
||||||
- name: Run analyzers
|
- name: Run analyzers
|
||||||
run: nix run .#fsharp-analyzers -- --project ./WoofWare.Myriad.Plugins/WoofWare.Myriad.Plugins.fsproj --analyzers-path ./.analyzerpackages/g-research.fsharp.analyzers/*/ --verbosity detailed --report ./analysis.sarif --treat-as-error GRA-STRING-001 GRA-STRING-002 GRA-STRING-003 GRA-UNIONCASE-001 GRA-INTERPOLATED-001 GRA-TYPE-ANNOTATE-001 GRA-VIRTUALCALL-001 GRA-IMMUTABLECOLLECTIONEQUALITY-001 GRA-JSONOPTS-001 GRA-LOGARGFUNCFULLAPP-001 GRA-DISPBEFOREASYNC-001 --exclude-analyzers PartialAppAnalyzer
|
run: nix run .#fsharp-analyzers -- --project ./WoofWare.Myriad.Plugins/WoofWare.Myriad.Plugins.fsproj --analyzers-path ./.analyzerpackages/g-research.fsharp.analyzers/0.8.0/ --verbosity detailed --report ./analysis.sarif --treat-as-error GRA-STRING-001 GRA-STRING-002 GRA-STRING-003 GRA-UNIONCASE-001 GRA-INTERPOLATED-001 GRA-TYPE-ANNOTATE-001 GRA-VIRTUALCALL-001 GRA-IMMUTABLECOLLECTIONEQUALITY-001 GRA-JSONOPTS-001 GRA-LOGARGFUNCFULLAPP-001 GRA-DISPBEFOREASYNC-001 --exclude-analyzers PartialAppAnalyzer
|
||||||
|
|
||||||
build-nix:
|
build-nix:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -66,7 +66,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v26
|
uses: cachix/install-nix-action@v25
|
||||||
with:
|
with:
|
||||||
extra_nix_config: |
|
extra_nix_config: |
|
||||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -79,7 +79,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v26
|
uses: cachix/install-nix-action@v25
|
||||||
with:
|
with:
|
||||||
extra_nix_config: |
|
extra_nix_config: |
|
||||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -92,7 +92,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v26
|
uses: cachix/install-nix-action@v25
|
||||||
with:
|
with:
|
||||||
extra_nix_config: |
|
extra_nix_config: |
|
||||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -105,7 +105,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@master
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v26
|
uses: cachix/install-nix-action@v25
|
||||||
with:
|
with:
|
||||||
extra_nix_config: |
|
extra_nix_config: |
|
||||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -118,7 +118,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@master
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v26
|
uses: cachix/install-nix-action@v25
|
||||||
with:
|
with:
|
||||||
extra_nix_config: |
|
extra_nix_config: |
|
||||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -132,7 +132,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v26
|
uses: cachix/install-nix-action@v25
|
||||||
with:
|
with:
|
||||||
extra_nix_config: |
|
extra_nix_config: |
|
||||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -188,7 +188,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v26
|
uses: cachix/install-nix-action@v25
|
||||||
with:
|
with:
|
||||||
extra_nix_config: |
|
extra_nix_config: |
|
||||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -206,25 +206,3 @@ jobs:
|
|||||||
path: packed-attribute
|
path: packed-attribute
|
||||||
- name: Publish to NuGet (attribute)
|
- name: Publish to NuGet (attribute)
|
||||||
run: nix develop --command dotnet nuget push "packed-attribute/WoofWare.Myriad.Plugins.Attributes.*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
|
run: nix develop --command dotnet nuget push "packed-attribute/WoofWare.Myriad.Plugins.Attributes.*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
|
||||||
|
|
||||||
github-release-plugin:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }}
|
|
||||||
needs: [all-required-checks-complete]
|
|
||||||
environment: main-deploy
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Download NuGet artifact (plugin)
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: nuget-package-plugin
|
|
||||||
- name: Download NuGet artifact (attribute)
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: nuget-package-attribute
|
|
||||||
- name: Tag and release plugin
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: sh .github/workflows/tag.sh
|
|
||||||
|
|||||||
17
.github/workflows/tag.sh
vendored
17
.github/workflows/tag.sh
vendored
@@ -1,17 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
find . -maxdepth 1 -type f -name '*.nupkg' -exec sh -c 'tag=$(basename "$1" .nupkg); git tag "$tag"; git push origin "$tag"' shell {} \;
|
|
||||||
|
|
||||||
export TAG
|
|
||||||
TAG=$(find . -maxdepth 1 -type f -name 'WoofWare.Myriad.Plugins.*.nupkg' -exec sh -c 'basename "$1" .nupkg' shell {} \; | grep -v Attributes)
|
|
||||||
|
|
||||||
case "$TAG" in
|
|
||||||
*"
|
|
||||||
"*)
|
|
||||||
echo "Error: TAG contains a newline; multiple plugins found."
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# target_commitish empty indicates the repo default branch
|
|
||||||
curl -L -X POST -H "Accept: application/vnd.github+json" -H "Authorization: Bearer $GITHUB_TOKEN" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/Smaug123/WoofWare.Myriad/releases -d '{"tag_name":"'"$TAG"'","target_commitish":"","name":"'"$TAG"'","draft":false,"prerelease":false,"generate_release_notes":false}'
|
|
||||||
@@ -11,12 +11,12 @@ type PairOpKind =
|
|||||||
| ThenDoSeq
|
| ThenDoSeq
|
||||||
|
|
||||||
[<CreateCatamorphism "TreeCata">]
|
[<CreateCatamorphism "TreeCata">]
|
||||||
type Tree<'a, 'b> =
|
type Tree<'a> =
|
||||||
| Const of Const<'a> * 'b
|
| Const of Const<'a>
|
||||||
| Pair of Tree<'a, 'b> * Tree<'a, 'b> * PairOpKind
|
| Pair of Tree<'a> * Tree<'a> * PairOpKind
|
||||||
| Sequential of Tree<'a, 'b> list
|
| Sequential of Tree<'a> list
|
||||||
| Builder of Tree<'a, 'b> * TreeBuilder<'b, 'a>
|
| Builder of Tree<'a> * TreeBuilder<'a>
|
||||||
|
|
||||||
and TreeBuilder<'b, 'a> =
|
and TreeBuilder<'a> =
|
||||||
| Child of TreeBuilder<'b, 'a>
|
| Child of TreeBuilder<'a>
|
||||||
| Parent of Tree<'a, 'b>
|
| Parent of Tree<'a>
|
||||||
|
|||||||
@@ -12,16 +12,16 @@ namespace ConsumePlugin
|
|||||||
open WoofWare.Myriad.Plugins
|
open WoofWare.Myriad.Plugins
|
||||||
|
|
||||||
/// Description of how to combine cases during a fold
|
/// Description of how to combine cases during a fold
|
||||||
type TreeBuilderCataCase<'b, 'a, 'TreeBuilder, 'Tree> =
|
type TreeBuilderCataCase<'a, 'TreeBuilder, 'Tree> =
|
||||||
/// How to operate on the Child case
|
/// How to operate on the Child case
|
||||||
abstract Child : 'TreeBuilder -> 'TreeBuilder
|
abstract Child : 'TreeBuilder -> 'TreeBuilder
|
||||||
/// How to operate on the Parent case
|
/// How to operate on the Parent case
|
||||||
abstract Parent : 'Tree -> 'TreeBuilder
|
abstract Parent : 'Tree -> 'TreeBuilder
|
||||||
|
|
||||||
/// Description of how to combine cases during a fold
|
/// Description of how to combine cases during a fold
|
||||||
type TreeCataCase<'a, 'b, 'TreeBuilder, 'Tree> =
|
type TreeCataCase<'a, 'TreeBuilder, 'Tree> =
|
||||||
/// How to operate on the Const case
|
/// How to operate on the Const case
|
||||||
abstract Const : Const<'a> -> 'b -> 'Tree
|
abstract Const : Const -> 'Tree
|
||||||
/// How to operate on the Pair case
|
/// How to operate on the Pair case
|
||||||
abstract Pair : 'Tree -> 'Tree -> PairOpKind -> 'Tree
|
abstract Pair : 'Tree -> 'Tree -> PairOpKind -> 'Tree
|
||||||
/// How to operate on the Sequential case
|
/// How to operate on the Sequential case
|
||||||
@@ -30,30 +30,30 @@ type TreeCataCase<'a, 'b, 'TreeBuilder, 'Tree> =
|
|||||||
abstract Builder : 'Tree -> 'TreeBuilder -> 'Tree
|
abstract Builder : 'Tree -> 'TreeBuilder -> 'Tree
|
||||||
|
|
||||||
/// Specifies how to perform a fold (catamorphism) over the type Tree and its friends.
|
/// Specifies how to perform a fold (catamorphism) over the type Tree and its friends.
|
||||||
type TreeCata<'b, 'a, 'TreeBuilder, 'Tree> =
|
type TreeCata<'a, 'a, 'TreeBuilder, 'Tree> =
|
||||||
{
|
{
|
||||||
/// How to perform a fold (catamorphism) over the type TreeBuilder
|
/// How to perform a fold (catamorphism) over the type TreeBuilder
|
||||||
TreeBuilder : TreeBuilderCataCase<'b, 'a, 'TreeBuilder, 'Tree>
|
TreeBuilder : TreeBuilderCataCase<'a, 'TreeBuilder, 'Tree>
|
||||||
/// How to perform a fold (catamorphism) over the type Tree
|
/// How to perform a fold (catamorphism) over the type Tree
|
||||||
Tree : TreeCataCase<'a, 'b, 'TreeBuilder, 'Tree>
|
Tree : TreeCataCase<'a, 'TreeBuilder, 'Tree>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Methods to perform a catamorphism over the type Tree
|
/// Methods to perform a catamorphism over the type Tree
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
module TreeCata =
|
module TreeCata =
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
type private Instruction<'b, 'a> =
|
type private Instruction<'a, 'a> =
|
||||||
| Process__TreeBuilder of TreeBuilder<'b, 'a>
|
| Process__TreeBuilder of TreeBuilder<'a>
|
||||||
| Process__Tree of Tree<'a, 'b>
|
| Process__Tree of Tree<'a>
|
||||||
| TreeBuilder_Child
|
| TreeBuilder_Child
|
||||||
| TreeBuilder_Parent
|
| TreeBuilder_Parent
|
||||||
| Tree_Pair of PairOpKind
|
| Tree_Pair of PairOpKind
|
||||||
| Tree_Sequential of int
|
| Tree_Sequential of int
|
||||||
| Tree_Builder
|
| Tree_Builder
|
||||||
|
|
||||||
let private loop (cata : TreeCata<'b, 'a, 'TreeBuilder, 'Tree>) (instructions : ResizeArray<Instruction<'b, 'a>>) =
|
let private loop (cata : TreeCata<_, _, _, _>) (instructions : ResizeArray<Instruction<_, _>>) =
|
||||||
let treeStack = ResizeArray<'Tree> ()
|
let treeStack = ResizeArray ()
|
||||||
let treeBuilderStack = ResizeArray<'TreeBuilder> ()
|
let treeBuilderStack = ResizeArray ()
|
||||||
|
|
||||||
while instructions.Count > 0 do
|
while instructions.Count > 0 do
|
||||||
let currentInstruction = instructions.[instructions.Count - 1]
|
let currentInstruction = instructions.[instructions.Count - 1]
|
||||||
@@ -70,7 +70,7 @@ module TreeCata =
|
|||||||
instructions.Add (Instruction.Process__Tree arg0_0)
|
instructions.Add (Instruction.Process__Tree arg0_0)
|
||||||
| Instruction.Process__Tree x ->
|
| Instruction.Process__Tree x ->
|
||||||
match x with
|
match x with
|
||||||
| Tree.Const (arg0_0, arg1_0) -> cata.Tree.Const arg0_0 arg1_0 |> treeStack.Add
|
| Tree.Const (arg0_0) -> cata.Tree.Const arg0_0 |> treeStack.Add
|
||||||
| Tree.Pair (arg0_0, arg1_0, arg2_0) ->
|
| Tree.Pair (arg0_0, arg1_0, arg2_0) ->
|
||||||
instructions.Add (Instruction.Tree_Pair (arg2_0))
|
instructions.Add (Instruction.Tree_Pair (arg2_0))
|
||||||
instructions.Add (Instruction.Process__Tree arg0_0)
|
instructions.Add (Instruction.Process__Tree arg0_0)
|
||||||
@@ -121,8 +121,8 @@ module TreeCata =
|
|||||||
|
|
||||||
/// Execute the catamorphism.
|
/// Execute the catamorphism.
|
||||||
let runTreeBuilder
|
let runTreeBuilder
|
||||||
(cata : TreeCata<'b, 'a, 'TreeBuilderRet, 'TreeRet>)
|
(cata : TreeCata<'a, 'a, 'TreeBuilderRet, 'TreeRet>)
|
||||||
(x : TreeBuilder<'b, 'a>)
|
(x : TreeBuilder<'a, 'a>)
|
||||||
: 'TreeBuilderRet
|
: 'TreeBuilderRet
|
||||||
=
|
=
|
||||||
let instructions = ResizeArray ()
|
let instructions = ResizeArray ()
|
||||||
@@ -131,7 +131,7 @@ module TreeCata =
|
|||||||
Seq.exactlyOne treeBuilderRetStack
|
Seq.exactlyOne treeBuilderRetStack
|
||||||
|
|
||||||
/// Execute the catamorphism.
|
/// Execute the catamorphism.
|
||||||
let runTree (cata : TreeCata<'b, 'a, 'TreeBuilderRet, 'TreeRet>) (x : Tree<'a, 'b>) : 'TreeRet =
|
let runTree (cata : TreeCata<'a, 'a, 'TreeBuilderRet, 'TreeRet>) (x : Tree<'a, 'a>) : 'TreeRet =
|
||||||
let instructions = ResizeArray ()
|
let instructions = ResizeArray ()
|
||||||
instructions.Add (Instruction.Process__Tree x)
|
instructions.Add (Instruction.Process__Tree x)
|
||||||
let treeBuilderRetStack, treeRetStack = loop cata instructions
|
let treeBuilderRetStack, treeRetStack = loop cata instructions
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ module FileSystemItemCata =
|
|||||||
| Process__FileSystemItem of FileSystemItem
|
| Process__FileSystemItem of FileSystemItem
|
||||||
| FileSystemItem_Directory of string * int * int
|
| FileSystemItem_Directory of string * int * int
|
||||||
|
|
||||||
let private loop (cata : FileSystemCata<'FileSystemItem>) (instructions : ResizeArray<Instruction>) =
|
let private loop (cata : FileSystemCata<_>) (instructions : ResizeArray<Instruction>) =
|
||||||
let fileSystemItemStack = ResizeArray<'FileSystemItem> ()
|
let fileSystemItemStack = ResizeArray ()
|
||||||
|
|
||||||
while instructions.Count > 0 do
|
while instructions.Count > 0 do
|
||||||
let currentInstruction = instructions.[instructions.Count - 1]
|
let currentInstruction = instructions.[instructions.Count - 1]
|
||||||
@@ -108,8 +108,8 @@ module GiftCata =
|
|||||||
| Gift_Boxed
|
| Gift_Boxed
|
||||||
| Gift_WithACard of string
|
| Gift_WithACard of string
|
||||||
|
|
||||||
let private loop (cata : GiftCata<'Gift>) (instructions : ResizeArray<Instruction>) =
|
let private loop (cata : GiftCata<_>) (instructions : ResizeArray<Instruction>) =
|
||||||
let giftStack = ResizeArray<'Gift> ()
|
let giftStack = ResizeArray ()
|
||||||
|
|
||||||
while instructions.Count > 0 do
|
while instructions.Count > 0 do
|
||||||
let currentInstruction = instructions.[instructions.Count - 1]
|
let currentInstruction = instructions.[instructions.Count - 1]
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ module MyListCata =
|
|||||||
| Process__MyList of MyList<'a>
|
| Process__MyList of MyList<'a>
|
||||||
| MyList_Cons of 'a
|
| MyList_Cons of 'a
|
||||||
|
|
||||||
let private loop (cata : MyListCata<'a, 'MyList>) (instructions : ResizeArray<Instruction<'a>>) =
|
let private loop (cata : MyListCata<_, _>) (instructions : ResizeArray<Instruction<_>>) =
|
||||||
let myListStack = ResizeArray<'MyList> ()
|
let myListStack = ResizeArray ()
|
||||||
|
|
||||||
while instructions.Count > 0 do
|
while instructions.Count > 0 do
|
||||||
let currentInstruction = instructions.[instructions.Count - 1]
|
let currentInstruction = instructions.[instructions.Count - 1]
|
||||||
@@ -89,8 +89,8 @@ module MyList2Cata =
|
|||||||
| Process__MyList2 of MyList2<'a>
|
| Process__MyList2 of MyList2<'a>
|
||||||
| MyList2_Cons of 'a
|
| MyList2_Cons of 'a
|
||||||
|
|
||||||
let private loop (cata : MyList2Cata<'a, 'MyList2>) (instructions : ResizeArray<Instruction<'a>>) =
|
let private loop (cata : MyList2Cata<_, _>) (instructions : ResizeArray<Instruction<_>>) =
|
||||||
let myList2Stack = ResizeArray<'MyList2> ()
|
let myList2Stack = ResizeArray ()
|
||||||
|
|
||||||
while instructions.Count > 0 do
|
while instructions.Count > 0 do
|
||||||
let currentInstruction = instructions.[instructions.Count - 1]
|
let currentInstruction = instructions.[instructions.Count - 1]
|
||||||
|
|||||||
12
README.md
12
README.md
@@ -332,7 +332,7 @@ thereby allowing the programmer to use F#'s record-update syntax.
|
|||||||
Takes a collection of mutually recursive discriminated unions:
|
Takes a collection of mutually recursive discriminated unions:
|
||||||
|
|
||||||
```fsharp
|
```fsharp
|
||||||
[<CreateCatamorphism "MyCata">]
|
[<CreateCatamorphism>]
|
||||||
type Expr =
|
type Expr =
|
||||||
| Const of Const
|
| Const of Const
|
||||||
| Pair of Expr * Expr * PairOpKind
|
| Pair of Expr * Expr * PairOpKind
|
||||||
@@ -356,7 +356,7 @@ type ExprBuilderCata<'Expr, 'ExprBuilder> =
|
|||||||
abstract Child : 'ExprBuilder -> 'ExprBuilder
|
abstract Child : 'ExprBuilder -> 'ExprBuilder
|
||||||
abstract Parent : 'Expr -> 'ExprBuilder
|
abstract Parent : 'Expr -> 'ExprBuilder
|
||||||
|
|
||||||
type MyCata<'Expr, 'ExprBuilder> =
|
type Cata<'Expr, 'ExprBuilder> =
|
||||||
{
|
{
|
||||||
Expr : ExprCata<'Expr, 'ExprBuilder>
|
Expr : ExprCata<'Expr, 'ExprBuilder>
|
||||||
ExprBuilder : ExprBuilderCata<'Expr, 'ExprBuilder>
|
ExprBuilder : ExprBuilderCata<'Expr, 'ExprBuilder>
|
||||||
@@ -364,10 +364,10 @@ type MyCata<'Expr, 'ExprBuilder> =
|
|||||||
|
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
module ExprCata =
|
module ExprCata =
|
||||||
let runExpr (cata : MyCata<'ExprRet, 'ExprBuilderRet>) (x : Expr) : 'ExprRet =
|
let runExpr (cata : Cata<'ExprRet, 'ExprBuilderRet>) (x : Expr) : 'ExprRet =
|
||||||
failwith "this is implemented"
|
failwith "this is implemented"
|
||||||
|
|
||||||
let runExprBuilder (cata : MyCata<'ExprRet, 'ExprBuilderRet>) (x : ExprBuilder) : 'ExprBuilderRet =
|
let runExprBuilder (cata : Cata<'ExprRet, 'ExprBuilderRet>) (x : ExprBuilder) : 'ExprBuilderRet =
|
||||||
failwith "this is implemented"
|
failwith "this is implemented"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -381,10 +381,6 @@ and then each time you only plug in what you want to do.
|
|||||||
* Mutually recursive DUs are supported (as in the example above).
|
* Mutually recursive DUs are supported (as in the example above).
|
||||||
Every DU in a recursive `type Foo... and Bar...` knot will be given an appropriate cata, as long as any one of those DUs has the `[<CreateCatamorphism>]` attribute.
|
Every DU in a recursive `type Foo... and Bar...` knot will be given an appropriate cata, as long as any one of those DUs has the `[<CreateCatamorphism>]` attribute.
|
||||||
* There is *limited* support for records and for lists.
|
* There is *limited* support for records and for lists.
|
||||||
* There is *extremely brittle* support for generics in the DUs you are cata'ing over.
|
|
||||||
It is based on the names of the generic parameters, so you must ensure that generic parameters with the same name have the same meaning across the various cases in your recursive knot of DUs.
|
|
||||||
(If you overstep the bounds of what this generator can do, you will get compile-time errors, e.g. with generics being constrained to each other's values.)
|
|
||||||
See the [List tests](./WoofWare.Myriad.Plugins.Test/TestCataGenerator/TestMyList2.fs) for an example, where we re-implement `FSharpList<'a>`.
|
|
||||||
|
|
||||||
### Limitations
|
### Limitations
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ApiSurface" Version="4.0.33" />
|
<PackageReference Include="ApiSurface" Version="4.0.28" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0"/>
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0"/>
|
||||||
<PackageReference Include="NUnit" Version="4.1.0"/>
|
<PackageReference Include="NUnit" Version="3.13.3"/>
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -8,17 +8,17 @@ open FsCheck
|
|||||||
|
|
||||||
[<TestFixture>]
|
[<TestFixture>]
|
||||||
module TestCataGenerator =
|
module TestCataGenerator =
|
||||||
let idCata<'a, 'b> : TreeCata<'a, 'b, _, _> =
|
let idCata : TreeCata<_, _> =
|
||||||
{
|
{
|
||||||
Tree =
|
Tree =
|
||||||
{ new TreeCataCase<_, _, _, _> with
|
{ new TreeCataCase<_, _> with
|
||||||
member _.Const x y = Const (x, y)
|
member _.Const x = Const x
|
||||||
member _.Pair x y z = Pair (x, y, z)
|
member _.Pair x y z = Pair (x, y, z)
|
||||||
member _.Sequential xs = Sequential xs
|
member _.Sequential xs = Sequential xs
|
||||||
member _.Builder x b = Builder (x, b)
|
member _.Builder x b = Builder (x, b)
|
||||||
}
|
}
|
||||||
TreeBuilder =
|
TreeBuilder =
|
||||||
{ new TreeBuilderCataCase<_, _, _, _> with
|
{ new TreeBuilderCataCase<_, _> with
|
||||||
member _.Child x = Child x
|
member _.Child x = Child x
|
||||||
member _.Parent x = Parent x
|
member _.Parent x = Parent x
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,7 @@ module TestCataGenerator =
|
|||||||
[<Test>]
|
[<Test>]
|
||||||
let ``Example`` () =
|
let ``Example`` () =
|
||||||
let x =
|
let x =
|
||||||
Tree.Pair (Tree.Const (Const.Verbatim 0, "hi"), Tree.Const (Const.String "", "bye"), PairOpKind.ThenDoSeq)
|
Tree.Pair (Tree.Const (Const.Int 0), Tree.Const (Const.String ""), PairOpKind.ThenDoSeq)
|
||||||
|
|
||||||
TreeCata.runTree idCata x |> shouldEqual x
|
TreeCata.runTree idCata x |> shouldEqual x
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ module TestCataGenerator =
|
|||||||
let ``Cata works`` () =
|
let ``Cata works`` () =
|
||||||
let builderCases = ref 0
|
let builderCases = ref 0
|
||||||
|
|
||||||
let property (x : Tree<int, string>) =
|
let property (x : Tree) =
|
||||||
match x with
|
match x with
|
||||||
| Tree.Builder _ -> Interlocked.Increment builderCases |> ignore
|
| Tree.Builder _ -> Interlocked.Increment builderCases |> ignore
|
||||||
| _ -> ()
|
| _ -> ()
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ module TestMyList =
|
|||||||
Tail = tail
|
Tail = tail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[<Test>]
|
[<Test>]
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ module TestMyList2 =
|
|||||||
{ new MyList2CataCase<'a, _> with
|
{ new MyList2CataCase<'a, _> with
|
||||||
member _.Nil = MyList2.Nil
|
member _.Nil = MyList2.Nil
|
||||||
|
|
||||||
member _.Cons (head : 'a) (tail : MyList2<'a>) = MyList2.Cons (head, tail)
|
member _.Cons head tail = MyList2.Cons (head, tail)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[<Test>]
|
[<Test>]
|
||||||
|
|||||||
@@ -33,12 +33,13 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ApiSurface" Version="4.0.33"/>
|
<PackageReference Include="ApiSurface" Version="4.0.28"/>
|
||||||
<PackageReference Include="FsCheck" Version="2.16.6"/>
|
<PackageReference Include="FsCheck" Version="2.16.6"/>
|
||||||
<PackageReference Include="FsUnit" Version="6.0.0"/>
|
<PackageReference Include="FsUnit" Version="6.0.0"/>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0"/>
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
|
||||||
<PackageReference Include="NUnit" Version="4.1.0"/>
|
<PackageReference Include="NUnit" Version="4.0.1"/>
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -76,9 +76,6 @@ type internal AdtNode =
|
|||||||
{
|
{
|
||||||
Type : SynType
|
Type : SynType
|
||||||
Name : Ident option
|
Name : Ident option
|
||||||
/// An ordered list, so you can look up any given generic within `this.Type`
|
|
||||||
/// to discover what its index is in the parent DU which defined it.
|
|
||||||
GenericsOfParent : SynTyparDecl list
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A DU is a sum of products (e.g. `type Thing = Foo of a * b`);
|
/// A DU is a sum of products (e.g. `type Thing = Foo of a * b`);
|
||||||
@@ -88,10 +85,6 @@ type internal AdtProduct =
|
|||||||
{
|
{
|
||||||
Name : SynIdent
|
Name : SynIdent
|
||||||
Fields : AdtNode list
|
Fields : AdtNode list
|
||||||
/// This AdtProduct represents a product in which there might be
|
|
||||||
/// some bound type parameters. This field lists the bound
|
|
||||||
/// type parameters in the order they appeared on the parent type.
|
|
||||||
Generics : SynTyparDecl list
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
@@ -442,30 +435,15 @@ module internal AstHelper =
|
|||||||
{
|
{
|
||||||
Type = ty
|
Type = ty
|
||||||
Name = id
|
Name = id
|
||||||
GenericsOfParent = typars
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Generics = typars
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
cases, typars, access
|
cases, typars, access
|
||||||
| _ -> failwithf "Failed to get union cases for type that was: %+A" repr
|
| _ -> failwithf "Failed to get union cases for type that was: %+A" repr
|
||||||
|
|
||||||
let getRecordFields (SynTypeDefn.SynTypeDefn (typeInfo, repr, _, _, _, _)) : AdtNode list =
|
let getRecordFields (SynTypeDefn.SynTypeDefn (_, repr, _, _, _, _)) : AdtNode list =
|
||||||
let (SynComponentInfo.SynComponentInfo (typeParams = typars)) = typeInfo
|
|
||||||
|
|
||||||
let typars =
|
|
||||||
match typars with
|
|
||||||
| None -> []
|
|
||||||
| Some (SynTyparDecls.PrefixList (decls, _)) -> decls
|
|
||||||
| Some (SynTyparDecls.SinglePrefix (l, _)) -> [ l ]
|
|
||||||
| Some (SynTyparDecls.PostfixList (decls, constraints, _)) ->
|
|
||||||
if not constraints.IsEmpty then
|
|
||||||
failwith "Constrained type parameters not currently supported"
|
|
||||||
|
|
||||||
decls
|
|
||||||
|
|
||||||
match repr with
|
match repr with
|
||||||
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Record (_, fields, _), _) ->
|
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Record (_, fields, _), _) ->
|
||||||
fields
|
fields
|
||||||
@@ -473,7 +451,6 @@ module internal AstHelper =
|
|||||||
{
|
{
|
||||||
Name = ident
|
Name = ident
|
||||||
Type = ty
|
Type = ty
|
||||||
GenericsOfParent = typars
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
| _ -> failwithf "Failed to get record elements for type that was: %+A" repr
|
| _ -> failwithf "Failed to get record elements for type that was: %+A" repr
|
||||||
|
|||||||
@@ -35,10 +35,8 @@ module internal CataGenerator =
|
|||||||
/// The relationship this field has with the parent type (or the
|
/// The relationship this field has with the parent type (or the
|
||||||
/// recursive knot of parent types)
|
/// recursive knot of parent types)
|
||||||
Description : FieldDescription
|
Description : FieldDescription
|
||||||
/// Any generic parameters this field consumes.
|
/// Any generic parameters this field consumes
|
||||||
/// This only makes sense in the context of a UnionAnalysis:
|
RequiredGenerics : SynType list option
|
||||||
/// it is an index into the parent Union's collection of generic parameters.
|
|
||||||
RequiredGenerics : int list option
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CataUnionRecordField = (Ident * CataUnionBasicField) list
|
type CataUnionRecordField = (Ident * CataUnionBasicField) list
|
||||||
@@ -121,10 +119,12 @@ module internal CataGenerator =
|
|||||||
(userProvidedTypars : SynTyparDecl list)
|
(userProvidedTypars : SynTyparDecl list)
|
||||||
(allArtificialTypars : SynType list)
|
(allArtificialTypars : SynType list)
|
||||||
(relevantTypar : SynType)
|
(relevantTypar : SynType)
|
||||||
(analysis : UnionAnalysis)
|
(unionType : SynTypeDefn)
|
||||||
: SynBinding
|
: SynBinding
|
||||||
=
|
=
|
||||||
let relevantTypeName = analysis.ParentTypeName
|
let relevantTypeName =
|
||||||
|
match unionType with
|
||||||
|
| SynTypeDefn.SynTypeDefn (SynComponentInfo.SynComponentInfo (longId = id), _, _, _, _, _) -> List.last id
|
||||||
|
|
||||||
let allArtificialTyparNames =
|
let allArtificialTyparNames =
|
||||||
allArtificialTypars
|
allArtificialTypars
|
||||||
@@ -134,11 +134,7 @@ module internal CataGenerator =
|
|||||||
| _ -> failwith "logic error in generator"
|
| _ -> failwith "logic error in generator"
|
||||||
)
|
)
|
||||||
|
|
||||||
let userProvidedTyparsForCase =
|
let userProvidedTypars =
|
||||||
analysis.Typars
|
|
||||||
|> List.map (fun (SynTyparDecl.SynTyparDecl (_, ty)) -> SynType.Var (ty, range0))
|
|
||||||
|
|
||||||
let userProvidedTyparsForCata =
|
|
||||||
userProvidedTypars
|
userProvidedTypars
|
||||||
|> List.map (fun (SynTyparDecl.SynTyparDecl (_, ty)) -> SynType.Var (ty, range0))
|
|> List.map (fun (SynTyparDecl.SynTyparDecl (_, ty)) -> SynType.Var (ty, range0))
|
||||||
|
|
||||||
@@ -149,7 +145,7 @@ module internal CataGenerator =
|
|||||||
|
|
||||||
let inputObjectType =
|
let inputObjectType =
|
||||||
let baseType =
|
let baseType =
|
||||||
SynType.CreateLongIdent (SynLongIdent.CreateFromLongIdent relevantTypeName)
|
SynType.CreateLongIdent (SynLongIdent.CreateFromLongIdent [ relevantTypeName ])
|
||||||
|
|
||||||
if userProvidedTypars.Length = 0 then
|
if userProvidedTypars.Length = 0 then
|
||||||
baseType
|
baseType
|
||||||
@@ -157,7 +153,7 @@ module internal CataGenerator =
|
|||||||
SynType.App (
|
SynType.App (
|
||||||
baseType,
|
baseType,
|
||||||
Some range0,
|
Some range0,
|
||||||
userProvidedTyparsForCase,
|
userProvidedTypars,
|
||||||
List.replicate (userProvidedTypars.Length - 1) range0,
|
List.replicate (userProvidedTypars.Length - 1) range0,
|
||||||
Some range0,
|
Some range0,
|
||||||
false,
|
false,
|
||||||
@@ -174,7 +170,7 @@ module internal CataGenerator =
|
|||||||
SynType.App (
|
SynType.App (
|
||||||
SynType.CreateLongIdent (SynLongIdent.CreateFromLongIdent [ cataName ]),
|
SynType.CreateLongIdent (SynLongIdent.CreateFromLongIdent [ cataName ]),
|
||||||
Some range0,
|
Some range0,
|
||||||
userProvidedTyparsForCata @ allArtificialTypars,
|
userProvidedTypars @ allArtificialTypars,
|
||||||
List.replicate (userProvidedTypars.Length + allArtificialTypars.Length - 1) range0,
|
List.replicate (userProvidedTypars.Length + allArtificialTypars.Length - 1) range0,
|
||||||
Some range0,
|
Some range0,
|
||||||
false,
|
false,
|
||||||
@@ -198,8 +194,8 @@ module internal CataGenerator =
|
|||||||
None
|
None
|
||||||
),
|
),
|
||||||
SynPat.CreateLongIdent (
|
SynPat.CreateLongIdent (
|
||||||
SynLongIdent.CreateString ("run" + List.last(relevantTypeName).idText),
|
SynLongIdent.CreateString ("run" + relevantTypeName.idText),
|
||||||
[ SynPat.CreateParen cataObject ; SynPat.CreateParen inputObject ]
|
[ SynPat.CreateParen (cataObject) ; SynPat.CreateParen inputObject ]
|
||||||
),
|
),
|
||||||
Some (SynBindingReturnInfo.Create relevantTypar),
|
Some (SynBindingReturnInfo.Create relevantTypar),
|
||||||
SynExpr.CreateTyped (
|
SynExpr.CreateTyped (
|
||||||
@@ -223,7 +219,10 @@ module internal CataGenerator =
|
|||||||
SynExpr.CreateLongIdent (SynLongIdent.Create [ "instructions" ; "Add" ]),
|
SynExpr.CreateLongIdent (SynLongIdent.Create [ "instructions" ; "Add" ]),
|
||||||
SynExpr.CreateParen (
|
SynExpr.CreateParen (
|
||||||
SynExpr.CreateApp (
|
SynExpr.CreateApp (
|
||||||
SynExpr.CreateLongIdent analysis.AssociatedProcessInstruction,
|
SynExpr.CreateLongIdent (
|
||||||
|
SynLongIdent.Create
|
||||||
|
[ "Instruction" ; "Process__" + relevantTypeName.idText ]
|
||||||
|
),
|
||||||
SynExpr.CreateLongIdent (SynLongIdent.CreateString "x")
|
SynExpr.CreateLongIdent (SynLongIdent.CreateString "x")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -304,19 +303,14 @@ module internal CataGenerator =
|
|||||||
/// Get the fields of this particular union case, and describe their relation to the
|
/// Get the fields of this particular union case, and describe their relation to the
|
||||||
/// recursive knot of user-provided DUs for which we are creating a cata.
|
/// recursive knot of user-provided DUs for which we are creating a cata.
|
||||||
let analyse
|
let analyse
|
||||||
(availableGenerics : SynTyparDecl list)
|
|
||||||
(allRecordTypes : SynTypeDefn list)
|
(allRecordTypes : SynTypeDefn list)
|
||||||
(allUnionTypes : SynTypeDefn list)
|
(allUnionTypes : SynTypeDefn list)
|
||||||
(argIndex : int)
|
(argIndex : int)
|
||||||
(fields : AdtNode list)
|
(fields : AdtNode list)
|
||||||
: CataUnionBasicField list
|
: CataUnionBasicField list
|
||||||
=
|
=
|
||||||
let availableGenerics =
|
|
||||||
availableGenerics
|
|
||||||
|> List.map (fun (SynTyparDecl.SynTyparDecl (_, SynTypar.SynTypar (ident, _, _))) -> ident)
|
|
||||||
|
|
||||||
let rec go (prefix : string) (name : Ident option) (ty : SynType) : CataUnionBasicField =
|
let rec go (prefix : string) (name : Ident option) (ty : SynType) : CataUnionBasicField =
|
||||||
let dealWithPrimitive (typeArgs : int list option) (ty : SynType) (typeName : LongIdent) =
|
let dealWithPrimitive (typeArgs : SynType list option) (ty : SynType) (typeName : LongIdent) =
|
||||||
let key = typeName |> List.map _.idText |> String.concat "/"
|
let key = typeName |> List.map _.idText |> String.concat "/"
|
||||||
|
|
||||||
let isKnownUnion =
|
let isKnownUnion =
|
||||||
@@ -347,7 +341,7 @@ module internal CataGenerator =
|
|||||||
RequiredGenerics = typeArgs
|
RequiredGenerics = typeArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
let rec dealWithType (typeArgs : int list option) (stripped : SynType) =
|
let rec dealWithType (typeArgs : SynType list option) (stripped : SynType) =
|
||||||
match stripped with
|
match stripped with
|
||||||
| ListType child ->
|
| ListType child ->
|
||||||
let gone = go (prefix + "_") None child
|
let gone = go (prefix + "_") None child
|
||||||
@@ -388,20 +382,7 @@ module internal CataGenerator =
|
|||||||
| SynType.App (ty, _, childTypeArgs, _, _, _, _) ->
|
| SynType.App (ty, _, childTypeArgs, _, _, _, _) ->
|
||||||
match typeArgs with
|
match typeArgs with
|
||||||
| Some _ -> failwithf "Nested applications of types not supported in %+A" ty
|
| Some _ -> failwithf "Nested applications of types not supported in %+A" ty
|
||||||
| None ->
|
| None -> dealWithType (Some childTypeArgs) (SynType.stripOptionalParen ty)
|
||||||
let childTypeArgs =
|
|
||||||
childTypeArgs
|
|
||||||
|> List.map (fun generic ->
|
|
||||||
let generic =
|
|
||||||
match generic with
|
|
||||||
| SynType.Var (SynTypar.SynTypar (name, _, _), _) -> name
|
|
||||||
| _ -> failwithf "Unrecognised generic arg: %+A" generic
|
|
||||||
|
|
||||||
availableGenerics
|
|
||||||
|> List.findIndex (fun knownGeneric -> knownGeneric.idText = generic.idText)
|
|
||||||
)
|
|
||||||
|
|
||||||
dealWithType (Some childTypeArgs) (SynType.stripOptionalParen ty)
|
|
||||||
| SynType.LongIdent (SynLongIdent.SynLongIdent (ty, _, _)) -> dealWithPrimitive typeArgs stripped ty
|
| SynType.LongIdent (SynLongIdent.SynLongIdent (ty, _, _)) -> dealWithPrimitive typeArgs stripped ty
|
||||||
| SynType.Var (typar, _) ->
|
| SynType.Var (typar, _) ->
|
||||||
{
|
{
|
||||||
@@ -476,8 +457,6 @@ module internal CataGenerator =
|
|||||||
{
|
{
|
||||||
Name = name |> Option.map Ident.lowerFirstLetter
|
Name = name |> Option.map Ident.lowerFirstLetter
|
||||||
Type = ty
|
Type = ty
|
||||||
// TODO this is definitely wrong
|
|
||||||
GenericsOfParent = []
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -520,7 +499,6 @@ module internal CataGenerator =
|
|||||||
false,
|
false,
|
||||||
range0
|
range0
|
||||||
)
|
)
|
||||||
GenericsOfParent = union.Typars
|
|
||||||
}
|
}
|
||||||
|> List.singleton
|
|> List.singleton
|
||||||
}
|
}
|
||||||
@@ -533,28 +511,12 @@ module internal CataGenerator =
|
|||||||
|
|
||||||
/// Build the DU which defines the states our state machine can be in.
|
/// Build the DU which defines the states our state machine can be in.
|
||||||
let createInstructionType (analysis : UnionAnalysis list) : SynTypeDefn =
|
let createInstructionType (analysis : UnionAnalysis list) : SynTypeDefn =
|
||||||
let parentGenerics =
|
|
||||||
analysis
|
|
||||||
|> List.collect _.Typars
|
|
||||||
|> List.map (fun (SynTyparDecl.SynTyparDecl (_, SynTypar.SynTypar (ident, _, _))) -> ident.idText)
|
|
||||||
|> List.distinct
|
|
||||||
|> List.map (fun i ->
|
|
||||||
SynTyparDecl.SynTyparDecl ([], SynTypar.SynTypar (Ident.Create i, TyparStaticReq.None, false))
|
|
||||||
)
|
|
||||||
|
|
||||||
// One union case for each union type, and then
|
// One union case for each union type, and then
|
||||||
// a union case for each union case which contains a recursive reference.
|
// a union case for each union case which contains a recursive reference.
|
||||||
let casesFromProcess : SynUnionCase list =
|
let casesFromProcess : SynUnionCase list =
|
||||||
baseCases analysis
|
baseCases analysis
|
||||||
|> List.map (fun unionCase ->
|
|> List.map (fun unionCase ->
|
||||||
let fields =
|
SynUnionCase.Create (unionCase.Name, unionCase.Fields |> List.map (fun f -> SynField.Create f.Type))
|
||||||
unionCase.Fields
|
|
||||||
|> List.map (fun field ->
|
|
||||||
// TODO: adjust type parameters
|
|
||||||
SynField.Create field.Type
|
|
||||||
)
|
|
||||||
|
|
||||||
SynUnionCase.Create (unionCase.Name, fields)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
let casesFromCases =
|
let casesFromCases =
|
||||||
@@ -566,22 +528,14 @@ module internal CataGenerator =
|
|||||||
let cases = casesFromProcess @ casesFromCases
|
let cases = casesFromProcess @ casesFromCases
|
||||||
|
|
||||||
let typars =
|
let typars =
|
||||||
let count = analysis |> List.map (fun x -> List.length x.Typars) |> List.max
|
// TODO: deduplicate names where we have the same generic across multiple DUs
|
||||||
|
|
||||||
if analysis |> List.forall (fun x -> x.Typars.IsEmpty) then
|
|
||||||
None
|
|
||||||
else
|
|
||||||
|
|
||||||
let typars =
|
|
||||||
analysis
|
analysis
|
||||||
|> List.collect _.Typars
|
|> List.collect _.Typars
|
||||||
|> List.map (fun (SynTyparDecl.SynTyparDecl (_, SynTypar.SynTypar (ident, _, _))) -> ident.idText)
|
|> fun x ->
|
||||||
|> List.distinct
|
if x.IsEmpty then
|
||||||
|> List.map (fun i ->
|
None
|
||||||
SynTyparDecl.SynTyparDecl ([], SynTypar.SynTypar (Ident.Create i, TyparStaticReq.None, false))
|
else
|
||||||
)
|
Some (SynTyparDecls.PostfixList (x, [], range0))
|
||||||
|
|
||||||
Some (SynTyparDecls.PostfixList (typars, [], range0))
|
|
||||||
|
|
||||||
SynTypeDefn.SynTypeDefn (
|
SynTypeDefn.SynTypeDefn (
|
||||||
SynComponentInfo.SynComponentInfo (
|
SynComponentInfo.SynComponentInfo (
|
||||||
@@ -679,26 +633,7 @@ module internal CataGenerator =
|
|||||||
[ SynType.Var (generics.[getNameKeyUnion ty], range0) ],
|
[ SynType.Var (generics.[getNameKeyUnion ty], range0) ],
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
| FieldDescription.NonRecursive ty ->
|
| FieldDescription.NonRecursive ty -> ty
|
||||||
match field.RequiredGenerics with
|
|
||||||
| None -> ty
|
|
||||||
| Some generics ->
|
|
||||||
let generics =
|
|
||||||
generics
|
|
||||||
|> List.map (fun i ->
|
|
||||||
let (SynTyparDecl.SynTyparDecl (_, typar)) = analysis.Typars.[i]
|
|
||||||
SynType.Var (typar, range0)
|
|
||||||
)
|
|
||||||
|
|
||||||
SynType.App (
|
|
||||||
ty,
|
|
||||||
Some range0,
|
|
||||||
generics,
|
|
||||||
List.replicate (generics.Length - 1) range0,
|
|
||||||
Some range0,
|
|
||||||
false,
|
|
||||||
range0
|
|
||||||
)
|
|
||||||
|
|
||||||
SynType.Fun (
|
SynType.Fun (
|
||||||
SynType.SignatureParameter (
|
SynType.SignatureParameter (
|
||||||
@@ -785,11 +720,7 @@ module internal CataGenerator =
|
|||||||
|
|
||||||
let userInputGenerics =
|
let userInputGenerics =
|
||||||
analysis.Typars
|
analysis.Typars
|
||||||
|> List.map (fun (SynTyparDecl.SynTyparDecl (_, SynTypar.SynTypar (ident, _, _))) -> ident.idText)
|
|> List.map (fun (SynTyparDecl.SynTyparDecl (_, typar)) -> SynType.Var (typar, range0))
|
||||||
|> List.distinct
|
|
||||||
|> List.map (fun i ->
|
|
||||||
SynType.Var (SynTypar.SynTypar (Ident.Create i, TyparStaticReq.None, false), range0)
|
|
||||||
)
|
|
||||||
|
|
||||||
let ty =
|
let ty =
|
||||||
SynType.App (
|
SynType.App (
|
||||||
@@ -820,11 +751,9 @@ module internal CataGenerator =
|
|||||||
// A "real" generic for each generic in the user-provided type
|
// A "real" generic for each generic in the user-provided type
|
||||||
let genericsFromUserInput =
|
let genericsFromUserInput =
|
||||||
analysis
|
analysis
|
||||||
|> List.collect _.Typars
|
|> List.collect (fun analysis ->
|
||||||
|> List.map (fun (SynTyparDecl.SynTyparDecl (_, SynTypar.SynTypar (ident, _, _))) -> ident.idText)
|
// TODO: deduplicate generics with the same name from different cases
|
||||||
|> List.distinct
|
analysis.Typars
|
||||||
|> List.map (fun i ->
|
|
||||||
SynTyparDecl.SynTyparDecl ([], SynTypar.SynTypar (Ident.Create i, TyparStaticReq.None, false))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
let genericsFromCata =
|
let genericsFromCata =
|
||||||
@@ -877,18 +806,21 @@ module internal CataGenerator =
|
|||||||
prod.Fields
|
prod.Fields
|
||||||
|> List.indexed
|
|> List.indexed
|
||||||
|> List.collect (fun (i, node) ->
|
|> List.collect (fun (i, node) ->
|
||||||
|
let availableGenerics =
|
||||||
|
match node.Type with
|
||||||
|
| SynType.App (_, _, vars, _, _, _, _) -> vars
|
||||||
|
| _ -> []
|
||||||
|
|
||||||
match getNameUnion node.Type with
|
match getNameUnion node.Type with
|
||||||
| None ->
|
| None ->
|
||||||
analyse typars allRecordTypes allUnionTypes i [ node ]
|
analyse allRecordTypes allUnionTypes i [ node ] |> List.map CataUnionField.Basic
|
||||||
|> List.map CataUnionField.Basic
|
|
||||||
| Some name ->
|
| Some name ->
|
||||||
|
|
||||||
match Map.tryFind (List.last(name).idText) recordTypes with
|
match Map.tryFind (List.last(name).idText) recordTypes with
|
||||||
| None ->
|
| None ->
|
||||||
analyse typars allRecordTypes allUnionTypes i [ node ]
|
analyse allRecordTypes allUnionTypes i [ node ] |> List.map CataUnionField.Basic
|
||||||
|> List.map CataUnionField.Basic
|
|
||||||
| Some fields ->
|
| Some fields ->
|
||||||
List.zip fields (analyse typars allRecordTypes allUnionTypes i fields)
|
List.zip fields (analyse allRecordTypes allUnionTypes i fields)
|
||||||
|> List.map (fun (field, analysis) -> Option.get field.Name, analysis)
|
|> List.map (fun (field, analysis) -> Option.get field.Name, analysis)
|
||||||
|> CataUnionField.Record
|
|> CataUnionField.Record
|
||||||
|> List.singleton
|
|> List.singleton
|
||||||
@@ -1378,20 +1310,16 @@ module internal CataGenerator =
|
|||||||
None
|
None
|
||||||
)
|
)
|
||||||
|
|
||||||
let userSuppliedGenerics =
|
// A generic for each DU case, and a generic for each generic in the DU
|
||||||
analysis
|
let genericCount = analysis.Length + (analysis |> List.sumBy _.Typars.Length)
|
||||||
|> List.collect _.Typars
|
|
||||||
|> List.map (fun (SynTyparDecl.SynTyparDecl (_, SynTypar.SynTypar (ident, _, _))) -> ident.idText)
|
|
||||||
|> List.distinct
|
|
||||||
|> List.map (fun i -> SynTypar.SynTypar (Ident.Create i, TyparStaticReq.None, false))
|
|
||||||
|
|
||||||
let instructionsArrType =
|
let instructionsArrType =
|
||||||
if not userSuppliedGenerics.IsEmpty then
|
if genericCount > analysis.Length then
|
||||||
SynType.App (
|
SynType.App (
|
||||||
SynType.CreateLongIdent "Instruction",
|
SynType.CreateLongIdent "Instruction",
|
||||||
Some range0,
|
Some range0,
|
||||||
userSuppliedGenerics |> List.map (fun x -> SynType.Var (x, range0)),
|
List.replicate (genericCount - analysis.Length) (SynType.Anon range0),
|
||||||
List.replicate (userSuppliedGenerics.Length - 1) range0,
|
List.replicate (genericCount - analysis.Length - 1) range0,
|
||||||
Some range0,
|
Some range0,
|
||||||
false,
|
false,
|
||||||
range0
|
range0
|
||||||
@@ -1399,14 +1327,6 @@ module internal CataGenerator =
|
|||||||
else
|
else
|
||||||
SynType.CreateLongIdent "Instruction"
|
SynType.CreateLongIdent "Instruction"
|
||||||
|
|
||||||
let cataGenerics =
|
|
||||||
[
|
|
||||||
for generic in userSuppliedGenerics do
|
|
||||||
yield SynType.Var (generic, range0)
|
|
||||||
for case in analysis do
|
|
||||||
yield SynType.Var (SynTypar.SynTypar (case.GenericName, TyparStaticReq.None, false), range0)
|
|
||||||
]
|
|
||||||
|
|
||||||
let headPat =
|
let headPat =
|
||||||
SynPat.LongIdent (
|
SynPat.LongIdent (
|
||||||
SynLongIdent.CreateString "loop",
|
SynLongIdent.CreateString "loop",
|
||||||
@@ -1420,8 +1340,8 @@ module internal CataGenerator =
|
|||||||
SynType.App (
|
SynType.App (
|
||||||
SynType.CreateLongIdent (SynLongIdent.CreateFromLongIdent [ cataTypeName ]),
|
SynType.CreateLongIdent (SynLongIdent.CreateFromLongIdent [ cataTypeName ]),
|
||||||
Some range0,
|
Some range0,
|
||||||
cataGenerics,
|
List.replicate genericCount (SynType.Anon range0),
|
||||||
List.replicate (cataGenerics.Length - 1) range0,
|
List.replicate (genericCount - 1) range0,
|
||||||
Some range0,
|
Some range0,
|
||||||
false,
|
false,
|
||||||
range0
|
range0
|
||||||
@@ -1536,20 +1456,7 @@ module internal CataGenerator =
|
|||||||
SynPat.Named (SynIdent.SynIdent (unionCase.StackName, None), false, None, range0),
|
SynPat.Named (SynIdent.SynIdent (unionCase.StackName, None), false, None, range0),
|
||||||
None,
|
None,
|
||||||
SynExpr.CreateApp (
|
SynExpr.CreateApp (
|
||||||
SynExpr.TypeApp (
|
SynExpr.CreateLongIdent (SynLongIdent.CreateString "ResizeArray"),
|
||||||
SynExpr.CreateIdent (Ident.Create "ResizeArray"),
|
|
||||||
range0,
|
|
||||||
[
|
|
||||||
SynType.Var (
|
|
||||||
SynTypar.SynTypar (unionCase.GenericName, TyparStaticReq.None, false),
|
|
||||||
range0
|
|
||||||
)
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
Some range0,
|
|
||||||
range0,
|
|
||||||
range0
|
|
||||||
),
|
|
||||||
SynExpr.CreateConst SynConst.Unit
|
SynExpr.CreateConst SynConst.Unit
|
||||||
),
|
),
|
||||||
range0,
|
range0,
|
||||||
@@ -1619,21 +1526,15 @@ module internal CataGenerator =
|
|||||||
|> fun x -> SynType.Var (x, range0)
|
|> fun x -> SynType.Var (x, range0)
|
||||||
)
|
)
|
||||||
|
|
||||||
let userProvidedGenerics =
|
let userProvidedGenerics = analysis |> List.collect (fun x -> x.Typars)
|
||||||
analysis
|
|
||||||
|> List.collect _.Typars
|
|
||||||
|> List.map (fun (SynTyparDecl (_, SynTypar.SynTypar (ident, _, _))) -> ident.idText)
|
|
||||||
|> List.distinct
|
|
||||||
|> List.map (fun x ->
|
|
||||||
SynTyparDecl.SynTyparDecl ([], SynTypar.SynTypar (Ident.Create x, TyparStaticReq.None, false))
|
|
||||||
)
|
|
||||||
|
|
||||||
let runFunctions =
|
let runFunctions =
|
||||||
List.zip analysis allTypars
|
List.zip allUnionTypes allTypars
|
||||||
|> List.map (fun (analysis, relevantTypar) ->
|
|> List.map (fun (unionType, relevantTypar) ->
|
||||||
createRunFunction cataName userProvidedGenerics allTypars relevantTypar analysis
|
createRunFunction cataName userProvidedGenerics allTypars relevantTypar unionType
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
let cataStructures =
|
let cataStructures =
|
||||||
createCataStructure analysis
|
createCataStructure analysis
|
||||||
|> List.map (fun repr -> SynModuleDecl.Types ([ repr ], range0))
|
|> List.map (fun repr -> SynModuleDecl.Types ([ repr ], range0))
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageDownload Include="G-Research.FSharp.Analyzers" Version="[0.9.3]" />
|
<PackageDownload Include="G-Research.FSharp.Analyzers" Version="[0.8.0]" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
76
nix/deps.nix
76
nix/deps.nix
@@ -3,18 +3,23 @@
|
|||||||
{fetchNuGet}: [
|
{fetchNuGet}: [
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "fsharp-analyzers";
|
pname = "fsharp-analyzers";
|
||||||
version = "0.25.0";
|
version = "0.24.0";
|
||||||
sha256 = "sha256-njfJYi40jNvrD+mgu9LtQw2Omh8P1SSDThesozH0KQY=";
|
sha256 = "sha256-cNaM/yHI28sHDGamKMrU237ltOyrR+8vPNUImB5RxjU=";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "fantomas";
|
pname = "fantomas";
|
||||||
version = "6.3.0";
|
version = "6.3.0-alpha-007";
|
||||||
sha256 = "sha256-PWiyzkiDL8LBE/fwClS0d6PrE0D5pKYYZiMDZmyk9Y0=";
|
sha256 = "sha256-uZw6h6k/DS4BcYtK9cv8TLS0H8MZDO3WBaPPTdtTgu0=";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "ApiSurface";
|
pname = "ApiSurface";
|
||||||
version = "4.0.33";
|
version = "4.0.28";
|
||||||
sha256 = "0mmsa5gxfd3bbgacip0c1hljwd958zcx1012qdh033sx6nfz3v36";
|
sha256 = "1gg0dqbgbb8aqn2lxi5gf2wq969kgskby5wph6m2b3hdkz7265ak";
|
||||||
|
})
|
||||||
|
(fetchNuGet {
|
||||||
|
pname = "coverlet.collector";
|
||||||
|
version = "6.0.0";
|
||||||
|
sha256 = "12j34vrkmph8lspbafnqmfnj2qvysz1jcrks2khw798s6dwv0j90";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "Fantomas.Core";
|
pname = "Fantomas.Core";
|
||||||
@@ -116,11 +121,21 @@
|
|||||||
version = "8.0.0";
|
version = "8.0.0";
|
||||||
sha256 = "0055f69q3hbagqp8gl3nk0vfn4qyqyxsxyy7pd0g7wm3z28byzmx";
|
sha256 = "0055f69q3hbagqp8gl3nk0vfn4qyqyxsxyy7pd0g7wm3z28byzmx";
|
||||||
})
|
})
|
||||||
|
(fetchNuGet {
|
||||||
|
pname = "Microsoft.CodeCoverage";
|
||||||
|
version = "17.8.0";
|
||||||
|
sha256 = "173wjadp3gan4x2jfjchngnc4ca4mb95h1sbb28jydfkfw0z1zvj";
|
||||||
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "Microsoft.CodeCoverage";
|
pname = "Microsoft.CodeCoverage";
|
||||||
version = "17.9.0";
|
version = "17.9.0";
|
||||||
sha256 = "1gljgi69k0fz8vy8bn6xlyxabj6q4vls2zza9wz7ng6ix3irm89r";
|
sha256 = "1gljgi69k0fz8vy8bn6xlyxabj6q4vls2zza9wz7ng6ix3irm89r";
|
||||||
})
|
})
|
||||||
|
(fetchNuGet {
|
||||||
|
pname = "Microsoft.NET.Test.Sdk";
|
||||||
|
version = "17.8.0";
|
||||||
|
sha256 = "1syvl3g0hbrcgfi9rq6pld8s8hqqww4dflf1lxn59ccddyyx0gmv";
|
||||||
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "Microsoft.NET.Test.Sdk";
|
pname = "Microsoft.NET.Test.Sdk";
|
||||||
version = "17.9.0";
|
version = "17.9.0";
|
||||||
@@ -266,11 +281,21 @@
|
|||||||
version = "8.0.0";
|
version = "8.0.0";
|
||||||
sha256 = "1gdx7n45wwia3yvang3ls92sk3wrymqcx9p349j8wba2lyjf9m44";
|
sha256 = "1gdx7n45wwia3yvang3ls92sk3wrymqcx9p349j8wba2lyjf9m44";
|
||||||
})
|
})
|
||||||
|
(fetchNuGet {
|
||||||
|
pname = "Microsoft.TestPlatform.ObjectModel";
|
||||||
|
version = "17.8.0";
|
||||||
|
sha256 = "0b0i7lmkrcfvim8i3l93gwqvkhhhfzd53fqfnygdqvkg6np0cg7m";
|
||||||
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "Microsoft.TestPlatform.ObjectModel";
|
pname = "Microsoft.TestPlatform.ObjectModel";
|
||||||
version = "17.9.0";
|
version = "17.9.0";
|
||||||
sha256 = "1kgsl9w9fganbm9wvlkqgk0ag9hfi58z88rkfybc6kvg78bx89ca";
|
sha256 = "1kgsl9w9fganbm9wvlkqgk0ag9hfi58z88rkfybc6kvg78bx89ca";
|
||||||
})
|
})
|
||||||
|
(fetchNuGet {
|
||||||
|
pname = "Microsoft.TestPlatform.TestHost";
|
||||||
|
version = "17.8.0";
|
||||||
|
sha256 = "0f5jah93kjkvxwmhwb78lw11m9pkkq9fvf135hpymmmpxqbdh97q";
|
||||||
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "Microsoft.TestPlatform.TestHost";
|
pname = "Microsoft.TestPlatform.TestHost";
|
||||||
version = "17.9.0";
|
version = "17.9.0";
|
||||||
@@ -291,6 +316,11 @@
|
|||||||
version = "3.6.133";
|
version = "3.6.133";
|
||||||
sha256 = "1cdw8krvsnx0n34f7fm5hiiy7bs6h3asvncqcikc0g46l50w2j80";
|
sha256 = "1cdw8krvsnx0n34f7fm5hiiy7bs6h3asvncqcikc0g46l50w2j80";
|
||||||
})
|
})
|
||||||
|
(fetchNuGet {
|
||||||
|
pname = "NETStandard.Library";
|
||||||
|
version = "2.0.0";
|
||||||
|
sha256 = "1bc4ba8ahgk15m8k4nd7x406nhi0kwqzbgjk2dmw52ss553xz7iy";
|
||||||
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NETStandard.Library";
|
pname = "NETStandard.Library";
|
||||||
version = "2.0.3";
|
version = "2.0.3";
|
||||||
@@ -308,23 +338,28 @@
|
|||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NuGet.Common";
|
pname = "NuGet.Common";
|
||||||
version = "6.9.1";
|
version = "6.8.0";
|
||||||
sha256 = "0ic3d46r9v05pkczpmskw86yzixm6iwshbw0ya8i2957nhhlymw8";
|
sha256 = "0l3ij8iwy7wj6s7f93lzi9168r4wz8zyin6a08iwgk7hvq44cia1";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NuGet.Configuration";
|
pname = "NuGet.Configuration";
|
||||||
version = "6.9.1";
|
version = "6.8.0";
|
||||||
sha256 = "07z4qgbibpg59j2r05ifnqdyqf2xinm33rx7gjyr1f73kzg01m33";
|
sha256 = "0x03p408smkmv1gv7pmvsia4lkn0xaj4wfrkl58pjf8bbv51y0yw";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NuGet.Frameworks";
|
pname = "NuGet.Frameworks";
|
||||||
version = "6.9.1";
|
version = "6.5.0";
|
||||||
sha256 = "0s3az3ac53icjnmb14hfjcmkvzscvrkm62jgqf48yvsbysyhqm5s";
|
sha256 = "0s37d1p4md0k6d4cy6sq36f2dgkd9qfbzapxhkvi8awwh0vrynhj";
|
||||||
|
})
|
||||||
|
(fetchNuGet {
|
||||||
|
pname = "NuGet.Frameworks";
|
||||||
|
version = "6.8.0";
|
||||||
|
sha256 = "0i2xvhgkjkjr496i3pg8hamwv6505fia45qhn7jg5m01wb3cvsjl";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NuGet.Packaging";
|
pname = "NuGet.Packaging";
|
||||||
version = "6.9.1";
|
version = "6.8.0";
|
||||||
sha256 = "0w0arkmzg3qh1brq4vm10zrsjm7nw706ld4y5kqcmvjpd16f4b4y";
|
sha256 = "031z4s905bxi94h3f0qy4j1b6jxdxgqgpkzqvvpfxch07szxcbim";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NuGet.Protocol";
|
pname = "NuGet.Protocol";
|
||||||
@@ -333,13 +368,18 @@
|
|||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NuGet.Versioning";
|
pname = "NuGet.Versioning";
|
||||||
version = "6.9.1";
|
version = "6.8.0";
|
||||||
sha256 = "0xrs82dydy9cgxf0qypr01wawwnq1nf6fc7rwisb4y5v4r259fdm";
|
sha256 = "1sd25h46fd12ng780r02q4ijcx1imkb53kj1y2y7cwg5myh537ks";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NUnit";
|
pname = "NUnit";
|
||||||
version = "4.1.0";
|
version = "3.13.3";
|
||||||
sha256 = "0fj6xwgqaxq3mrai86bklclfmjkzf038mrslwfqf4ignaz9f7g5j";
|
sha256 = "0wdzfkygqnr73s6lpxg5b1pwaqz9f414fxpvpdmf72bvh4jaqzv6";
|
||||||
|
})
|
||||||
|
(fetchNuGet {
|
||||||
|
pname = "NUnit";
|
||||||
|
version = "4.0.1";
|
||||||
|
sha256 = "0jgiq3dbwli5r70j0bw7021d69r7bhr58s8kphlpjmf7k47l5pcd";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NUnit3TestAdapter";
|
pname = "NUnit3TestAdapter";
|
||||||
|
|||||||
Reference in New Issue
Block a user