mirror of
https://github.com/Smaug123/WoofWare.Myriad
synced 2025-10-05 20:18:43 +00:00
Compare commits
82 Commits
WoofWare.M
...
WoofWare.M
Author | SHA1 | Date | |
---|---|---|---|
|
f30a73fd4f | ||
|
b2d64562bf | ||
|
e7e629613e | ||
|
4560138b59 | ||
|
425d5313b4 | ||
|
0fe97da788 | ||
|
f944953384 | ||
|
7930039ad1 | ||
|
8d275f0047 | ||
|
682b12fdb2 | ||
|
325f8634a4 | ||
|
3e5d663544 | ||
|
bb88f80c85 | ||
|
71f26930c6 | ||
|
680728a06e | ||
|
cdc6f2d511 | ||
|
3be487c328 | ||
|
a5f4d169ca | ||
|
ce634efff2 | ||
|
1529dd1fb2 | ||
|
59558b0766 | ||
|
8602894efc | ||
|
51d349b365 | ||
|
120df84bbf | ||
|
603f875a12 | ||
|
2df41555de | ||
|
49e31e52b5 | ||
|
277a186fda | ||
|
129687ec1c | ||
|
c7fea55e28 | ||
|
ded7b32771 | ||
|
b272f8b645 | ||
|
b8d60aec90 | ||
|
0e3510e1e5 | ||
|
8a1edd90d5 | ||
|
74fdd7c0a9 | ||
|
23f55814f9 | ||
|
15c04bb373 | ||
|
a860a93f9c | ||
|
b056af348e | ||
|
b44c8db6e9 | ||
|
7d6a2cea01 | ||
|
d779a602f4 | ||
|
23cd5272fb | ||
|
93538ee6b4 | ||
|
8a29c2f444 | ||
|
1367e00f34 | ||
|
bff08c90cd | ||
|
4136f7fe94 | ||
|
9fe2e3b1fa | ||
|
13a597a365 | ||
|
3acc492f22 | ||
|
eefe64f5a4 | ||
|
93a2d92299 | ||
|
33793e8cbe | ||
|
fa7ef1ffba | ||
|
a25c45dc3a | ||
|
af5f2abdf8 | ||
|
0f89816432 | ||
|
d571da6a22 | ||
|
39a9e94ca5 | ||
|
487f73312a | ||
|
b7aa564306 | ||
|
a34dee0a1c | ||
|
44506f3650 | ||
|
ca7134cfb8 | ||
|
773fd088a7 | ||
|
6e5c0332cd | ||
|
aece186424 | ||
|
827e9aa3ec | ||
|
d59ebdfccb | ||
|
5319a33b7b | ||
|
29b93b2f20 | ||
|
40106d8aa3 | ||
|
4d641b0662 | ||
|
16e6b91548 | ||
|
8488883835 | ||
|
0652744c57 | ||
|
9252979673 | ||
|
1120a3752d | ||
|
7ca6b0c0eb | ||
|
50efb8d9bc |
@@ -3,13 +3,13 @@
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"fantomas": {
|
||||
"version": "6.3.15",
|
||||
"version": "7.0.1",
|
||||
"commands": [
|
||||
"fantomas"
|
||||
]
|
||||
},
|
||||
"fsharp-analyzers": {
|
||||
"version": "0.27.0",
|
||||
"version": "0.30.0",
|
||||
"commands": [
|
||||
"fsharp-analyzers"
|
||||
]
|
||||
|
98
.github/workflows/dotnet.yaml
vendored
98
.github/workflows/dotnet.yaml
vendored
@@ -29,7 +29,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@V28
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@V28
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@V28
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@V28
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -97,7 +97,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@V28
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -116,7 +116,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@V28
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -129,7 +129,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@V28
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -142,7 +142,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@V28
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -156,7 +156,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@V28
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -198,27 +198,40 @@ jobs:
|
||||
# Verify that there is exactly one nupkg in the artifact that would be NuGet published
|
||||
run: if [[ $(find packed-attribute -maxdepth 1 -name 'WoofWare.Myriad.Plugins.Attributes.*.nupkg' -printf c | wc -c) -ne "1" ]]; then exit 1; fi
|
||||
|
||||
github-release-plugin-dry-run:
|
||||
needs: [nuget-pack]
|
||||
github-release-dry-run:
|
||||
strategy:
|
||||
matrix:
|
||||
artifact:
|
||||
- nuget-package-plugin
|
||||
- nuget-package-attribute
|
||||
runs-on: ubuntu-latest
|
||||
needs: [nuget-pack]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download NuGet artifact (plugin)
|
||||
- name: Download NuGet artifact
|
||||
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
|
||||
name: ${{ matrix.artifact }}
|
||||
- name: Compute package path
|
||||
id: compute-path
|
||||
run: |
|
||||
find . -maxdepth 1 -type f -name 'WoofWare.Myriad.*.nupkg' -exec sh -c 'echo "output=$(basename "$1")" >> $GITHUB_OUTPUT' shell {} \;
|
||||
- name: Compute tag name
|
||||
id: compute-tag
|
||||
env:
|
||||
DRY_RUN: 1
|
||||
GITHUB_TOKEN: mock-token
|
||||
run: sh .github/workflows/tag.sh
|
||||
NUPKG_PATH: ${{ steps.compute-path.outputs.output }}
|
||||
run: echo "output=$(basename "$NUPKG_PATH" .nupkg)" >> $GITHUB_OUTPUT
|
||||
- name: Tag and release
|
||||
uses: G-Research/common-actions/github-release@19d7281a0f9f83e13c78f99a610dbc80fc59ba3b
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
target-commitish: ${{ github.sha }}
|
||||
tag: ${{ steps.compute-tag.outputs.output }}
|
||||
binary-contents: ${{ steps.compute-path.outputs.output }}
|
||||
dry-run: true
|
||||
|
||||
all-required-checks-complete:
|
||||
needs: [check-dotnet-format, check-nix-format, check-accurate-generations, build, build-nix, linkcheck, flake-check, analyzers, nuget-pack, expected-pack, github-release-plugin-dry-run]
|
||||
needs: [check-dotnet-format, check-nix-format, check-accurate-generations, build, build-nix, linkcheck, flake-check, analyzers, nuget-pack, expected-pack, github-release-dry-run]
|
||||
if: ${{ always() }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -241,7 +254,7 @@ jobs:
|
||||
name: nuget-package-attribute
|
||||
path: packed
|
||||
- name: Attest Build Provenance
|
||||
uses: actions/attest-build-provenance@1c608d11d69870c2092266b3f9a6f3abbf17002c # v1.4.3
|
||||
uses: actions/attest-build-provenance@c074443f1aee8d4aeeae555aebba3282517141b2 # v2.2.3
|
||||
with:
|
||||
subject-path: "packed/*.nupkg"
|
||||
|
||||
@@ -260,7 +273,7 @@ jobs:
|
||||
name: nuget-package-plugin
|
||||
path: packed
|
||||
- name: Attest Build Provenance
|
||||
uses: actions/attest-build-provenance@1c608d11d69870c2092266b3f9a6f3abbf17002c # v1.4.3
|
||||
uses: actions/attest-build-provenance@c074443f1aee8d4aeeae555aebba3282517141b2 # v2.2.3
|
||||
with:
|
||||
subject-path: "packed/*.nupkg"
|
||||
|
||||
@@ -276,7 +289,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@V28
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -309,7 +322,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@V28
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -330,7 +343,12 @@ jobs:
|
||||
nupkg-dir: packed/
|
||||
dotnet: ${{ steps.dotnet-identify.outputs.dotnet }}
|
||||
|
||||
github-release-plugin:
|
||||
github-release:
|
||||
strategy:
|
||||
matrix:
|
||||
artifact:
|
||||
- nuget-package-attribute
|
||||
- nuget-package-plugin
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }}
|
||||
needs: [all-required-checks-complete]
|
||||
@@ -339,15 +357,23 @@ jobs:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download NuGet artifact (plugin)
|
||||
- name: Download NuGet artifact
|
||||
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
|
||||
name: ${{ matrix.artifact }}
|
||||
- name: Compute package path
|
||||
id: compute-path
|
||||
run: |
|
||||
find . -maxdepth 1 -type f -name 'WoofWare.Myriad.*.nupkg' -exec sh -c 'echo "output=$(basename "$1")" >> $GITHUB_OUTPUT' shell {} \;
|
||||
- name: Compute tag name
|
||||
id: compute-tag
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: sh .github/workflows/tag.sh
|
||||
NUPKG_PATH: ${{ steps.compute-path.outputs.output }}
|
||||
run: echo "output=$(basename "$NUPKG_PATH" .nupkg)" >> $GITHUB_OUTPUT
|
||||
- name: Tag and release
|
||||
uses: G-Research/common-actions/github-release@19d7281a0f9f83e13c78f99a610dbc80fc59ba3b
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
target-commitish: ${{ github.sha }}
|
||||
tag: ${{ steps.compute-tag.outputs.output }}
|
||||
binary-contents: ${{ steps.compute-path.outputs.output }}
|
||||
|
11
.github/workflows/flake_update.yaml
vendored
11
.github/workflows/flake_update.yaml
vendored
@@ -21,21 +21,20 @@ jobs:
|
||||
- name: Update Nix flake
|
||||
run: 'nix flake update'
|
||||
|
||||
- name: Build passthru
|
||||
run: 'nix build ".#default.passthru.fetch-deps"'
|
||||
- name: Build fetch-deps
|
||||
run: 'nix build ".#default.fetch-deps"'
|
||||
|
||||
- name: Run passthru
|
||||
- name: Run fetch-deps
|
||||
run: |
|
||||
set -o pipefail
|
||||
./result | tee /tmp/passthru.txt
|
||||
cp /"$(cat /tmp/passthru.txt | grep " wrote lockfile to " | cut -d / -f 2-)" nix/deps.nix
|
||||
./result nix/deps.json
|
||||
|
||||
- name: Format
|
||||
run: 'nix develop --command alejandra .'
|
||||
|
||||
- name: Create token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@v1
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
# https://github.com/actions/create-github-app-token/issues/136
|
||||
app-id: ${{ secrets.APP_ID }}
|
||||
|
120
.github/workflows/tag.sh
vendored
120
.github/workflows/tag.sh
vendored
@@ -1,120 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Dry-run? $DRY_RUN!"
|
||||
|
||||
find . -maxdepth 1 -type f ! -name "$(printf "*\n*")" -name '*.nupkg' | while IFS= read -r file
|
||||
do
|
||||
tag=$(basename "$file" .nupkg)
|
||||
git tag "$tag"
|
||||
${DRY_RUN:+echo} git push origin "$tag"
|
||||
done
|
||||
|
||||
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_body='{"tag_name":"'"$TAG"'","target_commitish":"","name":"'"$TAG"'","draft":false,"prerelease":false,"generate_release_notes":false}'
|
||||
|
||||
echo "cURL body: $curl_body"
|
||||
|
||||
failed_output=$(cat <<'EOF'
|
||||
{
|
||||
"message": "Validation Failed",
|
||||
"errors": [
|
||||
{
|
||||
"resource": "Release",
|
||||
"code": "already_exists",
|
||||
"field": "tag_name"
|
||||
}
|
||||
],
|
||||
"documentation_url": "https://docs.github.com/rest/releases/releases#create-a-release"
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
success_output=$(cat <<'EOF'
|
||||
{
|
||||
"url": "https://api.github.com/repos/Smaug123/WoofWare.Myriad/releases/158152116",
|
||||
"assets_url": "https://api.github.com/repos/Smaug123/WoofWare.Myriad/releases/158152116/assets",
|
||||
"upload_url": "https://uploads.github.com/repos/Smaug123/WoofWare.Myriad/releases/158152116/assets{?name,label}",
|
||||
"html_url": "https://github.com/Smaug123/WoofWare.Myriad/releases/tag/WoofWare.Myriad.Plugins.2.1.30",
|
||||
"id": 158152116,
|
||||
"author": {
|
||||
"login": "github-actions[bot]",
|
||||
"id": 41898282,
|
||||
"node_id": "MDM6Qm90NDE4OTgyODI=",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/github-actions%5Bbot%5D",
|
||||
"html_url": "https://github.com/apps/github-actions",
|
||||
"followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers",
|
||||
"following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs",
|
||||
"repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos",
|
||||
"events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events",
|
||||
"type": "Bot",
|
||||
"site_admin": false
|
||||
},
|
||||
"node_id": "RE_kwDOJfksgc4JbTW0",
|
||||
"tag_name": "WoofWare.Myriad.Plugins.2.1.30",
|
||||
"target_commitish": "main",
|
||||
"name": "WoofWare.Myriad.Plugins.2.1.30",
|
||||
"draft": false,
|
||||
"prerelease": false,
|
||||
"created_at": "2024-05-30T11:00:55Z",
|
||||
"published_at": "2024-05-30T11:03:02Z",
|
||||
"assets": [
|
||||
|
||||
],
|
||||
"tarball_url": "https://api.github.com/repos/Smaug123/WoofWare.Myriad/tarball/WoofWare.Myriad.Plugins.2.1.30",
|
||||
"zipball_url": "https://api.github.com/repos/Smaug123/WoofWare.Myriad/zipball/WoofWare.Myriad.Plugins.2.1.30",
|
||||
"body": null
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
HANDLE_OUTPUT=''
|
||||
handle_error() {
|
||||
ERROR_OUTPUT="$1"
|
||||
exit_message=$(echo "$ERROR_OUTPUT" | jq -r --exit-status 'if .errors | length == 1 then .errors[0].code else null end')
|
||||
if [ "$exit_message" = "already_exists" ] ; then
|
||||
HANDLE_OUTPUT="Did not create GitHub release because it already exists at this version."
|
||||
else
|
||||
echo "Unexpected error output from curl: $(cat curl_output.json)"
|
||||
echo "JQ output: $(exit_message)"
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
run_tests() {
|
||||
handle_error "$failed_output"
|
||||
if [ "$HANDLE_OUTPUT" != "Did not create GitHub release because it already exists at this version." ]; then
|
||||
echo "Bad output from handler: $HANDLE_OUTPUT"
|
||||
exit 3
|
||||
fi
|
||||
HANDLE_OUTPUT=''
|
||||
echo "Tests passed."
|
||||
}
|
||||
|
||||
run_tests
|
||||
|
||||
if [ "$DRY_RUN" != 1 ] ; then
|
||||
if curl --fail-with-body -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 "$curl_body" > curl_output.json; then
|
||||
echo "Curl succeeded."
|
||||
else
|
||||
handle_error "$(cat curl_output.json)"
|
||||
echo "$HANDLE_OUTPUT"
|
||||
fi
|
||||
fi
|
22
CHANGELOG.md
22
CHANGELOG.md
@@ -1,5 +1,27 @@
|
||||
Notable changes are recorded here.
|
||||
|
||||
# WoofWare.Myriad.Plugins 7.0.1
|
||||
|
||||
All generators should now be compatible with `<Nullable>enable</Nullable>`.
|
||||
|
||||
**Please test the results and let me know of unexpected failures.**
|
||||
There are a number of heuristics in this code, because:
|
||||
|
||||
* `System.Text.Json.Nodes` is an unfathomably weird API which simply requires us to make educated guesses about whether a user-provided type is supposed to be nullable, despite this being irrelevant to the operation of `System.Text.Json`;
|
||||
* Some types (like `Uri` and `String`) have `ToString` methods which can't return `null`, but in general `Object.ToString` can of course return `null`, and as far as I can tell there is simply no way to know from the source alone whether a given type will have a nullable `ToString`.
|
||||
|
||||
# WoofWare.Myriad.Plugins 6.0.1
|
||||
|
||||
The `ArgParser` generator's type signatures have changed.
|
||||
The `parse'` method no longer takes `getEnvironmentVariable : string -> string`; it's now `getEnvironmentVariable : string -> string option`.
|
||||
This is to permit satisfying the `<Nullable>enable</Nullable>` compiler setting.
|
||||
If you're calling `parse'`, give it `Environment.GetEnvironmentVariable >> Option.ofObj` instead.
|
||||
|
||||
# WoofWare.Myriad.Plugins 5.0.1
|
||||
|
||||
We now enforce non-nullability on more types during JSON parse.
|
||||
We have always expected you to consume nullable types wrapped in an `option`, but now we enforce this in more cases by throwing `ArgumentNullException`.
|
||||
|
||||
# WoofWare.Myriad.Plugins 3.0.1
|
||||
|
||||
Semantics of `HttpClient`'s URI component composition changed:
|
||||
|
@@ -1,9 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<OtherFlags>--reflectionfree $(OtherFlags)</OtherFlags>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<MyriadSdkGenerator Include="$(MSBuildThisFileDirectory)..\WoofWare.Myriad.Plugins\bin\$(Configuration)\net6.0\WoofWare.Myriad.Plugins.dll"/>
|
||||
@@ -32,6 +33,20 @@
|
||||
<Compile Include="GeneratedMock.fs">
|
||||
<MyriadFile>MockExample.fs</MyriadFile>
|
||||
</Compile>
|
||||
<Compile Include="MockExampleNoAttributes.fs" />
|
||||
<Compile Include="GeneratedMockNoAttributes.fs">
|
||||
<MyriadFile>MockExampleNoAttributes.fs</MyriadFile>
|
||||
<MyriadParams>
|
||||
<IPublicTypeNoAttr>GenerateMock</IPublicTypeNoAttr>
|
||||
<IPublicTypeInternalFalseNoAttr>GenerateMock(false)</IPublicTypeInternalFalseNoAttr>
|
||||
<InternalTypeNoAttr>GenerateMock</InternalTypeNoAttr>
|
||||
<PrivateTypeNoAttr>GenerateMock</PrivateTypeNoAttr>
|
||||
<PrivateTypeInternalFalseNoAttr>GenerateMock(false)</PrivateTypeInternalFalseNoAttr>
|
||||
<VeryPublicTypeNoAttr>GenerateMock</VeryPublicTypeNoAttr>
|
||||
<CurriedNoAttr>GenerateMock</CurriedNoAttr>
|
||||
<TypeWithInterfaceNoAttr>GenerateMock</TypeWithInterfaceNoAttr>
|
||||
</MyriadParams>
|
||||
</Compile>
|
||||
<Compile Include="Vault.fs" />
|
||||
<Compile Include="GeneratedVault.fs">
|
||||
<MyriadFile>Vault.fs</MyriadFile>
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,7 @@ module BasicNoPositionals =
|
||||
/// Waiting to receive a value for the key we've already consumed
|
||||
| AwaitingValue of key : string
|
||||
|
||||
let parse' (getEnvironmentVariable : string -> string) (args : string list) : BasicNoPositionals =
|
||||
let parse' (getEnvironmentVariable : string -> string option) (args : string list) : BasicNoPositionals =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -223,7 +223,7 @@ module BasicNoPositionals =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
let parse (args : string list) : BasicNoPositionals =
|
||||
parse' System.Environment.GetEnvironmentVariable args
|
||||
parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -239,7 +239,7 @@ module Basic =
|
||||
/// Waiting to receive a value for the key we've already consumed
|
||||
| AwaitingValue of key : string
|
||||
|
||||
let parse' (getEnvironmentVariable : string -> string) (args : string list) : Basic =
|
||||
let parse' (getEnvironmentVariable : string -> string option) (args : string list) : Basic =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -430,7 +430,7 @@ module Basic =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
let parse (args : string list) : Basic =
|
||||
parse' System.Environment.GetEnvironmentVariable args
|
||||
parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -446,7 +446,7 @@ module BasicWithIntPositionals =
|
||||
/// Waiting to receive a value for the key we've already consumed
|
||||
| AwaitingValue of key : string
|
||||
|
||||
let parse' (getEnvironmentVariable : string -> string) (args : string list) : BasicWithIntPositionals =
|
||||
let parse' (getEnvironmentVariable : string -> string option) (args : string list) : BasicWithIntPositionals =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -633,7 +633,7 @@ module BasicWithIntPositionals =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
let parse (args : string list) : BasicWithIntPositionals =
|
||||
parse' System.Environment.GetEnvironmentVariable args
|
||||
parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -649,7 +649,7 @@ module LoadsOfTypes =
|
||||
/// Waiting to receive a value for the key we've already consumed
|
||||
| AwaitingValue of key : string
|
||||
|
||||
let parse' (getEnvironmentVariable : string -> string) (args : string list) : LoadsOfTypes =
|
||||
let parse' (getEnvironmentVariable : string -> string option) (args : string list) : LoadsOfTypes =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -1038,7 +1038,7 @@ module LoadsOfTypes =
|
||||
match arg_10 with
|
||||
| None ->
|
||||
match "CONSUMEPLUGIN_THINGS" |> getEnvironmentVariable with
|
||||
| null ->
|
||||
| None ->
|
||||
sprintf
|
||||
"No value was supplied for %s, nor was environment variable %s set"
|
||||
(sprintf "--%s" "yet-another-optional-thing")
|
||||
@@ -1046,7 +1046,7 @@ module LoadsOfTypes =
|
||||
|> ArgParser_errors.Add
|
||||
|
||||
Unchecked.defaultof<_>
|
||||
| x -> x |> (fun x -> x)
|
||||
| Some x -> x |> (fun x -> x)
|
||||
|> Choice2Of2
|
||||
| Some x -> Choice1Of2 x
|
||||
|
||||
@@ -1068,7 +1068,7 @@ module LoadsOfTypes =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
let parse (args : string list) : LoadsOfTypes =
|
||||
parse' System.Environment.GetEnvironmentVariable args
|
||||
parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -1084,7 +1084,7 @@ module LoadsOfTypesNoPositionals =
|
||||
/// Waiting to receive a value for the key we've already consumed
|
||||
| AwaitingValue of key : string
|
||||
|
||||
let parse' (getEnvironmentVariable : string -> string) (args : string list) : LoadsOfTypesNoPositionals =
|
||||
let parse' (getEnvironmentVariable : string -> string option) (args : string list) : LoadsOfTypesNoPositionals =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -1476,7 +1476,7 @@ module LoadsOfTypesNoPositionals =
|
||||
match arg_9 with
|
||||
| None ->
|
||||
match "CONSUMEPLUGIN_THINGS" |> getEnvironmentVariable with
|
||||
| null ->
|
||||
| None ->
|
||||
sprintf
|
||||
"No value was supplied for %s, nor was environment variable %s set"
|
||||
(sprintf "--%s" "yet-another-optional-thing")
|
||||
@@ -1484,7 +1484,7 @@ module LoadsOfTypesNoPositionals =
|
||||
|> ArgParser_errors.Add
|
||||
|
||||
Unchecked.defaultof<_>
|
||||
| x -> x |> (fun x -> x)
|
||||
| Some x -> x |> (fun x -> x)
|
||||
|> Choice2Of2
|
||||
| Some x -> Choice1Of2 x
|
||||
|
||||
@@ -1505,7 +1505,7 @@ module LoadsOfTypesNoPositionals =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
let parse (args : string list) : LoadsOfTypesNoPositionals =
|
||||
parse' System.Environment.GetEnvironmentVariable args
|
||||
parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -1524,7 +1524,7 @@ module DatesAndTimesArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type DatesAndTimes with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : DatesAndTimes =
|
||||
static member parse' (getEnvironmentVariable : string -> string option) (args : string list) : DatesAndTimes =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -1787,7 +1787,7 @@ module DatesAndTimesArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : DatesAndTimes =
|
||||
DatesAndTimes.parse' System.Environment.GetEnvironmentVariable args
|
||||
DatesAndTimes.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -1806,7 +1806,7 @@ module ParentRecordArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type ParentRecord with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ParentRecord =
|
||||
static member parse' (getEnvironmentVariable : string -> string option) (args : string list) : ParentRecord =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -2016,7 +2016,7 @@ module ParentRecordArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ParentRecord =
|
||||
ParentRecord.parse' System.Environment.GetEnvironmentVariable args
|
||||
ParentRecord.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -2035,7 +2035,11 @@ module ParentRecordChildPosArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type ParentRecordChildPos with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ParentRecordChildPos =
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: ParentRecordChildPos
|
||||
=
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -2209,7 +2213,7 @@ module ParentRecordChildPosArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ParentRecordChildPos =
|
||||
ParentRecordChildPos.parse' System.Environment.GetEnvironmentVariable args
|
||||
ParentRecordChildPos.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -2228,7 +2232,11 @@ module ParentRecordSelfPosArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type ParentRecordSelfPos with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ParentRecordSelfPos =
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: ParentRecordSelfPos
|
||||
=
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -2388,7 +2396,7 @@ module ParentRecordSelfPosArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ParentRecordSelfPos =
|
||||
ParentRecordSelfPos.parse' System.Environment.GetEnvironmentVariable args
|
||||
ParentRecordSelfPos.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -2407,7 +2415,11 @@ module ChoicePositionalsArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type ChoicePositionals with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ChoicePositionals =
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: ChoicePositionals
|
||||
=
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -2502,7 +2514,7 @@ module ChoicePositionalsArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ChoicePositionals =
|
||||
ChoicePositionals.parse' System.Environment.GetEnvironmentVariable args
|
||||
ChoicePositionals.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -2521,7 +2533,11 @@ module ContainsBoolEnvVarArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type ContainsBoolEnvVar with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ContainsBoolEnvVar =
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: ContainsBoolEnvVar
|
||||
=
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -2653,7 +2669,7 @@ module ContainsBoolEnvVarArgParse =
|
||||
match arg_0 with
|
||||
| None ->
|
||||
match "CONSUMEPLUGIN_THINGS" |> getEnvironmentVariable with
|
||||
| null ->
|
||||
| None ->
|
||||
sprintf
|
||||
"No value was supplied for %s, nor was environment variable %s set"
|
||||
(sprintf "--%s" "bool-var")
|
||||
@@ -2661,7 +2677,7 @@ module ContainsBoolEnvVarArgParse =
|
||||
|> ArgParser_errors.Add
|
||||
|
||||
Unchecked.defaultof<_>
|
||||
| x ->
|
||||
| Some x ->
|
||||
if System.String.Equals (x, "1", System.StringComparison.OrdinalIgnoreCase) then
|
||||
true
|
||||
else if System.String.Equals (x, "0", System.StringComparison.OrdinalIgnoreCase) then
|
||||
@@ -2679,7 +2695,7 @@ module ContainsBoolEnvVarArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ContainsBoolEnvVar =
|
||||
ContainsBoolEnvVar.parse' System.Environment.GetEnvironmentVariable args
|
||||
ContainsBoolEnvVar.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -2698,7 +2714,7 @@ module WithFlagDuArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type WithFlagDu with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : WithFlagDu =
|
||||
static member parse' (getEnvironmentVariable : string -> string option) (args : string list) : WithFlagDu =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -2852,7 +2868,7 @@ module WithFlagDuArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : WithFlagDu =
|
||||
WithFlagDu.parse' System.Environment.GetEnvironmentVariable args
|
||||
WithFlagDu.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -2871,7 +2887,11 @@ module ContainsFlagEnvVarArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type ContainsFlagEnvVar with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ContainsFlagEnvVar =
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: ContainsFlagEnvVar
|
||||
=
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -3018,7 +3038,7 @@ module ContainsFlagEnvVarArgParse =
|
||||
match arg_0 with
|
||||
| None ->
|
||||
match "CONSUMEPLUGIN_THINGS" |> getEnvironmentVariable with
|
||||
| null ->
|
||||
| None ->
|
||||
sprintf
|
||||
"No value was supplied for %s, nor was environment variable %s set"
|
||||
(sprintf "--%s" "dry-run")
|
||||
@@ -3026,7 +3046,7 @@ module ContainsFlagEnvVarArgParse =
|
||||
|> ArgParser_errors.Add
|
||||
|
||||
Unchecked.defaultof<_>
|
||||
| x ->
|
||||
| Some x ->
|
||||
if System.String.Equals (x, "1", System.StringComparison.OrdinalIgnoreCase) then
|
||||
if true = Consts.FALSE then
|
||||
DryRunMode.Wet
|
||||
@@ -3056,7 +3076,7 @@ module ContainsFlagEnvVarArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ContainsFlagEnvVar =
|
||||
ContainsFlagEnvVar.parse' System.Environment.GetEnvironmentVariable args
|
||||
ContainsFlagEnvVar.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -3076,7 +3096,7 @@ module ContainsFlagDefaultValueArgParse =
|
||||
type ContainsFlagDefaultValue with
|
||||
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string)
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: ContainsFlagDefaultValue
|
||||
=
|
||||
@@ -3239,7 +3259,7 @@ module ContainsFlagDefaultValueArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ContainsFlagDefaultValue =
|
||||
ContainsFlagDefaultValue.parse' System.Environment.GetEnvironmentVariable args
|
||||
ContainsFlagDefaultValue.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -3258,7 +3278,7 @@ module ManyLongFormsArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type ManyLongForms with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ManyLongForms =
|
||||
static member parse' (getEnvironmentVariable : string -> string option) (args : string list) : ManyLongForms =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -3504,7 +3524,7 @@ module ManyLongFormsArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ManyLongForms =
|
||||
ManyLongForms.parse' System.Environment.GetEnvironmentVariable args
|
||||
ManyLongForms.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -3524,7 +3544,7 @@ module FlagsIntoPositionalArgsArgParse =
|
||||
type FlagsIntoPositionalArgs with
|
||||
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string)
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: FlagsIntoPositionalArgs
|
||||
=
|
||||
@@ -3668,7 +3688,7 @@ module FlagsIntoPositionalArgsArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : FlagsIntoPositionalArgs =
|
||||
FlagsIntoPositionalArgs.parse' System.Environment.GetEnvironmentVariable args
|
||||
FlagsIntoPositionalArgs.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -3688,7 +3708,7 @@ module FlagsIntoPositionalArgsChoiceArgParse =
|
||||
type FlagsIntoPositionalArgsChoice with
|
||||
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string)
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: FlagsIntoPositionalArgsChoice
|
||||
=
|
||||
@@ -3832,7 +3852,7 @@ module FlagsIntoPositionalArgsChoiceArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : FlagsIntoPositionalArgsChoice =
|
||||
FlagsIntoPositionalArgsChoice.parse' System.Environment.GetEnvironmentVariable args
|
||||
FlagsIntoPositionalArgsChoice.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -3852,7 +3872,7 @@ module FlagsIntoPositionalArgsIntArgParse =
|
||||
type FlagsIntoPositionalArgsInt with
|
||||
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string)
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: FlagsIntoPositionalArgsInt
|
||||
=
|
||||
@@ -3996,7 +4016,7 @@ module FlagsIntoPositionalArgsIntArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : FlagsIntoPositionalArgsInt =
|
||||
FlagsIntoPositionalArgsInt.parse' System.Environment.GetEnvironmentVariable args
|
||||
FlagsIntoPositionalArgsInt.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -4016,7 +4036,7 @@ module FlagsIntoPositionalArgsIntChoiceArgParse =
|
||||
type FlagsIntoPositionalArgsIntChoice with
|
||||
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string)
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: FlagsIntoPositionalArgsIntChoice
|
||||
=
|
||||
@@ -4160,7 +4180,7 @@ module FlagsIntoPositionalArgsIntChoiceArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : FlagsIntoPositionalArgsIntChoice =
|
||||
FlagsIntoPositionalArgsIntChoice.parse' System.Environment.GetEnvironmentVariable args
|
||||
FlagsIntoPositionalArgsIntChoice.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -4180,7 +4200,7 @@ module FlagsIntoPositionalArgs'ArgParse =
|
||||
type FlagsIntoPositionalArgs' with
|
||||
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string)
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: FlagsIntoPositionalArgs'
|
||||
=
|
||||
@@ -4324,4 +4344,4 @@ module FlagsIntoPositionalArgs'ArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : FlagsIntoPositionalArgs' =
|
||||
FlagsIntoPositionalArgs'.parse' System.Environment.GetEnvironmentVariable args
|
||||
FlagsIntoPositionalArgs'.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
|
@@ -31,7 +31,7 @@ module FileSystemItemCata =
|
||||
[<RequireQualifiedAccess>]
|
||||
type private Instruction =
|
||||
| Process__FileSystemItem of FileSystemItem
|
||||
| FileSystemItem_Directory of string * int * int
|
||||
| FileSystemItem_Directory of name : string * dirSize : int * contents : int
|
||||
|
||||
let private loop (cata : FileSystemCata<'FileSystemItem>) (instructions : ResizeArray<Instruction>) =
|
||||
let fileSystemItemStack = ResizeArray<'FileSystemItem> ()
|
||||
@@ -106,7 +106,7 @@ module GiftCata =
|
||||
| Process__Gift of Gift
|
||||
| Gift_Wrapped of WrappingPaperStyle
|
||||
| Gift_Boxed
|
||||
| Gift_WithACard of string
|
||||
| Gift_WithACard of message : string
|
||||
|
||||
let private loop (cata : GiftCata<'Gift>) (instructions : ResizeArray<Instruction>) =
|
||||
let giftStack = ResizeArray<'Gift> ()
|
||||
|
@@ -14,7 +14,24 @@ module internal InternalTypeNotExtensionSerial =
|
||||
/// Serialize to a JSON node
|
||||
let toJsonNode (input : InternalTypeNotExtensionSerial) : System.Text.Json.Nodes.JsonNode =
|
||||
let node = System.Text.Json.Nodes.JsonObject ()
|
||||
do node.Add ((Literals.something), (input.InternalThing2 |> System.Text.Json.Nodes.JsonValue.Create<string>))
|
||||
|
||||
do
|
||||
node.Add (
|
||||
(Literals.something),
|
||||
(input.InternalThing2
|
||||
|> (fun field ->
|
||||
let field = System.Text.Json.Nodes.JsonValue.Create<string> field
|
||||
|
||||
(match field with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected type string to be non-null, but received a null value when serialising"
|
||||
)
|
||||
| field -> field)
|
||||
))
|
||||
)
|
||||
|
||||
node :> _
|
||||
namespace ConsumePlugin
|
||||
|
||||
@@ -29,7 +46,24 @@ module internal InternalTypeExtensionJsonSerializeExtension =
|
||||
/// Serialize to a JSON node
|
||||
static member toJsonNode (input : InternalTypeExtension) : System.Text.Json.Nodes.JsonNode =
|
||||
let node = System.Text.Json.Nodes.JsonObject ()
|
||||
do node.Add ((Literals.something), (input.ExternalThing |> System.Text.Json.Nodes.JsonValue.Create<string>))
|
||||
|
||||
do
|
||||
node.Add (
|
||||
(Literals.something),
|
||||
(input.ExternalThing
|
||||
|> (fun field ->
|
||||
let field = System.Text.Json.Nodes.JsonValue.Create<string> field
|
||||
|
||||
(match field with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected type string to be non-null, but received a null value when serialising"
|
||||
)
|
||||
| field -> field)
|
||||
))
|
||||
)
|
||||
|
||||
node :> _
|
||||
|
||||
namespace ConsumePlugin
|
||||
@@ -40,16 +74,14 @@ module InnerType =
|
||||
/// Parse from a JSON node.
|
||||
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : InnerType =
|
||||
let arg_0 =
|
||||
(match node.[(Literals.something)] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.[(Literals.something)] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
{
|
||||
Thing = arg_0
|
||||
@@ -62,79 +94,97 @@ module JsonRecordType =
|
||||
/// Parse from a JSON node.
|
||||
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : JsonRecordType =
|
||||
let arg_5 =
|
||||
(match node.["f"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("f")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsArray ()
|
||||
|> Seq.map (fun elt -> elt.AsValue().GetValue<System.Int32> ())
|
||||
|> Array.ofSeq
|
||||
match node.["f"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("f")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsArray ()
|
||||
|> Seq.map (fun elt ->
|
||||
(match elt with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected element of array (element type int32) to be non-null, but found a null element"
|
||||
)
|
||||
| elt -> elt.AsValue().GetValue<System.Int32> ())
|
||||
)
|
||||
|> Array.ofSeq
|
||||
|
||||
let arg_4 =
|
||||
(match node.["e"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("e")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsArray ()
|
||||
|> Seq.map (fun elt -> elt.AsValue().GetValue<System.String> ())
|
||||
|> Array.ofSeq
|
||||
match node.["e"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("e")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsArray ()
|
||||
|> Seq.map (fun elt ->
|
||||
(match elt with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected element of array (element type string) to be non-null, but found a null element"
|
||||
)
|
||||
| elt -> elt.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> Array.ofSeq
|
||||
|
||||
let arg_3 =
|
||||
InnerType.jsonParse (
|
||||
match node.["d"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("d")
|
||||
)
|
||||
match node.["d"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("d")
|
||||
)
|
||||
| v -> v
|
||||
)
|
||||
)
|
||||
| Some node -> InnerType.jsonParse node
|
||||
|
||||
let arg_2 =
|
||||
(match node.["hi"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("hi")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsArray ()
|
||||
|> Seq.map (fun elt -> elt.AsValue().GetValue<System.Int32> ())
|
||||
|> List.ofSeq
|
||||
match node.["hi"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("hi")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsArray ()
|
||||
|> Seq.map (fun elt ->
|
||||
(match elt with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected element of array (element type int32) to be non-null, but found a null element"
|
||||
)
|
||||
| elt -> elt.AsValue().GetValue<System.Int32> ())
|
||||
)
|
||||
|> List.ofSeq
|
||||
|
||||
let arg_1 =
|
||||
(match node.["another-thing"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("another-thing")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["another-thing"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("another-thing")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
let arg_0 =
|
||||
(match node.["a"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("a")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int32> ()
|
||||
match node.["a"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("a")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int32> ()
|
||||
|
||||
{
|
||||
A = arg_0
|
||||
@@ -152,16 +202,14 @@ module internal InternalTypeNotExtension =
|
||||
/// Parse from a JSON node.
|
||||
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : InternalTypeNotExtension =
|
||||
let arg_0 =
|
||||
(match node.[(Literals.something)] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.[(Literals.something)] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
{
|
||||
InternalThing = arg_0
|
||||
@@ -177,16 +225,14 @@ module internal InternalTypeExtensionJsonParseExtension =
|
||||
/// Parse from a JSON node.
|
||||
static member jsonParse (node : System.Text.Json.Nodes.JsonNode) : InternalTypeExtension =
|
||||
let arg_0 =
|
||||
(match node.[(Literals.something)] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.[(Literals.something)] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
{
|
||||
ExternalThing = arg_0
|
||||
@@ -201,248 +247,215 @@ module ToGetExtensionMethodJsonParseExtension =
|
||||
|
||||
/// Parse from a JSON node.
|
||||
static member jsonParse (node : System.Text.Json.Nodes.JsonNode) : ToGetExtensionMethod =
|
||||
let arg_20 = System.Numerics.BigInteger.Parse (node.["whiskey"].ToJsonString ())
|
||||
let arg_20 =
|
||||
match node.["whiskey"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("whiskey")
|
||||
)
|
||||
)
|
||||
| Some node -> System.Numerics.BigInteger.Parse (node.ToJsonString ())
|
||||
|
||||
let arg_19 =
|
||||
(match node.["victor"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("victor")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Char> ()
|
||||
match node.["victor"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("victor")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Char> ()
|
||||
|
||||
let arg_18 =
|
||||
(match node.["uniform"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("uniform")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Decimal> ()
|
||||
match node.["uniform"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("uniform")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Decimal> ()
|
||||
|
||||
let arg_17 =
|
||||
(match node.["tango"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("tango")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.SByte> ()
|
||||
match node.["tango"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("tango")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.SByte> ()
|
||||
|
||||
let arg_16 =
|
||||
(match node.["quebec"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("quebec")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Byte> ()
|
||||
match node.["quebec"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("quebec")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Byte> ()
|
||||
|
||||
let arg_15 =
|
||||
(match node.["papa"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("papa")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Byte> ()
|
||||
match node.["papa"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("papa")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Byte> ()
|
||||
|
||||
let arg_14 =
|
||||
(match node.["oscar"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("oscar")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.SByte> ()
|
||||
match node.["oscar"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("oscar")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.SByte> ()
|
||||
|
||||
let arg_13 =
|
||||
(match node.["november"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("november")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.UInt16> ()
|
||||
match node.["november"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("november")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.UInt16> ()
|
||||
|
||||
let arg_12 =
|
||||
(match node.["mike"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("mike")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int16> ()
|
||||
match node.["mike"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("mike")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int16> ()
|
||||
|
||||
let arg_11 =
|
||||
(match node.["lima"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lima")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.UInt32> ()
|
||||
match node.["lima"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lima")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.UInt32> ()
|
||||
|
||||
let arg_10 =
|
||||
(match node.["kilo"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("kilo")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int32> ()
|
||||
match node.["kilo"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("kilo")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int32> ()
|
||||
|
||||
let arg_9 =
|
||||
(match node.["juliette"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("juliette")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.UInt32> ()
|
||||
match node.["juliette"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("juliette")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.UInt32> ()
|
||||
|
||||
let arg_8 =
|
||||
(match node.["india"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("india")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int32> ()
|
||||
match node.["india"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("india")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int32> ()
|
||||
|
||||
let arg_7 =
|
||||
(match node.["hotel"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("hotel")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.UInt64> ()
|
||||
match node.["hotel"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("hotel")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.UInt64> ()
|
||||
|
||||
let arg_6 =
|
||||
(match node.["golf"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("golf")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int64> ()
|
||||
match node.["golf"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("golf")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int64> ()
|
||||
|
||||
let arg_5 =
|
||||
(match node.["foxtrot"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("foxtrot")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Double> ()
|
||||
match node.["foxtrot"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("foxtrot")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Double> ()
|
||||
|
||||
let arg_4 =
|
||||
(match node.["echo"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("echo")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Single> ()
|
||||
match node.["echo"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("echo")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Single> ()
|
||||
|
||||
let arg_3 =
|
||||
(match node.["delta"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("delta")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Single> ()
|
||||
match node.["delta"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("delta")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Single> ()
|
||||
|
||||
let arg_2 =
|
||||
(match node.["charlie"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("charlie")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Double> ()
|
||||
match node.["charlie"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("charlie")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Double> ()
|
||||
|
||||
let arg_1 =
|
||||
(match node.["bravo"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("bravo")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<string> ()
|
||||
|> System.Uri
|
||||
match node.["bravo"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("bravo")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<string> () |> System.Uri
|
||||
|
||||
let arg_0 =
|
||||
(match node.["alpha"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("alpha")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["alpha"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("alpha")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
{
|
||||
Alpha = arg_0
|
||||
|
@@ -206,3 +206,34 @@ type internal TypeWithInterfaceMock =
|
||||
|
||||
interface System.IDisposable with
|
||||
member this.Dispose () : unit = this.Dispose ()
|
||||
namespace SomeNamespace
|
||||
|
||||
open System
|
||||
open WoofWare.Myriad.Plugins
|
||||
|
||||
/// Mock record type for an interface
|
||||
type internal TypeWithPropertiesMock =
|
||||
{
|
||||
/// Implementation of IDisposable.Dispose
|
||||
Dispose : unit -> unit
|
||||
Prop1 : unit -> int
|
||||
Prop2 : unit -> unit Async
|
||||
Mem1 : string option -> string[] Async
|
||||
}
|
||||
|
||||
/// An implementation where every method throws.
|
||||
static member Empty : TypeWithPropertiesMock =
|
||||
{
|
||||
Dispose = (fun () -> ())
|
||||
Prop1 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Prop1"))
|
||||
Prop2 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Prop2"))
|
||||
Mem1 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem1"))
|
||||
}
|
||||
|
||||
interface TypeWithProperties with
|
||||
member this.Mem1 arg_0_0 = this.Mem1 (arg_0_0)
|
||||
member this.Prop1 = this.Prop1 ()
|
||||
member this.Prop2 = this.Prop2 ()
|
||||
|
||||
interface System.IDisposable with
|
||||
member this.Dispose () : unit = this.Dispose ()
|
||||
|
200
ConsumePlugin/GeneratedMockNoAttributes.fs
Normal file
200
ConsumePlugin/GeneratedMockNoAttributes.fs
Normal file
@@ -0,0 +1,200 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// This code was generated by myriad.
|
||||
// Changes to this file will be lost when the code is regenerated.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace SomeNamespace
|
||||
|
||||
open System
|
||||
|
||||
/// Mock record type for an interface
|
||||
type internal PublicTypeNoAttrMock =
|
||||
{
|
||||
Mem1 : string * int -> string list
|
||||
Mem2 : string -> int
|
||||
Mem3 : int * option<System.Threading.CancellationToken> -> string
|
||||
}
|
||||
|
||||
/// An implementation where every method throws.
|
||||
static member Empty : PublicTypeNoAttrMock =
|
||||
{
|
||||
Mem1 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem1"))
|
||||
Mem2 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem2"))
|
||||
Mem3 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem3"))
|
||||
}
|
||||
|
||||
interface IPublicTypeNoAttr with
|
||||
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.Mem3 (arg_0_0, arg_0_1) = this.Mem3 (arg_0_0, arg_0_1)
|
||||
namespace SomeNamespace
|
||||
|
||||
open System
|
||||
|
||||
/// Mock record type for an interface
|
||||
type public PublicTypeInternalFalseNoAttrMock =
|
||||
{
|
||||
Mem1 : string * int -> string list
|
||||
Mem2 : string -> int
|
||||
Mem3 : int * option<System.Threading.CancellationToken> -> string
|
||||
}
|
||||
|
||||
/// An implementation where every method throws.
|
||||
static member Empty : PublicTypeInternalFalseNoAttrMock =
|
||||
{
|
||||
Mem1 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem1"))
|
||||
Mem2 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem2"))
|
||||
Mem3 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem3"))
|
||||
}
|
||||
|
||||
interface IPublicTypeInternalFalseNoAttr with
|
||||
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.Mem3 (arg_0_0, arg_0_1) = this.Mem3 (arg_0_0, arg_0_1)
|
||||
namespace SomeNamespace
|
||||
|
||||
open System
|
||||
|
||||
/// Mock record type for an interface
|
||||
type internal InternalTypeNoAttrMock =
|
||||
{
|
||||
Mem1 : string * int -> unit
|
||||
Mem2 : string -> int
|
||||
}
|
||||
|
||||
/// An implementation where every method throws.
|
||||
static member Empty : InternalTypeNoAttrMock =
|
||||
{
|
||||
Mem1 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem1"))
|
||||
Mem2 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem2"))
|
||||
}
|
||||
|
||||
interface InternalTypeNoAttr with
|
||||
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)
|
||||
namespace SomeNamespace
|
||||
|
||||
open System
|
||||
|
||||
/// Mock record type for an interface
|
||||
type private PrivateTypeNoAttrMock =
|
||||
{
|
||||
Mem1 : string * int -> unit
|
||||
Mem2 : string -> int
|
||||
}
|
||||
|
||||
/// An implementation where every method throws.
|
||||
static member Empty : PrivateTypeNoAttrMock =
|
||||
{
|
||||
Mem1 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem1"))
|
||||
Mem2 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem2"))
|
||||
}
|
||||
|
||||
interface PrivateTypeNoAttr with
|
||||
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)
|
||||
namespace SomeNamespace
|
||||
|
||||
open System
|
||||
|
||||
/// Mock record type for an interface
|
||||
type private PrivateTypeInternalFalseNoAttrMock =
|
||||
{
|
||||
Mem1 : string * int -> unit
|
||||
Mem2 : string -> int
|
||||
}
|
||||
|
||||
/// An implementation where every method throws.
|
||||
static member Empty : PrivateTypeInternalFalseNoAttrMock =
|
||||
{
|
||||
Mem1 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem1"))
|
||||
Mem2 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem2"))
|
||||
}
|
||||
|
||||
interface PrivateTypeInternalFalseNoAttr with
|
||||
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)
|
||||
namespace SomeNamespace
|
||||
|
||||
open System
|
||||
|
||||
/// Mock record type for an interface
|
||||
type internal VeryPublicTypeNoAttrMock<'a, 'b> =
|
||||
{
|
||||
Mem1 : 'a -> 'b
|
||||
}
|
||||
|
||||
/// An implementation where every method throws.
|
||||
static member Empty () : VeryPublicTypeNoAttrMock<'a, 'b> =
|
||||
{
|
||||
Mem1 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem1"))
|
||||
}
|
||||
|
||||
interface VeryPublicTypeNoAttr<'a, 'b> with
|
||||
member this.Mem1 arg_0_0 = this.Mem1 (arg_0_0)
|
||||
namespace SomeNamespace
|
||||
|
||||
open System
|
||||
|
||||
/// Mock record type for an interface
|
||||
type internal CurriedNoAttrMock<'a> =
|
||||
{
|
||||
Mem1 : int -> 'a -> string
|
||||
Mem2 : int * string -> 'a -> string
|
||||
Mem3 : (int * string) -> 'a -> string
|
||||
Mem4 : (int * string) -> ('a * int) -> string
|
||||
Mem5 : int * string -> ('a * int) -> string
|
||||
Mem6 : int * string -> 'a * int -> string
|
||||
}
|
||||
|
||||
/// An implementation where every method throws.
|
||||
static member Empty () : CurriedNoAttrMock<'a> =
|
||||
{
|
||||
Mem1 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem1"))
|
||||
Mem2 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem2"))
|
||||
Mem3 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem3"))
|
||||
Mem4 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem4"))
|
||||
Mem5 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem5"))
|
||||
Mem6 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem6"))
|
||||
}
|
||||
|
||||
interface CurriedNoAttr<'a> with
|
||||
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.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)) =
|
||||
this.Mem4 (arg_0_0, arg_0_1) (arg_1_0, arg_1_1)
|
||||
|
||||
member this.Mem5 (arg_0_0, arg_0_1) ((arg_1_0, arg_1_1)) =
|
||||
this.Mem5 (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)
|
||||
namespace SomeNamespace
|
||||
|
||||
open System
|
||||
|
||||
/// Mock record type for an interface
|
||||
type internal TypeWithInterfaceNoAttrMock =
|
||||
{
|
||||
/// 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 : TypeWithInterfaceNoAttrMock =
|
||||
{
|
||||
Dispose = (fun () -> ())
|
||||
Mem1 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem1"))
|
||||
Mem2 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem2"))
|
||||
}
|
||||
|
||||
interface TypeWithInterfaceNoAttr 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 ()
|
File diff suppressed because it is too large
Load Diff
@@ -48,7 +48,27 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
return jsonNode.AsArray () |> Seq.map (fun elt -> Gym.jsonParse elt) |> List.ofSeq
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type Gym list"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return
|
||||
jsonNode.AsArray ()
|
||||
|> Seq.map (fun elt ->
|
||||
(match elt with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected element of array (element type Gym) to be non-null, but found a null element"
|
||||
)
|
||||
| elt -> Gym.jsonParse elt)
|
||||
)
|
||||
|> List.ofSeq
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
|
||||
@@ -63,7 +83,7 @@ module PureGymApi =
|
||||
| v -> v),
|
||||
System.Uri (
|
||||
"v1/gyms/{gym_id}/attendance"
|
||||
.Replace ("{gym_id}", gymId.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
.Replace ("{gym_id}", gymId.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -82,6 +102,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type GymAttendance"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return GymAttendance.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -97,7 +126,7 @@ module PureGymApi =
|
||||
| v -> v),
|
||||
System.Uri (
|
||||
"v1/gyms/{gym_id}/attendance"
|
||||
.Replace ("{gym_id}", gymId.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
.Replace ("{gym_id}", gymId.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -116,6 +145,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type GymAttendance"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return GymAttendance.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -146,6 +184,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type Member"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return Member.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -160,8 +207,7 @@ module PureGymApi =
|
||||
| null -> System.Uri "https://whatnot.com/"
|
||||
| v -> v),
|
||||
System.Uri (
|
||||
"v1/gyms/{gym}"
|
||||
.Replace ("{gym}", gym.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
"v1/gyms/{gym}".Replace ("{gym}", gym.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -180,6 +226,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type Gym"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return Gym.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -210,6 +265,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type MemberActivityDto"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return MemberActivityDto.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -240,6 +304,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type UriThing"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return UriThing.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -267,23 +340,42 @@ module PureGymApi =
|
||||
foo
|
||||
|> (fun field ->
|
||||
match field with
|
||||
| None -> null :> System.Text.Json.Nodes.JsonNode
|
||||
| None -> None
|
||||
| Some field ->
|
||||
((fun field ->
|
||||
let ret = System.Text.Json.Nodes.JsonObject ()
|
||||
(field
|
||||
|> (fun field ->
|
||||
let ret = System.Text.Json.Nodes.JsonObject ()
|
||||
|
||||
for (KeyValue (key, value)) in field do
|
||||
ret.Add (
|
||||
key.ToString (),
|
||||
System.Text.Json.Nodes.JsonValue.Create<string> value
|
||||
)
|
||||
for (KeyValue (key, value)) in field do
|
||||
let key = key.ToString ()
|
||||
|
||||
ret
|
||||
)
|
||||
field)
|
||||
ret.Add (
|
||||
key,
|
||||
(fun field ->
|
||||
let field =
|
||||
System.Text.Json.Nodes.JsonValue.Create<string> field
|
||||
|
||||
(match field with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected type string to be non-null, but received a null value when serialising"
|
||||
)
|
||||
| field -> field)
|
||||
)
|
||||
value
|
||||
)
|
||||
|
||||
ret
|
||||
))
|
||||
:> System.Text.Json.Nodes.JsonNode
|
||||
|> Some
|
||||
)
|
||||
|> (fun node ->
|
||||
match node with
|
||||
| None -> "null"
|
||||
| Some node -> node.ToJsonString ()
|
||||
)
|
||||
|> (fun node -> if isNull node then "null" else node.ToJsonString ())
|
||||
)
|
||||
|
||||
do httpMessage.Content <- queryParams
|
||||
@@ -295,15 +387,25 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode = jsonNode |> Option.ofObj
|
||||
|
||||
return
|
||||
match jsonNode with
|
||||
| null -> None
|
||||
| v ->
|
||||
| None -> None
|
||||
| Some v ->
|
||||
v.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = (kvp.Value).AsValue().GetValue<System.String> ()
|
||||
key, value
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type string to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> Map.ofSeq
|
||||
|> Some
|
||||
@@ -326,9 +428,9 @@ module PureGymApi =
|
||||
else
|
||||
"?")
|
||||
+ "fromDate="
|
||||
+ ((fromDate.ToString "yyyy-MM-dd") |> System.Web.HttpUtility.UrlEncode)
|
||||
+ ((fromDate.ToString "yyyy-MM-dd") |> System.Uri.EscapeDataString)
|
||||
+ "&toDate="
|
||||
+ ((toDate.ToString "yyyy-MM-dd") |> System.Web.HttpUtility.UrlEncode)),
|
||||
+ ((toDate.ToString "yyyy-MM-dd") |> System.Uri.EscapeDataString)),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -347,6 +449,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type Sessions"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return Sessions.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -367,9 +478,9 @@ module PureGymApi =
|
||||
else
|
||||
"?")
|
||||
+ "fromDate="
|
||||
+ ((fromDate.ToString "yyyy-MM-dd") |> System.Web.HttpUtility.UrlEncode)
|
||||
+ ((fromDate.ToString "yyyy-MM-dd") |> System.Uri.EscapeDataString)
|
||||
+ "&toDate="
|
||||
+ ((toDate.ToString "yyyy-MM-dd") |> System.Web.HttpUtility.UrlEncode)),
|
||||
+ ((toDate.ToString "yyyy-MM-dd") |> System.Uri.EscapeDataString)),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -388,6 +499,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type Sessions"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return Sessions.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -547,9 +667,7 @@ module PureGymApi =
|
||||
|
||||
let queryParams =
|
||||
new System.Net.Http.StringContent (
|
||||
user
|
||||
|> PureGym.Member.toJsonNode
|
||||
|> (fun node -> if isNull node then "null" else node.ToJsonString ())
|
||||
user |> PureGym.Member.toJsonNode |> (fun node -> node.ToJsonString ())
|
||||
)
|
||||
|
||||
do httpMessage.Content <- queryParams
|
||||
@@ -581,8 +699,18 @@ module PureGymApi =
|
||||
let queryParams =
|
||||
new System.Net.Http.StringContent (
|
||||
user
|
||||
|> System.Text.Json.Nodes.JsonValue.Create<Uri>
|
||||
|> (fun node -> if isNull node then "null" else node.ToJsonString ())
|
||||
|> (fun field ->
|
||||
let field = System.Text.Json.Nodes.JsonValue.Create<Uri> field
|
||||
|
||||
(match field with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected type URI to be non-null, but received a null value when serialising"
|
||||
)
|
||||
| field -> field)
|
||||
)
|
||||
|> (fun node -> node.ToJsonString ())
|
||||
)
|
||||
|
||||
do httpMessage.Content <- queryParams
|
||||
@@ -614,8 +742,18 @@ module PureGymApi =
|
||||
let queryParams =
|
||||
new System.Net.Http.StringContent (
|
||||
user
|
||||
|> System.Text.Json.Nodes.JsonValue.Create<int>
|
||||
|> (fun node -> if isNull node then "null" else node.ToJsonString ())
|
||||
|> (fun field ->
|
||||
let field = System.Text.Json.Nodes.JsonValue.Create<int> field
|
||||
|
||||
(match field with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected type int32 to be non-null, but received a null value when serialising"
|
||||
)
|
||||
| field -> field)
|
||||
)
|
||||
|> (fun node -> node.ToJsonString ())
|
||||
)
|
||||
|
||||
do httpMessage.Content <- queryParams
|
||||
@@ -663,7 +801,7 @@ module PureGymApi =
|
||||
| v -> v),
|
||||
System.Uri (
|
||||
"endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -879,6 +1017,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type Response<MemberActivityDto>"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return
|
||||
new RestEase.Response<_> (
|
||||
responseString,
|
||||
@@ -915,6 +1062,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type RestEase.Response<MemberActivityDto>"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return
|
||||
new RestEase.Response<_> (
|
||||
responseString,
|
||||
@@ -951,6 +1107,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type Response<MemberActivityDto>"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return
|
||||
new RestEase.Response<_> (
|
||||
responseString,
|
||||
@@ -987,6 +1152,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type RestEase.Response<MemberActivityDto>"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return
|
||||
new RestEase.Response<_> (
|
||||
responseString,
|
||||
@@ -1076,7 +1250,7 @@ module internal ApiWithoutBaseAddress =
|
||||
| v -> v),
|
||||
System.Uri (
|
||||
"endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -1130,7 +1304,7 @@ module ApiWithBasePath =
|
||||
),
|
||||
System.Uri (
|
||||
"endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -1178,7 +1352,7 @@ module ApiWithBasePathAndAddress =
|
||||
),
|
||||
System.Uri (
|
||||
"endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -1232,7 +1406,7 @@ module ApiWithAbsoluteBasePath =
|
||||
),
|
||||
System.Uri (
|
||||
"endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -1280,7 +1454,7 @@ module ApiWithAbsoluteBasePathAndAddress =
|
||||
),
|
||||
System.Uri (
|
||||
"endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -1334,7 +1508,7 @@ module ApiWithBasePathAndAbsoluteEndpoint =
|
||||
),
|
||||
System.Uri (
|
||||
"/endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -1382,7 +1556,7 @@ module ApiWithBasePathAndAddressAndAbsoluteEndpoint =
|
||||
),
|
||||
System.Uri (
|
||||
"/endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -1436,7 +1610,7 @@ module ApiWithAbsoluteBasePathAndAbsoluteEndpoint =
|
||||
),
|
||||
System.Uri (
|
||||
"/endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -1484,7 +1658,7 @@ module ApiWithAbsoluteBasePathAndAddressAndAbsoluteEndpoint =
|
||||
),
|
||||
System.Uri (
|
||||
"/endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -1543,7 +1717,7 @@ module ApiWithHeaders =
|
||||
| v -> v),
|
||||
System.Uri (
|
||||
"endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -1606,7 +1780,7 @@ module ApiWithHeaders2 =
|
||||
| v -> v),
|
||||
System.Uri (
|
||||
"endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Web.HttpUtility.UrlEncode),
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -13,139 +13,147 @@ module JwtVaultAuthResponse =
|
||||
/// Parse from a JSON node.
|
||||
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : JwtVaultAuthResponse =
|
||||
let arg_10 =
|
||||
(match node.["num_uses"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("num_uses")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int32> ()
|
||||
match node.["num_uses"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("num_uses")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int32> ()
|
||||
|
||||
let arg_9 =
|
||||
(match node.["orphan"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("orphan")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Boolean> ()
|
||||
match node.["orphan"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("orphan")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Boolean> ()
|
||||
|
||||
let arg_8 =
|
||||
(match node.["entity_id"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("entity_id")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["entity_id"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("entity_id")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
let arg_7 =
|
||||
(match node.["token_type"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("token_type")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["token_type"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("token_type")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
let arg_6 =
|
||||
(match node.["renewable"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("renewable")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Boolean> ()
|
||||
match node.["renewable"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("renewable")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Boolean> ()
|
||||
|
||||
let arg_5 =
|
||||
(match node.["lease_duration"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int32> ()
|
||||
match node.["lease_duration"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int32> ()
|
||||
|
||||
let arg_4 =
|
||||
(match node.["identity_policies"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("identity_policies")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsArray ()
|
||||
|> Seq.map (fun elt -> elt.AsValue().GetValue<System.String> ())
|
||||
|> List.ofSeq
|
||||
match node.["identity_policies"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("identity_policies")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsArray ()
|
||||
|> Seq.map (fun elt ->
|
||||
(match elt with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected element of array (element type string) to be non-null, but found a null element"
|
||||
)
|
||||
| elt -> elt.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> List.ofSeq
|
||||
|
||||
let arg_3 =
|
||||
(match node.["token_policies"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("token_policies")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsArray ()
|
||||
|> Seq.map (fun elt -> elt.AsValue().GetValue<System.String> ())
|
||||
|> List.ofSeq
|
||||
match node.["token_policies"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("token_policies")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsArray ()
|
||||
|> Seq.map (fun elt ->
|
||||
(match elt with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected element of array (element type string) to be non-null, but found a null element"
|
||||
)
|
||||
| elt -> elt.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> List.ofSeq
|
||||
|
||||
let arg_2 =
|
||||
(match node.["policies"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("policies")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsArray ()
|
||||
|> Seq.map (fun elt -> elt.AsValue().GetValue<System.String> ())
|
||||
|> List.ofSeq
|
||||
match node.["policies"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("policies")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsArray ()
|
||||
|> Seq.map (fun elt ->
|
||||
(match elt with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected element of array (element type string) to be non-null, but found a null element"
|
||||
)
|
||||
| elt -> elt.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> List.ofSeq
|
||||
|
||||
let arg_1 =
|
||||
(match node.["accessor"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("accessor")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["accessor"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("accessor")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
let arg_0 =
|
||||
(match node.["client_token"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("client_token")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["client_token"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("client_token")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
{
|
||||
ClientToken = arg_0
|
||||
@@ -168,64 +176,54 @@ module JwtVaultResponse =
|
||||
/// Parse from a JSON node.
|
||||
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : JwtVaultResponse =
|
||||
let arg_4 =
|
||||
JwtVaultAuthResponse.jsonParse (
|
||||
match node.["auth"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("auth")
|
||||
)
|
||||
match node.["auth"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("auth")
|
||||
)
|
||||
| v -> v
|
||||
)
|
||||
)
|
||||
| Some node -> JwtVaultAuthResponse.jsonParse node
|
||||
|
||||
let arg_3 =
|
||||
(match node.["lease_duration"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int32> ()
|
||||
match node.["lease_duration"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int32> ()
|
||||
|
||||
let arg_2 =
|
||||
(match node.["renewable"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("renewable")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Boolean> ()
|
||||
match node.["renewable"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("renewable")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Boolean> ()
|
||||
|
||||
let arg_1 =
|
||||
(match node.["lease_id"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_id")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["lease_id"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_id")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
let arg_0 =
|
||||
(match node.["request_id"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("request_id")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["request_id"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("request_id")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
{
|
||||
RequestId = arg_0
|
||||
@@ -242,190 +240,246 @@ module JwtSecretResponse =
|
||||
/// Parse from a JSON node.
|
||||
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : JwtSecretResponse =
|
||||
let arg_11 =
|
||||
(match node.["data8"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data8")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = (kvp.Value).AsValue().GetValue<string> () |> System.Uri
|
||||
key, value
|
||||
)
|
||||
|> Seq.map System.Collections.Generic.KeyValuePair
|
||||
|> System.Collections.Generic.Dictionary
|
||||
match node.["data8"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data8")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type URI to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<string> () |> System.Uri)
|
||||
)
|
||||
|> Seq.map System.Collections.Generic.KeyValuePair
|
||||
|> System.Collections.Generic.Dictionary
|
||||
|
||||
let arg_10 =
|
||||
(match node.["data7"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data7")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = (kvp.Value).AsValue().GetValue<System.Int32> ()
|
||||
key, value
|
||||
)
|
||||
|> Map.ofSeq
|
||||
match node.["data7"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data7")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type int32 to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.Int32> ())
|
||||
)
|
||||
|> Map.ofSeq
|
||||
|
||||
let arg_9 =
|
||||
(match node.["data6"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data6")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key) |> System.Uri
|
||||
let value = (kvp.Value).AsValue().GetValue<System.String> ()
|
||||
key, value
|
||||
)
|
||||
|> dict
|
||||
match node.["data6"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data6")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key) |> System.Uri
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type string to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> dict
|
||||
|
||||
let arg_8 =
|
||||
(match node.["data5"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data5")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key) |> System.Uri
|
||||
let value = (kvp.Value).AsValue().GetValue<System.String> ()
|
||||
key, value
|
||||
)
|
||||
|> readOnlyDict
|
||||
match node.["data5"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data5")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key) |> System.Uri
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type string to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> readOnlyDict
|
||||
|
||||
let arg_7 =
|
||||
(match node.["data4"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data4")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = (kvp.Value).AsValue().GetValue<System.String> ()
|
||||
key, value
|
||||
)
|
||||
|> Map.ofSeq
|
||||
match node.["data4"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data4")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type string to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> Map.ofSeq
|
||||
|
||||
let arg_6 =
|
||||
(match node.["data3"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data3")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = (kvp.Value).AsValue().GetValue<System.String> ()
|
||||
key, value
|
||||
)
|
||||
|> Seq.map System.Collections.Generic.KeyValuePair
|
||||
|> System.Collections.Generic.Dictionary
|
||||
match node.["data3"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data3")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type string to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> Seq.map System.Collections.Generic.KeyValuePair
|
||||
|> System.Collections.Generic.Dictionary
|
||||
|
||||
let arg_5 =
|
||||
(match node.["data2"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data2")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = (kvp.Value).AsValue().GetValue<System.String> ()
|
||||
key, value
|
||||
)
|
||||
|> dict
|
||||
match node.["data2"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data2")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type string to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> dict
|
||||
|
||||
let arg_4 =
|
||||
(match node.["data"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = (kvp.Value).AsValue().GetValue<System.String> ()
|
||||
key, value
|
||||
)
|
||||
|> readOnlyDict
|
||||
match node.["data"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type string to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> readOnlyDict
|
||||
|
||||
let arg_3 =
|
||||
(match node.["lease_duration"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int32> ()
|
||||
match node.["lease_duration"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int32> ()
|
||||
|
||||
let arg_2 =
|
||||
(match node.["renewable"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("renewable")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Boolean> ()
|
||||
match node.["renewable"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("renewable")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Boolean> ()
|
||||
|
||||
let arg_1 =
|
||||
(match node.["lease_id"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_id")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["lease_id"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_id")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
let arg_0 =
|
||||
(match node.["request_id"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("request_id")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["request_id"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("request_id")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
{
|
||||
RequestId = arg_0
|
||||
@@ -476,11 +530,8 @@ module VaultClient =
|
||||
| v -> v),
|
||||
System.Uri (
|
||||
"v1/{mountPoint}/{path}"
|
||||
.Replace("{path}", path.ToString () |> System.Web.HttpUtility.UrlEncode)
|
||||
.Replace (
|
||||
"{mountPoint}",
|
||||
mountPoint.ToString () |> System.Web.HttpUtility.UrlEncode
|
||||
),
|
||||
.Replace("{path}", path.ToString () |> System.Uri.EscapeDataString)
|
||||
.Replace ("{mountPoint}", mountPoint.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -499,6 +550,15 @@ module VaultClient =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type JwtSecretResponse"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return JwtSecretResponse.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -535,6 +595,15 @@ module VaultClient =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type JwtVaultResponse"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return JwtVaultResponse.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -573,11 +642,8 @@ module VaultClientNonExtensionMethod =
|
||||
| v -> v),
|
||||
System.Uri (
|
||||
"v1/{mountPoint}/{path}"
|
||||
.Replace("{path}", path.ToString () |> System.Web.HttpUtility.UrlEncode)
|
||||
.Replace (
|
||||
"{mountPoint}",
|
||||
mountPoint.ToString () |> System.Web.HttpUtility.UrlEncode
|
||||
),
|
||||
.Replace("{path}", path.ToString () |> System.Uri.EscapeDataString)
|
||||
.Replace ("{mountPoint}", mountPoint.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -596,6 +662,15 @@ module VaultClientNonExtensionMethod =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type JwtSecretResponse"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return JwtSecretResponse.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -632,6 +707,15 @@ module VaultClientNonExtensionMethod =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type JwtVaultResponse"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return JwtVaultResponse.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -673,11 +757,8 @@ module VaultClientExtensionMethodHttpClientExtension =
|
||||
| v -> v),
|
||||
System.Uri (
|
||||
"v1/{mountPoint}/{path}"
|
||||
.Replace("{path}", path.ToString () |> System.Web.HttpUtility.UrlEncode)
|
||||
.Replace (
|
||||
"{mountPoint}",
|
||||
mountPoint.ToString () |> System.Web.HttpUtility.UrlEncode
|
||||
),
|
||||
.Replace("{path}", path.ToString () |> System.Uri.EscapeDataString)
|
||||
.Replace ("{mountPoint}", mountPoint.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -696,6 +777,15 @@ module VaultClientExtensionMethodHttpClientExtension =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type JwtSecretResponse"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return JwtSecretResponse.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -732,6 +822,15 @@ module VaultClientExtensionMethodHttpClientExtension =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type JwtVaultResponse"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return JwtVaultResponse.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
|
@@ -31,7 +31,7 @@ module MyListCata =
|
||||
[<RequireQualifiedAccess>]
|
||||
type private Instruction<'a> =
|
||||
| Process__MyList of MyList<'a>
|
||||
| MyList_Cons of 'a
|
||||
| MyList_Cons of head : 'a
|
||||
|
||||
let private loop (cata : MyListCata<'a, 'MyList>) (instructions : ResizeArray<Instruction<'a>>) =
|
||||
let myListStack = ResizeArray<'MyList> ()
|
||||
|
@@ -48,3 +48,10 @@ type TypeWithInterface =
|
||||
inherit IDisposable
|
||||
abstract Mem1 : string option -> string[] Async
|
||||
abstract Mem2 : unit -> string[] Async
|
||||
|
||||
[<GenerateMock>]
|
||||
type TypeWithProperties =
|
||||
inherit IDisposable
|
||||
abstract Mem1 : string option -> string[] Async
|
||||
abstract Prop1 : int
|
||||
abstract Prop2 : unit Async
|
||||
|
41
ConsumePlugin/MockExampleNoAttributes.fs
Normal file
41
ConsumePlugin/MockExampleNoAttributes.fs
Normal file
@@ -0,0 +1,41 @@
|
||||
namespace SomeNamespace
|
||||
|
||||
open System
|
||||
|
||||
type IPublicTypeNoAttr =
|
||||
abstract Mem1 : string * int -> string list
|
||||
abstract Mem2 : string -> int
|
||||
abstract Mem3 : x : int * ?ct : System.Threading.CancellationToken -> string
|
||||
|
||||
type IPublicTypeInternalFalseNoAttr =
|
||||
abstract Mem1 : string * int -> string list
|
||||
abstract Mem2 : string -> int
|
||||
abstract Mem3 : x : int * ?ct : System.Threading.CancellationToken -> string
|
||||
|
||||
type internal InternalTypeNoAttr =
|
||||
abstract Mem1 : string * int -> unit
|
||||
abstract Mem2 : string -> int
|
||||
|
||||
type private PrivateTypeNoAttr =
|
||||
abstract Mem1 : string * int -> unit
|
||||
abstract Mem2 : string -> int
|
||||
|
||||
type private PrivateTypeInternalFalseNoAttr =
|
||||
abstract Mem1 : string * int -> unit
|
||||
abstract Mem2 : string -> int
|
||||
|
||||
type VeryPublicTypeNoAttr<'a, 'b> =
|
||||
abstract Mem1 : 'a -> 'b
|
||||
|
||||
type CurriedNoAttr<'a> =
|
||||
abstract Mem1 : int -> 'a -> string
|
||||
abstract Mem2 : int * string -> 'a -> string
|
||||
abstract Mem3 : (int * string) -> 'a -> string
|
||||
abstract Mem4 : (int * string) -> ('a * int) -> string
|
||||
abstract Mem5 : x : int * string -> ('a * int) -> string
|
||||
abstract Mem6 : int * string -> y : 'a * int -> string
|
||||
|
||||
type TypeWithInterfaceNoAttr =
|
||||
inherit IDisposable
|
||||
abstract Mem1 : string option -> string[] Async
|
||||
abstract Mem2 : unit -> string[] Async
|
@@ -10,7 +10,7 @@
|
||||
<WarnOn>FS3388,FS3559</WarnOn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Nerdbank.GitVersioning" Version="3.6.143" PrivateAssets="all"/>
|
||||
<PackageReference Include="Nerdbank.GitVersioning" Version="3.8.38-alpha" PrivateAssets="all"/>
|
||||
<SourceLinkGitHubHost Include="github.com" ContentUrl="https://raw.githubusercontent.com"/>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition="'$(GITHUB_ACTION)' != ''">
|
||||
|
30
README.md
30
README.md
@@ -604,6 +604,36 @@ For example, this specifies that Myriad is to use the contents of `Client.fs` to
|
||||
</ItemGroup>
|
||||
```
|
||||
|
||||
## Alternative use without the attributes
|
||||
|
||||
You can avoid taking a reference on the `WoofWare.Myriad.Plugins.Attributes` assembly, instead putting all the configuration into the project file.
|
||||
This is implemented for everything except the SwaggerClientGenerator.
|
||||
|
||||
```xml
|
||||
<Project>
|
||||
<ItemGroup>
|
||||
<Compile Include="Client.fs" />
|
||||
<Compile Include="GeneratedClient.fs">
|
||||
<MyriadFile>Client.fs</MyriadFile>
|
||||
<MyriadParams>
|
||||
<MyTypeName1>GenerateMock(false)!JsonParse</MyTypeName1>
|
||||
<SomeOtherTypeName>GenerateMock</SomeOtherTypeName>
|
||||
</MyriadParams>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="WoofWare.Myriad.Plugins" Version="$(WoofWareMyriadPluginVersion)" PrivateAssets="all" />
|
||||
<PackageReference Include="Myriad.Sdk" Version="0.8.3" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
```
|
||||
|
||||
That is, you specify a `!`-delimited list of the attributes you *would* apply to the type.
|
||||
Supply "arguments" to the attribute name in the project file as you would to the attribute itself.
|
||||
|
||||
(Yes, this is indeed incredibly cumbersome, and you're not interested in the reasons it's all so mad!
|
||||
I'm hopefully going to get round to writing a more powerful source generation system which won't have these limitations.)
|
||||
|
||||
### Myriad Gotchas
|
||||
|
||||
* MsBuild doesn't always realise that it needs to invoke Myriad during rebuild.
|
||||
|
@@ -26,6 +26,11 @@ type ArgParserAttribute (isExtensionMethod : bool) =
|
||||
/// an argument which looks like a flag but which we don't recognise.)
|
||||
/// We will still interpret `--help` as requesting help, unless it comes after
|
||||
/// a standalone `--` separator.
|
||||
///
|
||||
/// If the type of the PositionalArgs field is `Choice<'a, 'a>`, then we will
|
||||
/// tell you whether each arg came before or after a standalone `--` separator.
|
||||
/// For example, `MyApp foo bar -- baz` with PositionalArgs of `Choice<string, string>`
|
||||
/// would yield `Choice1Of2 foo, Choice1Of2 bar, Choice2Of2 baz`.
|
||||
type PositionalArgsAttribute (includeFlagLike : bool) =
|
||||
inherit Attribute ()
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
@@ -17,10 +17,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ApiSurface" Version="4.1.5" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1"/>
|
||||
<PackageReference Include="NUnit" Version="4.2.2"/>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0"/>
|
||||
<PackageReference Include="ApiSurface" Version="4.1.20" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0"/>
|
||||
<PackageReference Include="NUnit" Version="4.3.2"/>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -68,7 +68,7 @@ module TestArgParser =
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment envCalls |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let args = [ "--foo=3" ; "--non-existent" ; "--bar=4" ; "--baz=true" ]
|
||||
|
||||
@@ -91,7 +91,7 @@ module TestArgParser =
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment envCalls |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let property (args : (int * bool) list) (afterDoubleDash : int list option) =
|
||||
let flatArgs =
|
||||
@@ -127,7 +127,7 @@ module TestArgParser =
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment envCalls |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let args = [ "--foo=3" ; "--rest" ; "7" ; "--bar=4" ; "--baz=true" ; "--rest=8" ]
|
||||
|
||||
@@ -150,7 +150,7 @@ module TestArgParser =
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment envCalls |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let args = [ "--foo=3" ; "--foo" ; "9" ; "--bar=4" ; "--baz=true" ; "--baz=false" ]
|
||||
|
||||
@@ -171,7 +171,7 @@ Argument '--baz' was supplied multiple times: True and false"""
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment envCalls |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let args = [ "--" ; "--foo=3" ; "--bar=4" ; "--baz=true" ]
|
||||
|
||||
@@ -191,7 +191,7 @@ Required argument '--baz' received no value"""
|
||||
let ``Help text`` () =
|
||||
let getEnvVar (s : string) =
|
||||
s |> shouldEqual "CONSUMEPLUGIN_THINGS"
|
||||
"hi!"
|
||||
Some "hi!"
|
||||
|
||||
let exc =
|
||||
Assert.Throws<exn> (fun () -> Basic.parse' getEnvVar [ "--help" ] |> ignore<Basic>)
|
||||
@@ -210,7 +210,7 @@ Required argument '--baz' received no value"""
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment envVars |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let exc =
|
||||
Assert.Throws<exn> (fun () -> LoadsOfTypes.parse' getEnvVar [ "--help" ] |> ignore<LoadsOfTypes>)
|
||||
@@ -236,7 +236,7 @@ Required argument '--baz' received no value"""
|
||||
let ``Default values`` () =
|
||||
let getEnvVar (s : string) =
|
||||
s |> shouldEqual "CONSUMEPLUGIN_THINGS"
|
||||
"hi!"
|
||||
Some "hi!"
|
||||
|
||||
let args =
|
||||
[
|
||||
@@ -264,7 +264,7 @@ Required argument '--baz' received no value"""
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment count |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let exc =
|
||||
Assert.Throws<exn> (fun () -> DatesAndTimes.parse' getEnvVar [ "--help" ] |> ignore<DatesAndTimes>)
|
||||
@@ -285,7 +285,7 @@ Required argument '--baz' received no value"""
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment count |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let parsed =
|
||||
DatesAndTimes.parse'
|
||||
@@ -448,7 +448,7 @@ Required argument '--exact' received no value"""
|
||||
let ``Bool env vars can be populated`` (envValue : string, boolValue : bool) =
|
||||
let getEnvVar (s : string) =
|
||||
s |> shouldEqual "CONSUMEPLUGIN_THINGS"
|
||||
envValue
|
||||
Some envValue
|
||||
|
||||
ContainsBoolEnvVar.parse' getEnvVar []
|
||||
|> shouldEqual
|
||||
@@ -470,7 +470,7 @@ Required argument '--exact' received no value"""
|
||||
let ``Flag DUs can be parsed from env var`` (envValue : string, boolValue : bool) =
|
||||
let getEnvVar (s : string) =
|
||||
s |> shouldEqual "CONSUMEPLUGIN_THINGS"
|
||||
envValue
|
||||
Some envValue
|
||||
|
||||
let boolValue = if boolValue then DryRunMode.Dry else DryRunMode.Wet
|
||||
|
||||
|
@@ -33,4 +33,4 @@ module TestPathParam =
|
||||
let api = PureGymApi.make client
|
||||
|
||||
api.GetPathParam("hello/world?(hi)").Result
|
||||
|> shouldEqual "hello%2fworld%3f(hi)"
|
||||
|> shouldEqual "hello%2Fworld%3F%28hi%29"
|
||||
|
@@ -3,7 +3,7 @@ namespace WoofWare.Myriad.Plugins.Test
|
||||
open System
|
||||
open System.Collections.Generic
|
||||
open System.Text.Json.Nodes
|
||||
open FsCheck.Random
|
||||
open FsCheck.FSharp
|
||||
open Microsoft.FSharp.Reflection
|
||||
open NUnit.Framework
|
||||
open FsCheck
|
||||
@@ -15,21 +15,21 @@ module TestJsonSerde =
|
||||
|
||||
let uriGen : Gen<Uri> =
|
||||
gen {
|
||||
let! suffix = Arb.generate<int>
|
||||
let! suffix = ArbMap.generate<int> ArbMap.defaults
|
||||
return Uri $"https://example.com/%i{suffix}"
|
||||
}
|
||||
|
||||
let rec innerGen (count : int) : Gen<InnerTypeWithBoth> =
|
||||
gen {
|
||||
let! guid = Arb.generate<Guid>
|
||||
let! mapKeys = Gen.listOf Arb.generate<NonNull<string>>
|
||||
let! guid = ArbMap.generate<Guid> ArbMap.defaults
|
||||
let! mapKeys = Gen.listOf (ArbMap.generate<NonNull<string>> ArbMap.defaults)
|
||||
let mapKeys = mapKeys |> List.map _.Get |> List.distinct
|
||||
let! mapValues = Gen.listOfLength mapKeys.Length uriGen
|
||||
let map = List.zip mapKeys mapValues |> Map.ofList
|
||||
|
||||
let! concreteDictKeys =
|
||||
if count > 0 then
|
||||
Gen.listOf Arb.generate<NonNull<string>>
|
||||
Gen.listOf (ArbMap.generate<NonNull<string>> ArbMap.defaults)
|
||||
else
|
||||
Gen.constant []
|
||||
|
||||
@@ -50,13 +50,16 @@ module TestJsonSerde =
|
||||
|> List.map KeyValuePair
|
||||
|> Dictionary
|
||||
|
||||
let! readOnlyDictKeys = Gen.listOf Arb.generate<NonNull<string>>
|
||||
let! readOnlyDictKeys = Gen.listOf (ArbMap.generate<NonNull<string>> ArbMap.defaults)
|
||||
let readOnlyDictKeys = readOnlyDictKeys |> List.map _.Get |> List.distinct
|
||||
let! readOnlyDictValues = Gen.listOfLength readOnlyDictKeys.Length (Gen.listOf Arb.generate<char>)
|
||||
|
||||
let! readOnlyDictValues =
|
||||
Gen.listOfLength readOnlyDictKeys.Length (Gen.listOf (ArbMap.generate<char> ArbMap.defaults))
|
||||
|
||||
let readOnlyDict = List.zip readOnlyDictKeys readOnlyDictValues |> readOnlyDict
|
||||
|
||||
let! dictKeys = Gen.listOf uriGen
|
||||
let! dictValues = Gen.listOfLength dictKeys.Length Arb.generate<bool>
|
||||
let! dictValues = Gen.listOfLength dictKeys.Length (ArbMap.generate<bool> ArbMap.defaults)
|
||||
let dict = List.zip dictKeys dictValues |> dict
|
||||
|
||||
return
|
||||
@@ -71,28 +74,38 @@ module TestJsonSerde =
|
||||
|
||||
let outerGen : Gen<JsonRecordTypeWithBoth> =
|
||||
gen {
|
||||
let! a = Arb.generate<int>
|
||||
let! b = Arb.generate<NonNull<string>>
|
||||
let! c = Gen.listOf Arb.generate<int>
|
||||
let! a = ArbMap.generate<int> ArbMap.defaults
|
||||
let! b = ArbMap.generate<NonNull<string>> ArbMap.defaults
|
||||
let! c = Gen.listOf (ArbMap.generate<int> ArbMap.defaults)
|
||||
let! depth = Gen.choose (0, 2)
|
||||
let! d = innerGen depth
|
||||
let! e = Gen.arrayOf Arb.generate<NonNull<string>>
|
||||
let! arr = Gen.arrayOf Arb.generate<int>
|
||||
let! byte = Arb.generate
|
||||
let! sbyte = Arb.generate
|
||||
let! i = Arb.generate
|
||||
let! i32 = Arb.generate
|
||||
let! i64 = Arb.generate
|
||||
let! u = Arb.generate
|
||||
let! u32 = Arb.generate
|
||||
let! u64 = Arb.generate
|
||||
let! f = Arb.generate |> Gen.filter (fun s -> Double.IsFinite (s / 1.0<measure>))
|
||||
let! f32 = Arb.generate |> Gen.filter (fun s -> Single.IsFinite (s / 1.0f<measure>))
|
||||
let! single = Arb.generate |> Gen.filter (fun s -> Single.IsFinite (s / 1.0f<measure>))
|
||||
let! intMeasureOption = Arb.generate
|
||||
let! intMeasureNullable = Arb.generate
|
||||
let! e = Gen.arrayOf (ArbMap.generate<NonNull<string>> ArbMap.defaults)
|
||||
let! arr = Gen.arrayOf (ArbMap.generate<int> ArbMap.defaults)
|
||||
let! byte = ArbMap.generate ArbMap.defaults
|
||||
let! sbyte = ArbMap.generate ArbMap.defaults
|
||||
let! i = ArbMap.generate ArbMap.defaults
|
||||
let! i32 = ArbMap.generate ArbMap.defaults
|
||||
let! i64 = ArbMap.generate ArbMap.defaults
|
||||
let! u = ArbMap.generate ArbMap.defaults
|
||||
let! u32 = ArbMap.generate ArbMap.defaults
|
||||
let! u64 = ArbMap.generate ArbMap.defaults
|
||||
|
||||
let! f =
|
||||
ArbMap.generate ArbMap.defaults
|
||||
|> Gen.filter (fun s -> Double.IsFinite (s / 1.0<measure>))
|
||||
|
||||
let! f32 =
|
||||
ArbMap.generate ArbMap.defaults
|
||||
|> Gen.filter (fun s -> Single.IsFinite (s / 1.0f<measure>))
|
||||
|
||||
let! single =
|
||||
ArbMap.generate ArbMap.defaults
|
||||
|> Gen.filter (fun s -> Single.IsFinite (s / 1.0f<measure>))
|
||||
|
||||
let! intMeasureOption = ArbMap.generate ArbMap.defaults
|
||||
let! intMeasureNullable = ArbMap.generate ArbMap.defaults
|
||||
let! someEnum = Gen.choose (0, 1)
|
||||
let! timestamp = Arb.generate
|
||||
let! timestamp = ArbMap.generate ArbMap.defaults
|
||||
|
||||
return
|
||||
{
|
||||
@@ -270,10 +283,10 @@ module TestJsonSerde =
|
||||
match case with
|
||||
| 0 -> return FirstDu.EmptyCase
|
||||
| 1 ->
|
||||
let! s = Arb.generate<NonNull<string>>
|
||||
let! s = ArbMap.generate<NonNull<string>> ArbMap.defaults
|
||||
return FirstDu.Case1 s.Get
|
||||
| 2 ->
|
||||
let! i = Arb.generate<int>
|
||||
let! i = ArbMap.generate<int> ArbMap.defaults
|
||||
let! record = outerGen
|
||||
return FirstDu.Case2 (record, i)
|
||||
| _ -> return failwith $"unexpected: %i{case}"
|
||||
@@ -293,7 +306,6 @@ module TestJsonSerde =
|
||||
|
||||
[<Test>]
|
||||
let ``DU generator covers all cases`` () =
|
||||
let rand = Random ()
|
||||
let cases = FSharpType.GetUnionCases typeof<FirstDu>
|
||||
let counts = Array.zeroCreate<int> cases.Length
|
||||
|
||||
@@ -301,11 +313,13 @@ module TestJsonSerde =
|
||||
|
||||
let mutable i = 0
|
||||
|
||||
while i < 10_000 && Array.exists (fun i -> i = 0) counts do
|
||||
let du = Gen.eval 10 (StdGen.StdGen (rand.Next (), rand.Next ())) duGen
|
||||
let property (du : FirstDu) =
|
||||
let tag = decompose du
|
||||
counts.[tag] <- counts.[tag] + 1
|
||||
i <- i + 1
|
||||
true
|
||||
|
||||
Check.One (Config.Quick, Prop.forAll (Arb.fromGen duGen) property)
|
||||
|
||||
for i in counts do
|
||||
i |> shouldBeGreaterThan 0
|
||||
|
@@ -34,3 +34,16 @@ module TestMockGenerator =
|
||||
mock.Mem1 3 'a' |> shouldEqual "aaa"
|
||||
mock.Mem2 (3, "hi") 'a' |> shouldEqual "hiahiahi"
|
||||
mock.Mem3 (3, "hi") 'a' |> shouldEqual "hiahiahi"
|
||||
|
||||
[<Test>]
|
||||
let ``Example of use: properties`` () =
|
||||
let mock : TypeWithProperties =
|
||||
{ TypeWithPropertiesMock.Empty with
|
||||
Mem1 = fun i -> async { return Option.toArray i }
|
||||
Prop1 = fun () -> 44
|
||||
}
|
||||
:> _
|
||||
|
||||
mock.Mem1 (Some "hi") |> Async.RunSynchronously |> shouldEqual [| "hi" |]
|
||||
|
||||
mock.Prop1 |> shouldEqual 44
|
||||
|
@@ -0,0 +1,36 @@
|
||||
namespace WoofWare.Myriad.Plugins.Test
|
||||
|
||||
open System
|
||||
open SomeNamespace
|
||||
open NUnit.Framework
|
||||
open FsUnitTyped
|
||||
|
||||
[<TestFixture>]
|
||||
module TestMockGeneratorNoAttr =
|
||||
|
||||
[<Test>]
|
||||
let ``Example of use: IPublicType`` () =
|
||||
let mock : IPublicTypeNoAttr =
|
||||
{ PublicTypeNoAttrMock.Empty with
|
||||
Mem1 = fun (s, count) -> List.replicate count s
|
||||
}
|
||||
:> _
|
||||
|
||||
let _ =
|
||||
Assert.Throws<NotImplementedException> (fun () -> mock.Mem2 "hi" |> ignore<int>)
|
||||
|
||||
mock.Mem1 ("hi", 3) |> shouldEqual [ "hi" ; "hi" ; "hi" ]
|
||||
|
||||
[<Test>]
|
||||
let ``Example of use: curried args`` () =
|
||||
let mock : CurriedNoAttr<_> =
|
||||
{ CurriedNoAttrMock.Empty () with
|
||||
Mem1 = fun i c -> Array.replicate i c |> String
|
||||
Mem2 = fun (i, s) c -> String.concat $"%c{c}" (List.replicate i s)
|
||||
Mem3 = fun (i, s) c -> String.concat $"%c{c}" (List.replicate i s)
|
||||
}
|
||||
:> _
|
||||
|
||||
mock.Mem1 3 'a' |> shouldEqual "aaa"
|
||||
mock.Mem2 (3, "hi") 'a' |> shouldEqual "hiahiahi"
|
||||
mock.Mem3 (3, "hi") 'a' |> shouldEqual "hiahiahi"
|
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
<!--
|
||||
@@ -9,6 +9,7 @@
|
||||
I have not yet seen a single instance where I care about this warning
|
||||
-->
|
||||
<NoWarn>$(NoWarn),NU1903</NoWarn>
|
||||
<TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -26,6 +27,7 @@
|
||||
<Compile Include="TestHttpClient\TestVaultClient.fs" />
|
||||
<Compile Include="TestHttpClient\TestVariableHeader.fs" />
|
||||
<Compile Include="TestMockGenerator\TestMockGenerator.fs" />
|
||||
<Compile Include="TestMockGenerator\TestMockGeneratorNoAttr.fs" />
|
||||
<Compile Include="TestJsonSerialize\TestJsonSerde.fs" />
|
||||
<Compile Include="TestCataGenerator\TestCataGenerator.fs" />
|
||||
<Compile Include="TestCataGenerator\TestDirectory.fs" />
|
||||
@@ -40,12 +42,12 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ApiSurface" Version="4.1.5"/>
|
||||
<PackageReference Include="FsCheck" Version="2.16.6"/>
|
||||
<PackageReference Include="FsUnit" Version="6.0.1"/>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1"/>
|
||||
<PackageReference Include="NUnit" Version="4.2.2"/>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0"/>
|
||||
<PackageReference Include="ApiSurface" Version="4.1.20"/>
|
||||
<PackageReference Include="FsCheck" Version="3.2.0"/>
|
||||
<PackageReference Include="FsUnit" Version="7.0.1"/>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0"/>
|
||||
<PackageReference Include="NUnit" Version="4.3.2"/>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -4,8 +4,8 @@ open System
|
||||
open System.Text
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Text.Range
|
||||
open Fantomas.FCS.Xml
|
||||
open Myriad.Core
|
||||
open TypeEquality
|
||||
open WoofWare.Whippet.Fantomas
|
||||
|
||||
type internal ArgParserOutputSpec =
|
||||
{
|
||||
@@ -673,7 +673,7 @@ module internal ArgParserGenerator =
|
||||
args
|
||||
|> Map.toList
|
||||
|> List.map (fun (ident, expr) -> SynLongIdent.create [ Ident.create ident ], expr)
|
||||
|> AstHelper.instantiateRecord
|
||||
|> SynExpr.createRecord None
|
||||
)
|
||||
|
||||
tree, counter
|
||||
@@ -1224,7 +1224,7 @@ module internal ArgParserGenerator =
|
||||
(SynExpr.CreateConst ()))
|
||||
])
|
||||
SynMatchClause.create
|
||||
(SynPat.listCons (SynPat.createConst (SynConst.CreateString "--")) (SynPat.named "rest"))
|
||||
(SynPat.listCons (SynPat.createConst (SynConst.Create "--")) (SynPat.named "rest"))
|
||||
(SynExpr.callMethodArg
|
||||
"AddRange"
|
||||
(SynExpr.paren (
|
||||
@@ -1396,7 +1396,7 @@ module internal ArgParserGenerator =
|
||||
|
||||
[
|
||||
SynMatchClause.create
|
||||
SynPat.createNull
|
||||
(SynPat.named "None")
|
||||
(SynExpr.sequential
|
||||
[
|
||||
errorMessage
|
||||
@@ -1406,7 +1406,7 @@ module internal ArgParserGenerator =
|
||||
unchecked
|
||||
])
|
||||
|
||||
SynMatchClause.create (SynPat.named "x") parser
|
||||
SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "x" ]) parser
|
||||
]
|
||||
|> SynExpr.createMatch result
|
||||
| ArgumentDefaultSpec.FunctionCall name ->
|
||||
@@ -1643,7 +1643,7 @@ module internal ArgParserGenerator =
|
||||
let modInfo =
|
||||
SynComponentInfo.create modName
|
||||
|> SynComponentInfo.withDocString (
|
||||
PreXmlDoc.Create $" Methods to parse arguments for the type %s{taggedType.Name.idText}"
|
||||
PreXmlDoc.create $"Methods to parse arguments for the type %s{taggedType.Name.idText}"
|
||||
)
|
||||
|> SynComponentInfo.addAttributes modAttrs
|
||||
|
||||
@@ -1666,7 +1666,7 @@ module internal ArgParserGenerator =
|
||||
[
|
||||
{
|
||||
Attrs = []
|
||||
Ident = Ident.create "key"
|
||||
Ident = Some (Ident.create "key")
|
||||
Type = SynType.string
|
||||
}
|
||||
]
|
||||
@@ -1694,7 +1694,7 @@ module internal ArgParserGenerator =
|
||||
[ Ident.create "parse'" ]
|
||||
[
|
||||
SynPat.named "getEnvironmentVariable"
|
||||
|> SynPat.annotateType (SynType.funFromDomain SynType.string SynType.string)
|
||||
|> SynPat.annotateType (SynType.funFromDomain SynType.string (SynType.option SynType.string))
|
||||
argsParam
|
||||
]
|
||||
|> SynBinding.withReturnAnnotation (SynType.createLongIdent [ taggedType.Name ])
|
||||
@@ -1708,7 +1708,12 @@ module internal ArgParserGenerator =
|
||||
|
||||
let parse =
|
||||
SynExpr.createLongIdent' parsePrimeCall
|
||||
|> SynExpr.applyTo (SynExpr.createLongIdent [ "System" ; "Environment" ; "GetEnvironmentVariable" ])
|
||||
|> SynExpr.applyTo (
|
||||
SynExpr.paren (
|
||||
SynExpr.createLongIdent [ "System" ; "Environment" ; "GetEnvironmentVariable" ]
|
||||
|> SynExpr.composeWith (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
|
||||
)
|
||||
)
|
||||
|> SynExpr.applyTo (SynExpr.createIdent "args")
|
||||
|> SynBinding.basic [ Ident.create "parse" ] [ argsParam ]
|
||||
|> SynBinding.withReturnAnnotation (SynType.createLongIdent [ taggedType.Name ])
|
||||
@@ -1740,75 +1745,12 @@ module internal ArgParserGenerator =
|
||||
|
||||
[
|
||||
for openStatement in opens do
|
||||
yield SynModuleDecl.CreateOpen openStatement
|
||||
yield SynModuleDecl.openAny openStatement
|
||||
yield taggedMod
|
||||
]
|
||||
|> SynModuleOrNamespace.createNamespace ns
|
||||
|
||||
let generate (context : GeneratorContext) : Output =
|
||||
let ast, _ =
|
||||
Ast.fromFilename context.InputFilename |> Async.RunSynchronously |> Array.head
|
||||
|
||||
let types =
|
||||
Ast.extractTypeDefn ast
|
||||
|> List.groupBy (fst >> List.map _.idText >> String.concat ".")
|
||||
|> List.map (fun (_, v) -> fst (List.head v), List.collect snd v)
|
||||
|
||||
let opens = AstHelper.extractOpens ast
|
||||
|
||||
let namespaceAndTypes =
|
||||
types
|
||||
|> List.collect (fun (ns, types) ->
|
||||
let typeWithAttr =
|
||||
types
|
||||
|> List.choose (fun ty ->
|
||||
match Ast.getAttribute<ArgParserAttribute> ty with
|
||||
| None -> None
|
||||
| Some attr ->
|
||||
let arg =
|
||||
match SynExpr.stripOptionalParen attr.ArgExpr with
|
||||
| SynExpr.Const (SynConst.Bool value, _) -> value
|
||||
| SynExpr.Const (SynConst.Unit, _) -> ArgParserAttribute.DefaultIsExtensionMethod
|
||||
| arg ->
|
||||
failwith
|
||||
$"Unrecognised argument %+A{arg} to [<%s{nameof ArgParserAttribute}>]. Literals are not supported. Use `true` or `false` (or unit) only."
|
||||
|
||||
let spec =
|
||||
{
|
||||
ExtensionMethods = arg
|
||||
}
|
||||
|
||||
Some (ty, spec)
|
||||
)
|
||||
|
||||
typeWithAttr
|
||||
|> List.map (fun taggedType ->
|
||||
let unions, records, others =
|
||||
(([], [], []), types)
|
||||
||> List.fold (fun
|
||||
(unions, records, others)
|
||||
(SynTypeDefn.SynTypeDefn (sci, repr, smd, _, _, _) as ty) ->
|
||||
match repr with
|
||||
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Union (access, cases, _), _) ->
|
||||
UnionType.OfUnion sci smd access cases :: unions, records, others
|
||||
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Record (access, fields, _), _) ->
|
||||
unions, RecordType.OfRecord sci smd access fields :: records, others
|
||||
| _ -> unions, records, ty :: others
|
||||
)
|
||||
|
||||
if not others.IsEmpty then
|
||||
failwith
|
||||
$"Error: all types recursively defined together with an ArgParserGenerator type must be discriminated unions or records. %+A{others}"
|
||||
|
||||
(ns, taggedType, unions, records)
|
||||
)
|
||||
)
|
||||
|
||||
let modules =
|
||||
namespaceAndTypes
|
||||
|> List.map (fun (ns, taggedType, unions, records) -> createModule opens ns taggedType unions records)
|
||||
|
||||
Output.Ast modules
|
||||
open Myriad.Core
|
||||
|
||||
/// Myriad generator that provides a catamorphism for an algebraic data type.
|
||||
[<MyriadGenerator("arg-parser")>]
|
||||
@@ -1817,4 +1759,66 @@ type ArgParserGenerator () =
|
||||
interface IMyriadGenerator with
|
||||
member _.ValidInputExtensions = [ ".fs" ]
|
||||
|
||||
member _.Generate (context : GeneratorContext) = ArgParserGenerator.generate context
|
||||
member _.Generate (context : GeneratorContext) =
|
||||
let ast, _ =
|
||||
Ast.fromFilename context.InputFilename |> Async.RunSynchronously |> Array.head
|
||||
|
||||
let types = Ast.getTypes ast
|
||||
|
||||
let opens = AstHelper.extractOpens ast
|
||||
|
||||
let namespaceAndTypes =
|
||||
types
|
||||
|> List.collect (fun (ns, types) ->
|
||||
let typeWithAttr =
|
||||
types
|
||||
|> List.choose (fun ty ->
|
||||
match SynTypeDefn.getAttribute typeof<ArgParserAttribute>.Name ty with
|
||||
| None -> None
|
||||
| Some attr ->
|
||||
let arg =
|
||||
match SynExpr.stripOptionalParen attr.ArgExpr with
|
||||
| SynExpr.Const (SynConst.Bool value, _) -> value
|
||||
| SynExpr.Const (SynConst.Unit, _) -> ArgParserAttribute.DefaultIsExtensionMethod
|
||||
| arg ->
|
||||
failwith
|
||||
$"Unrecognised argument %+A{arg} to [<%s{nameof ArgParserAttribute}>]. Literals are not supported. Use `true` or `false` (or unit) only."
|
||||
|
||||
let spec =
|
||||
{
|
||||
ExtensionMethods = arg
|
||||
}
|
||||
|
||||
Some (ty, spec)
|
||||
)
|
||||
|
||||
typeWithAttr
|
||||
|> List.map (fun taggedType ->
|
||||
let unions, records, others =
|
||||
(([], [], []), types)
|
||||
||> List.fold (fun
|
||||
(unions, records, others)
|
||||
(SynTypeDefn.SynTypeDefn (sci, repr, smd, _, _, _) as ty) ->
|
||||
match repr with
|
||||
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Union (access, cases, _), _) ->
|
||||
UnionType.OfUnion sci smd access cases :: unions, records, others
|
||||
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Record (access, fields, _), _) ->
|
||||
unions, RecordType.OfRecord sci smd access fields :: records, others
|
||||
| _ -> unions, records, ty :: others
|
||||
)
|
||||
|
||||
if not others.IsEmpty then
|
||||
failwith
|
||||
$"Error: all types recursively defined together with an ArgParserGenerator type must be discriminated unions or records. %+A{others}"
|
||||
|
||||
(ns, taggedType, unions, records)
|
||||
)
|
||||
)
|
||||
|
||||
let modules =
|
||||
namespaceAndTypes
|
||||
|> List.map (fun (ns, taggedType, unions, records) ->
|
||||
ArgParserGenerator.createModule opens ns taggedType unions records
|
||||
)
|
||||
|
||||
Output.Ast modules
|
||||
|
@@ -2,173 +2,7 @@ namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Text.Range
|
||||
open Fantomas.FCS.Xml
|
||||
|
||||
type internal ParameterInfo =
|
||||
{
|
||||
Attributes : SynAttribute list
|
||||
IsOptional : bool
|
||||
Id : Ident option
|
||||
Type : SynType
|
||||
}
|
||||
|
||||
type internal TupledArg =
|
||||
{
|
||||
HasParen : bool
|
||||
Args : ParameterInfo list
|
||||
}
|
||||
|
||||
type internal MemberInfo =
|
||||
{
|
||||
ReturnType : SynType
|
||||
Accessibility : SynAccess option
|
||||
/// Each element of this list is a list of args in a tuple, or just one arg if not a tuple.
|
||||
Args : TupledArg list
|
||||
Identifier : Ident
|
||||
Attributes : SynAttribute list
|
||||
XmlDoc : PreXmlDoc option
|
||||
IsInline : bool
|
||||
IsMutable : bool
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type internal PropertyAccessors =
|
||||
| Get
|
||||
| Set
|
||||
| GetSet
|
||||
|
||||
type internal PropertyInfo =
|
||||
{
|
||||
Type : SynType
|
||||
Accessibility : SynAccess option
|
||||
Attributes : SynAttribute list
|
||||
XmlDoc : PreXmlDoc option
|
||||
Accessors : PropertyAccessors
|
||||
IsInline : bool
|
||||
Identifier : Ident
|
||||
}
|
||||
|
||||
type internal InterfaceType =
|
||||
{
|
||||
Attributes : SynAttribute list
|
||||
Name : LongIdent
|
||||
Inherits : SynType list
|
||||
Members : MemberInfo list
|
||||
Properties : PropertyInfo list
|
||||
Generics : SynTyparDecls option
|
||||
Accessibility : SynAccess option
|
||||
}
|
||||
|
||||
type internal RecordType =
|
||||
{
|
||||
Name : Ident
|
||||
Fields : SynField list
|
||||
/// Any additional members which are not record fields.
|
||||
Members : SynMemberDefns option
|
||||
XmlDoc : PreXmlDoc option
|
||||
Generics : SynTyparDecls option
|
||||
TypeAccessibility : SynAccess option
|
||||
ImplAccessibility : SynAccess option
|
||||
Attributes : SynAttribute list
|
||||
}
|
||||
|
||||
/// Parse from the AST.
|
||||
static member OfRecord
|
||||
(sci : SynComponentInfo)
|
||||
(smd : SynMemberDefns)
|
||||
(access : SynAccess option)
|
||||
(recordFields : SynField list)
|
||||
: RecordType
|
||||
=
|
||||
match sci with
|
||||
| SynComponentInfo.SynComponentInfo (attrs, typars, _, longId, doc, _, implAccess, _) ->
|
||||
{
|
||||
Name = List.last longId
|
||||
Fields = recordFields
|
||||
Members = if smd.IsEmpty then None else Some smd
|
||||
XmlDoc = if doc.IsEmpty then None else Some doc
|
||||
Generics = typars
|
||||
ImplAccessibility = implAccess
|
||||
TypeAccessibility = access
|
||||
Attributes = attrs |> List.collect (fun l -> l.Attributes)
|
||||
}
|
||||
|
||||
/// Methods for manipulating UnionCase.
|
||||
[<RequireQualifiedAccess>]
|
||||
module UnionCase =
|
||||
/// Construct our structured `UnionCase` from an FCS `SynUnionCase`: extract everything
|
||||
/// we care about from the AST representation.
|
||||
let ofSynUnionCase (case : SynUnionCase) : UnionCase<Ident option> =
|
||||
match case with
|
||||
| SynUnionCase.SynUnionCase (attributes, ident, caseType, xmlDoc, access, _, _) ->
|
||||
|
||||
let ident =
|
||||
match ident with
|
||||
| SynIdent.SynIdent (ident, _) -> ident
|
||||
|
||||
let fields =
|
||||
match caseType with
|
||||
| SynUnionCaseKind.Fields cases -> cases
|
||||
| SynUnionCaseKind.FullType _ -> failwith "unexpected FullType union"
|
||||
|
||||
{
|
||||
Name = ident
|
||||
XmlDoc = if xmlDoc.IsEmpty then None else Some xmlDoc
|
||||
Access = access
|
||||
Attributes = attributes |> List.collect (fun t -> t.Attributes)
|
||||
Fields = fields |> List.map SynField.extract
|
||||
}
|
||||
|
||||
/// Functorial `map`.
|
||||
let mapIdentFields<'a, 'b> (f : 'a -> 'b) (unionCase : UnionCase<'a>) : UnionCase<'b> =
|
||||
{
|
||||
Attributes = unionCase.Attributes
|
||||
Name = unionCase.Name
|
||||
Access = unionCase.Access
|
||||
XmlDoc = unionCase.XmlDoc
|
||||
Fields = unionCase.Fields |> List.map (SynField.mapIdent f)
|
||||
}
|
||||
|
||||
/// Everything you need to know about a discriminated union definition.
|
||||
type internal UnionType =
|
||||
{
|
||||
/// The name of the DU: for example, `type Foo = | Blah` has this being `Foo`.
|
||||
Name : Ident
|
||||
/// Any additional members which are not union cases.
|
||||
Members : SynMemberDefns option
|
||||
/// Any docstring associated with the DU itself (not its cases).
|
||||
XmlDoc : PreXmlDoc option
|
||||
/// Generic type parameters this DU takes: `type Foo<'a> = | ...`.
|
||||
Generics : SynTyparDecls option
|
||||
/// Attributes of the DU (not its cases): `[<Attr>] type Foo = | ...`
|
||||
Attributes : SynAttribute list
|
||||
/// Accessibility modifier of the DU: `type private Foo = ...`
|
||||
TypeAccessibility : SynAccess option
|
||||
/// Accessibility modifier of the DU's implementation: `type Foo = private | ...`
|
||||
ImplAccessibility : SynAccess option
|
||||
/// The actual DU cases themselves.
|
||||
Cases : UnionCase<Ident option> list
|
||||
}
|
||||
|
||||
static member OfUnion
|
||||
(sci : SynComponentInfo)
|
||||
(smd : SynMemberDefns)
|
||||
(access : SynAccess option)
|
||||
(cases : SynUnionCase list)
|
||||
: UnionType
|
||||
=
|
||||
match sci with
|
||||
| SynComponentInfo.SynComponentInfo (attrs, typars, _, longId, doc, _, implAccess, _) ->
|
||||
{
|
||||
Name = List.last longId
|
||||
Members = if smd.IsEmpty then None else Some smd
|
||||
XmlDoc = if doc.IsEmpty then None else Some doc
|
||||
Generics = typars
|
||||
Attributes = attrs |> List.collect (fun l -> l.Attributes)
|
||||
TypeAccessibility = access
|
||||
ImplAccessibility = implAccess
|
||||
Cases = cases |> List.map UnionCase.ofSynUnionCase
|
||||
}
|
||||
open WoofWare.Whippet.Fantomas
|
||||
|
||||
/// Anything that is part of an ADT.
|
||||
/// A record is a product of stuff; this type represents one of those stuffs.
|
||||
@@ -202,13 +36,6 @@ module internal AstHelper =
|
||||
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Enum _, _) -> true
|
||||
| _ -> false
|
||||
|
||||
let instantiateRecord (fields : (SynLongIdent * SynExpr) list) : SynExpr =
|
||||
let fields =
|
||||
fields
|
||||
|> List.map (fun (rfn, synExpr) -> SynExprRecordField ((rfn, true), Some range0, Some synExpr, None))
|
||||
|
||||
SynExpr.Record (None, None, fields, range0)
|
||||
|
||||
let defineRecordType (record : RecordType) : SynTypeDefn =
|
||||
let name =
|
||||
SynComponentInfo.create record.Name
|
||||
|
@@ -3,12 +3,11 @@ namespace WoofWare.Myriad.Plugins
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.SyntaxTrivia
|
||||
open Fantomas.FCS.Xml
|
||||
open Myriad.Core
|
||||
open WoofWare.Whippet.Fantomas
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal CataGenerator =
|
||||
open Fantomas.FCS.Text.Range
|
||||
open Myriad.Core.Ast
|
||||
|
||||
/// The user-provided DU contains cases, each of which contains fields.
|
||||
/// We have a hard-coded set of things we know how to deal with as field contents.
|
||||
@@ -175,20 +174,14 @@ module internal CataGenerator =
|
||||
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "Seq" ; "exactlyOne" ])
|
||||
|> SynExpr.createLet
|
||||
[
|
||||
SynBinding.Let (
|
||||
valData = SynValData.SynValData (None, SynValInfo.Empty, None),
|
||||
pattern =
|
||||
SynPat.tupleNoParen (
|
||||
allArtificialTyparNames
|
||||
|> List.map (fun (t : Ident) ->
|
||||
SynPat.namedI (Ident.create (t.idText + "Stack") |> Ident.lowerFirstLetter)
|
||||
)
|
||||
),
|
||||
expr =
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.applyFunction (SynExpr.createIdent "loop") (SynExpr.createIdent "cata"))
|
||||
(SynExpr.createIdent "instructions")
|
||||
)
|
||||
SynBinding.basicTuple
|
||||
(allArtificialTyparNames
|
||||
|> List.map (fun (t : Ident) ->
|
||||
SynPat.namedI (Ident.create (t.idText + "Stack") |> Ident.lowerFirstLetter)
|
||||
))
|
||||
(SynExpr.applyFunction
|
||||
(SynExpr.applyFunction (SynExpr.createIdent "loop") (SynExpr.createIdent "cata"))
|
||||
(SynExpr.createIdent "instructions"))
|
||||
]
|
||||
]
|
||||
|> SynExpr.sequential
|
||||
@@ -463,18 +456,39 @@ module internal CataGenerator =
|
||||
{
|
||||
SynFieldData.Type = field.Type
|
||||
Attrs = []
|
||||
Ident = None
|
||||
Ident = field.Name
|
||||
}
|
||||
|> SynField.make
|
||||
)
|
||||
|
||||
SynUnionCase.Create (unionCase.Name, fields)
|
||||
{
|
||||
Name = unionCase.Name
|
||||
XmlDoc = None
|
||||
Access = None
|
||||
Attributes = []
|
||||
Fields = fields
|
||||
}
|
||||
|> SynUnionCase.create
|
||||
)
|
||||
|
||||
let casesFromCases =
|
||||
recursiveCases analysis
|
||||
|> List.map (fun case ->
|
||||
SynUnionCase.Create (case.Name, case.Fields |> List.map (fun field -> SynField.Create field.Type))
|
||||
{
|
||||
UnionCase.Name = case.Name
|
||||
XmlDoc = None
|
||||
Access = None
|
||||
Attributes = []
|
||||
Fields =
|
||||
case.Fields
|
||||
|> List.map (fun field ->
|
||||
{
|
||||
SynFieldData.Type = field.Type
|
||||
Attrs = []
|
||||
Ident = field.Name
|
||||
}
|
||||
)
|
||||
}
|
||||
|> SynUnionCase.create
|
||||
)
|
||||
|
||||
let cases = casesFromProcess @ casesFromCases
|
||||
@@ -539,8 +553,8 @@ module internal CataGenerator =
|
||||
|> List.map (fun case ->
|
||||
let arity =
|
||||
SynValInfo.SynValInfo (
|
||||
case.Fields |> List.map (fun field -> [ SynArgInfo.Empty ]),
|
||||
SynArgInfo.Empty
|
||||
case.Fields |> List.map (fun field -> [ SynArgInfo.empty ]),
|
||||
SynArgInfo.empty
|
||||
)
|
||||
|
||||
(SynType.var generics.[analysis.GenericName.idText], List.rev case.FlattenedFields)
|
||||
@@ -852,9 +866,7 @@ module internal CataGenerator =
|
||||
else
|
||||
[]
|
||||
|
||||
SynMatchClause.create
|
||||
(SynPat.CreateLongIdent (SynLongIdent.create unionCase.Match, matchLhs))
|
||||
matchBody
|
||||
SynMatchClause.create (SynPat.identWithArgs unionCase.Match (SynArgPats.create matchLhs)) matchBody
|
||||
)
|
||||
|
||||
SynExpr.createMatch (SynExpr.createIdent "x") matchCases
|
||||
@@ -1059,7 +1071,7 @@ module internal CataGenerator =
|
||||
(SynExpr.CreateConst 0)
|
||||
(SynExpr.createLongIdent [ "instructions" ; "Count" ]))
|
||||
body
|
||||
SynExpr.CreateTuple (
|
||||
SynExpr.tupleNoParen (
|
||||
analysis
|
||||
|> List.map (fun unionAnalysis -> [ unionAnalysis.StackName ] |> SynExpr.createLongIdent')
|
||||
)
|
||||
@@ -1103,7 +1115,7 @@ module internal CataGenerator =
|
||||
let modInfo =
|
||||
SynComponentInfo.create moduleName
|
||||
|> SynComponentInfo.withDocString (
|
||||
PreXmlDoc.Create $" Methods to perform a catamorphism over the type %s{parentName}"
|
||||
PreXmlDoc.create $"Methods to perform a catamorphism over the type %s{parentName}"
|
||||
)
|
||||
|> SynComponentInfo.addAttributes [ SynAttribute.requireQualifiedAccess ]
|
||||
|
||||
@@ -1150,7 +1162,7 @@ module internal CataGenerator =
|
||||
|
||||
[
|
||||
for openStatement in opens do
|
||||
yield SynModuleDecl.CreateOpen openStatement
|
||||
yield SynModuleDecl.openAny openStatement
|
||||
yield! cataStructures
|
||||
yield cataRecord
|
||||
yield
|
||||
@@ -1162,53 +1174,30 @@ module internal CataGenerator =
|
||||
]
|
||||
|> SynModuleOrNamespace.createNamespace ns
|
||||
|
||||
let generate (context : GeneratorContext) : Output =
|
||||
let ast, _ =
|
||||
Ast.fromFilename context.InputFilename |> Async.RunSynchronously |> Array.head
|
||||
/// This function comes from Myriad, and is therefore derived from an Apache 2.0-licenced work.
|
||||
/// https://github.com/MoiraeSoftware/myriad/blob/3c9818faabf9d508c10c28d5ecd26e66fafb48a1/src/Myriad.Core/Ast.fs#L160
|
||||
/// A copy of the Apache 2.0 licence is at ApacheLicence.txt.
|
||||
let groupedTypeDefns (ast : ParsedInput) : (LongIdent * SynTypeDefn list) list =
|
||||
let rec extractTypes (moduleDecls : SynModuleDecl list) (ns : LongIdent) =
|
||||
[
|
||||
for moduleDecl in moduleDecls do
|
||||
match moduleDecl with
|
||||
| SynModuleDecl.Types (types, _) -> yield (ns, types)
|
||||
| SynModuleDecl.NestedModule (SynComponentInfo (_, _, _, longId, _, _, _, _), _, decls, _, _, _) ->
|
||||
let combined = longId |> List.append ns
|
||||
yield! (extractTypes decls combined)
|
||||
| _ -> ()
|
||||
]
|
||||
|
||||
let types = Ast.extractTypeDefn ast
|
||||
[
|
||||
match ast with
|
||||
| ParsedInput.ImplFile (ParsedImplFileInput (_, _, _, _, _, modules, _, _, _)) ->
|
||||
for SynModuleOrNamespace (namespaceId, _, _, moduleDecls, _, _, _, _, _) in modules do
|
||||
yield! extractTypes moduleDecls namespaceId
|
||||
| _ -> ()
|
||||
]
|
||||
|
||||
let opens = AstHelper.extractOpens ast
|
||||
|
||||
let namespaceAndTypes =
|
||||
types
|
||||
|> List.choose (fun (ns, types) ->
|
||||
let typeWithAttr =
|
||||
types
|
||||
|> List.tryPick (fun ty ->
|
||||
match Ast.getAttribute<CreateCatamorphismAttribute> ty with
|
||||
| None -> None
|
||||
| Some attr -> Some (attr.ArgExpr, ty)
|
||||
)
|
||||
|
||||
match typeWithAttr with
|
||||
| Some taggedType ->
|
||||
let unions, records, others =
|
||||
(([], [], []), types)
|
||||
||> List.fold (fun
|
||||
(unions, records, others)
|
||||
(SynTypeDefn.SynTypeDefn (_, repr, _, _, _, _) as ty) ->
|
||||
match repr with
|
||||
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Union _, _) ->
|
||||
ty :: unions, records, others
|
||||
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Record _, _) ->
|
||||
unions, ty :: records, others
|
||||
| _ -> unions, records, ty :: others
|
||||
)
|
||||
|
||||
if not others.IsEmpty then
|
||||
failwith
|
||||
$"Error: all types recursively defined together with a CreateCatamorphism type must be discriminated unions or records. %+A{others}"
|
||||
|
||||
Some (ns, taggedType, unions, records)
|
||||
| _ -> None
|
||||
)
|
||||
|
||||
let modules =
|
||||
namespaceAndTypes
|
||||
|> List.map (fun (ns, taggedType, unions, records) -> createModule opens ns taggedType unions records)
|
||||
|
||||
Output.Ast modules
|
||||
open Myriad.Core
|
||||
|
||||
/// Myriad generator that provides a catamorphism for an algebraic data type.
|
||||
[<MyriadGenerator("create-catamorphism")>]
|
||||
@@ -1217,4 +1206,52 @@ type CreateCatamorphismGenerator () =
|
||||
interface IMyriadGenerator with
|
||||
member _.ValidInputExtensions = [ ".fs" ]
|
||||
|
||||
member _.Generate (context : GeneratorContext) = CataGenerator.generate context
|
||||
member _.Generate (context : GeneratorContext) =
|
||||
let ast, _ =
|
||||
Ast.fromFilename context.InputFilename |> Async.RunSynchronously |> Array.head
|
||||
|
||||
let types = CataGenerator.groupedTypeDefns ast
|
||||
|
||||
let opens = AstHelper.extractOpens ast
|
||||
|
||||
let namespaceAndTypes =
|
||||
types
|
||||
|> List.choose (fun (ns, types) ->
|
||||
let typeWithAttr =
|
||||
types
|
||||
|> List.tryPick (fun ty ->
|
||||
match SynTypeDefn.getAttribute typeof<CreateCatamorphismAttribute>.Name ty with
|
||||
| None -> None
|
||||
| Some attr -> Some (attr.ArgExpr, ty)
|
||||
)
|
||||
|
||||
match typeWithAttr with
|
||||
| Some taggedType ->
|
||||
let unions, records, others =
|
||||
(([], [], []), types)
|
||||
||> List.fold (fun
|
||||
(unions, records, others)
|
||||
(SynTypeDefn.SynTypeDefn (_, repr, _, _, _, _) as ty) ->
|
||||
match repr with
|
||||
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Union _, _) ->
|
||||
ty :: unions, records, others
|
||||
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Record _, _) ->
|
||||
unions, ty :: records, others
|
||||
| _ -> unions, records, ty :: others
|
||||
)
|
||||
|
||||
if not others.IsEmpty then
|
||||
failwith
|
||||
$"Error: all types recursively defined together with a CreateCatamorphism type must be discriminated unions or records. %+A{others}"
|
||||
|
||||
Some (ns, taggedType, unions, records)
|
||||
| _ -> None
|
||||
)
|
||||
|
||||
let modules =
|
||||
namespaceAndTypes
|
||||
|> List.map (fun (ns, taggedType, unions, records) ->
|
||||
CataGenerator.createModule opens ns taggedType unions records
|
||||
)
|
||||
|
||||
Output.Ast modules
|
||||
|
@@ -1,8 +1,8 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open System.IO
|
||||
open System.Net.Http
|
||||
open Fantomas.FCS.Syntax
|
||||
open WoofWare.Whippet.Fantomas
|
||||
|
||||
type internal HttpClientGeneratorOutputSpec =
|
||||
{
|
||||
@@ -13,17 +13,6 @@ type internal HttpClientGeneratorOutputSpec =
|
||||
module internal HttpClientGenerator =
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
let outputFile = FileInfo "/tmp/output.txt"
|
||||
|
||||
// do
|
||||
// use _ = File.Create outputFile.FullName
|
||||
// ()
|
||||
|
||||
let log (line : string) =
|
||||
// use w = outputFile.AppendText ()
|
||||
// w.WriteLine line
|
||||
()
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type PathSpec =
|
||||
| Verbatim of string
|
||||
@@ -234,7 +223,7 @@ module internal HttpClientGenerator =
|
||||
SynExpr.CreateConst ("{" + substituteId + "}")
|
||||
SynExpr.callMethod "ToString" (SynExpr.createIdent' varName)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.createLongIdent [ "System" ; "Web" ; "HttpUtility" ; "UrlEncode" ]
|
||||
SynExpr.createLongIdent [ "System" ; "Uri" ; "EscapeDataString" ]
|
||||
)
|
||||
])
|
||||
| _ -> template
|
||||
@@ -286,9 +275,7 @@ module internal HttpClientGenerator =
|
||||
SynExpr.createIdent' firstValueId
|
||||
|> SynExpr.toString firstValue.Type
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.createLongIdent [ "System" ; "Web" ; "HttpUtility" ; "UrlEncode" ]
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Uri" ; "EscapeDataString" ])
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.plus (SynExpr.plus urlSeparator (SynExpr.CreateConst (firstKey + "=")))
|
||||
|
||||
@@ -301,9 +288,7 @@ module internal HttpClientGenerator =
|
||||
|
||||
SynExpr.toString paramValue.Type (SynExpr.createIdent' paramValueId)
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.createLongIdent [ "System" ; "Web" ; "HttpUtility" ; "UrlEncode" ]
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Uri" ; "EscapeDataString" ])
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.plus (SynExpr.plus uri (SynExpr.CreateConst ("&" + paramKey + "=")))
|
||||
)
|
||||
@@ -412,30 +397,59 @@ module internal HttpClientGenerator =
|
||||
| String -> SynExpr.createIdent "responseString"
|
||||
| Stream -> SynExpr.createIdent "responseStream"
|
||||
| RestEaseResponseType contents ->
|
||||
let deserialiser =
|
||||
JsonParseGenerator.parseNode
|
||||
match JsonNodeWithNullability.Identify contents with
|
||||
| CannotBeNull ->
|
||||
let deserialiser =
|
||||
JsonParseGenerator.parseNonNullableNode
|
||||
None
|
||||
JsonParseGenerator.JsonParseOption.None
|
||||
contents
|
||||
(SynExpr.createIdent "jsonNode")
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.createThunk
|
||||
|
||||
// new RestEase.Response (content : string, response : HttpResponseMessage, deserialiser : unit -> 'T)
|
||||
SynExpr.createNew
|
||||
(SynType.app' (SynType.createLongIdent' [ "RestEase" ; "Response" ]) [ SynType.Anon range0 ])
|
||||
(SynExpr.tupleNoParen
|
||||
[
|
||||
SynExpr.createIdent "responseString"
|
||||
SynExpr.createIdent "response"
|
||||
deserialiser
|
||||
])
|
||||
| Nullable ->
|
||||
let deserialiser =
|
||||
JsonParseGenerator.parseNullableNode
|
||||
None
|
||||
JsonParseGenerator.JsonParseOption.None
|
||||
contents
|
||||
(SynExpr.createIdent "jsonNode")
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.createThunk
|
||||
|
||||
// new RestEase.Response (content : string, response : HttpResponseMessage, deserialiser : unit -> 'T)
|
||||
SynExpr.createNew
|
||||
(SynType.app' (SynType.createLongIdent' [ "RestEase" ; "Response" ]) [ SynType.Anon range0 ])
|
||||
(SynExpr.tupleNoParen
|
||||
[
|
||||
SynExpr.createIdent "responseString"
|
||||
SynExpr.createIdent "response"
|
||||
deserialiser
|
||||
])
|
||||
| retType ->
|
||||
match JsonNodeWithNullability.Identify retType with
|
||||
| Nullable ->
|
||||
JsonParseGenerator.parseNullableNode
|
||||
None
|
||||
JsonParseGenerator.JsonParseOption.None
|
||||
contents
|
||||
retType
|
||||
(SynExpr.createIdent "jsonNode")
|
||||
| CannotBeNull ->
|
||||
JsonParseGenerator.parseNonNullableNode
|
||||
None
|
||||
JsonParseGenerator.JsonParseOption.None
|
||||
retType
|
||||
(SynExpr.createIdent "jsonNode")
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.createThunk
|
||||
|
||||
// new RestEase.Response (content : string, response : HttpResponseMessage, deserialiser : unit -> 'T)
|
||||
SynExpr.createNew
|
||||
(SynType.app' (SynType.createLongIdent' [ "RestEase" ; "Response" ]) [ SynType.Anon range0 ])
|
||||
(SynExpr.tupleNoParen
|
||||
[
|
||||
SynExpr.createIdent "responseString"
|
||||
SynExpr.createIdent "response"
|
||||
deserialiser
|
||||
])
|
||||
| retType ->
|
||||
JsonParseGenerator.parseNode
|
||||
None
|
||||
JsonParseGenerator.JsonParseOption.None
|
||||
retType
|
||||
(SynExpr.createIdent "jsonNode")
|
||||
|
||||
let contentTypeHeader, memberHeaders =
|
||||
info.Headers
|
||||
@@ -508,23 +522,45 @@ module internal HttpClientGenerator =
|
||||
)
|
||||
]
|
||||
| BodyParamMethods.Serialise ty ->
|
||||
let isNullable =
|
||||
match JsonNodeWithNullability.Identify ty with
|
||||
| CannotBeNull -> false
|
||||
| Nullable -> true
|
||||
|
||||
[
|
||||
Let (
|
||||
"queryParams",
|
||||
createStringContent (
|
||||
SynExpr.createIdent' bodyParamName
|
||||
|> SynExpr.pipeThroughFunction (fst (JsonSerializeGenerator.serializeNode ty))
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
fst (
|
||||
(if isNullable then
|
||||
JsonSerializeGenerator.serializeNodeNullable
|
||||
else
|
||||
JsonSerializeGenerator.serializeNodeNonNullable)
|
||||
ty
|
||||
)
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.createLambda
|
||||
"node"
|
||||
(SynExpr.ifThenElse
|
||||
(SynExpr.applyFunction
|
||||
(SynExpr.createIdent "isNull")
|
||||
(SynExpr.createIdent "node"))
|
||||
(SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "node" ; "ToJsonString" ])
|
||||
(SynExpr.CreateConst ()))
|
||||
(SynExpr.CreateConst "null"))
|
||||
(if isNullable then
|
||||
SynExpr.createMatch
|
||||
(SynExpr.createIdent "node")
|
||||
[
|
||||
SynMatchClause.create
|
||||
(SynPat.named "None")
|
||||
(SynExpr.CreateConst "null")
|
||||
SynMatchClause.create
|
||||
(SynPat.nameWithArgs "Some" [ SynPat.named "node" ])
|
||||
(SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "node" ; "ToJsonString" ])
|
||||
(SynExpr.CreateConst ()))
|
||||
]
|
||||
else
|
||||
(SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "node" ; "ToJsonString" ])
|
||||
(SynExpr.CreateConst ())))
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -571,6 +607,24 @@ module internal HttpClientGenerator =
|
||||
)
|
||||
)
|
||||
|
||||
let jsonNodeWithoutNull =
|
||||
match JsonNodeWithNullability.Identify info.TaskReturnType with
|
||||
| Nullable ->
|
||||
Let (
|
||||
"jsonNode",
|
||||
SynExpr.createIdent "jsonNode"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
|
||||
)
|
||||
| CannotBeNull ->
|
||||
Let (
|
||||
"jsonNode",
|
||||
JsonSerializeGenerator.assertNotNull
|
||||
(Ident.create "jsonNode")
|
||||
(SynExpr.CreateConst
|
||||
$"Response from server was the JSON null object; expected a non-nullable type %s{SynType.toHumanReadableString info.TaskReturnType}")
|
||||
(SynExpr.createIdent "jsonNode")
|
||||
)
|
||||
|
||||
let setVariableHeaders =
|
||||
variableHeaders
|
||||
|> List.map (fun (headerName, callToGetValue) ->
|
||||
@@ -645,14 +699,16 @@ module internal HttpClientGenerator =
|
||||
yield responseString
|
||||
yield responseStream
|
||||
yield jsonNode
|
||||
yield jsonNodeWithoutNull
|
||||
| String -> yield responseString
|
||||
| Stream -> yield responseStream
|
||||
| Unit ->
|
||||
| UnitType ->
|
||||
// What we're returning doesn't depend on the content, so don't bother!
|
||||
()
|
||||
| _ ->
|
||||
yield responseStream
|
||||
yield jsonNode
|
||||
yield jsonNodeWithoutNull
|
||||
]
|
||||
|> SynExpr.createCompExpr "async" returnExpr
|
||||
|> SynExpr.startAsTask cancellationTokenArg
|
||||
@@ -992,10 +1048,14 @@ type HttpClientGenerator () =
|
||||
member _.ValidInputExtensions = [ ".fs" ]
|
||||
|
||||
member _.Generate (context : GeneratorContext) =
|
||||
let targetedTypes =
|
||||
MyriadParamParser.render context.AdditionalParameters
|
||||
|> Map.map (fun _ v -> v.Split '!' |> Array.toList |> List.map DesiredGenerator.Parse)
|
||||
|
||||
let ast, _ =
|
||||
Ast.fromFilename context.InputFilename |> Async.RunSynchronously |> Array.head
|
||||
|
||||
let types = Ast.extractTypeDefn ast
|
||||
let types = Ast.getTypes ast
|
||||
|
||||
let opens = AstHelper.extractOpens ast
|
||||
|
||||
@@ -1004,13 +1064,33 @@ type HttpClientGenerator () =
|
||||
|> List.choose (fun (ns, types) ->
|
||||
types
|
||||
|> List.choose (fun typeDef ->
|
||||
match Ast.getAttribute<HttpClientAttribute> typeDef with
|
||||
| None -> None
|
||||
match SynTypeDefn.getAttribute typeof<HttpClientAttribute>.Name typeDef with
|
||||
| None ->
|
||||
let name = SynTypeDefn.getName typeDef |> List.map _.idText |> String.concat "."
|
||||
|
||||
match Map.tryFind name targetedTypes with
|
||||
| Some desired ->
|
||||
desired
|
||||
|> List.tryPick (fun generator ->
|
||||
match generator with
|
||||
| DesiredGenerator.HttpClient arg ->
|
||||
let spec =
|
||||
{
|
||||
ExtensionMethods =
|
||||
arg
|
||||
|> Option.defaultValue
|
||||
HttpClientAttribute.DefaultIsExtensionMethod
|
||||
}
|
||||
|
||||
Some (typeDef, spec)
|
||||
| _ -> None
|
||||
)
|
||||
| _ -> None
|
||||
| Some attr ->
|
||||
let arg =
|
||||
match SynExpr.stripOptionalParen attr.ArgExpr with
|
||||
| SynExpr.Const (SynConst.Bool value, _) -> value
|
||||
| SynExpr.Const (SynConst.Unit, _) -> JsonParseAttribute.DefaultIsExtensionMethod
|
||||
| SynExpr.Const (SynConst.Unit, _) -> HttpClientAttribute.DefaultIsExtensionMethod
|
||||
| arg ->
|
||||
failwith
|
||||
$"Unrecognised argument %+A{arg} to [<%s{nameof HttpClientAttribute}>]. Literals are not supported. Use `true` or `false` (or unit) only."
|
||||
|
@@ -3,6 +3,7 @@ namespace WoofWare.Myriad.Plugins
|
||||
open System
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Xml
|
||||
open WoofWare.Whippet.Fantomas
|
||||
|
||||
type internal GenerateMockOutputSpec =
|
||||
{
|
||||
@@ -88,7 +89,7 @@ module internal InterfaceMockGenerator =
|
||||
[]
|
||||
else
|
||||
[ SynPat.unit ])
|
||||
(AstHelper.instantiateRecord constructorFields)
|
||||
(SynExpr.createRecord None constructorFields)
|
||||
|> SynBinding.withXmlDoc (PreXmlDoc.create "An implementation where every method throws.")
|
||||
|> SynBinding.withReturnAnnotation constructorReturnType
|
||||
|> SynMemberDefn.staticMember
|
||||
@@ -158,6 +159,15 @@ module internal InterfaceMockGenerator =
|
||||
|> SynMemberDefn.memberImplementation
|
||||
)
|
||||
|
||||
let properties =
|
||||
interfaceType.Properties
|
||||
|> List.map (fun pi ->
|
||||
SynExpr.createLongIdent' [ Ident.create "this" ; pi.Identifier ]
|
||||
|> SynExpr.applyTo (SynExpr.CreateConst ())
|
||||
|> SynBinding.basic [ Ident.create "this" ; pi.Identifier ] []
|
||||
|> SynMemberDefn.memberImplementation
|
||||
)
|
||||
|
||||
let interfaceName =
|
||||
let baseName = SynType.createLongIdent interfaceType.Name
|
||||
|
||||
@@ -173,7 +183,7 @@ module internal InterfaceMockGenerator =
|
||||
|
||||
SynType.app' baseName generics
|
||||
|
||||
SynMemberDefn.Interface (interfaceName, Some range0, Some members, range0)
|
||||
SynMemberDefn.Interface (interfaceName, Some range0, Some (members @ properties), range0)
|
||||
|
||||
let access =
|
||||
match interfaceType.Accessibility, spec.IsInternal with
|
||||
@@ -247,6 +257,15 @@ module internal InterfaceMockGenerator =
|
||||
|> SynField.make
|
||||
|> SynField.withDocString (mem.XmlDoc |> Option.defaultValue PreXmlDoc.Empty)
|
||||
|
||||
let constructProperty (prop : PropertyInfo) : SynField =
|
||||
{
|
||||
Attrs = []
|
||||
Ident = Some prop.Identifier
|
||||
Type = SynType.toFun [ SynType.unit ] prop.Type
|
||||
}
|
||||
|> SynField.make
|
||||
|> SynField.withDocString (prop.XmlDoc |> Option.defaultValue PreXmlDoc.Empty)
|
||||
|
||||
let createRecord
|
||||
(namespaceId : LongIdent)
|
||||
(opens : SynOpenDeclTarget list)
|
||||
@@ -254,7 +273,12 @@ module internal InterfaceMockGenerator =
|
||||
: SynModuleOrNamespace
|
||||
=
|
||||
let interfaceType = AstHelper.parseInterface interfaceType
|
||||
let fields = interfaceType.Members |> List.map constructMember
|
||||
|
||||
let fields =
|
||||
interfaceType.Members
|
||||
|> List.map constructMember
|
||||
|> List.append (interfaceType.Properties |> List.map constructProperty)
|
||||
|
||||
let docString = PreXmlDoc.create "Mock record type for an interface"
|
||||
|
||||
let name =
|
||||
@@ -283,18 +307,42 @@ type InterfaceMockGenerator () =
|
||||
member _.ValidInputExtensions = [ ".fs" ]
|
||||
|
||||
member _.Generate (context : GeneratorContext) =
|
||||
let targetedTypes =
|
||||
MyriadParamParser.render context.AdditionalParameters
|
||||
|> Map.map (fun _ v -> v.Split '!' |> Array.toList |> List.map DesiredGenerator.Parse)
|
||||
|
||||
let ast, _ =
|
||||
Ast.fromFilename context.InputFilename |> Async.RunSynchronously |> Array.head
|
||||
|
||||
let types = Ast.extractTypeDefn ast
|
||||
let types = Ast.getTypes ast
|
||||
|
||||
let namespaceAndInterfaces =
|
||||
types
|
||||
|> List.choose (fun (ns, types) ->
|
||||
types
|
||||
|> List.choose (fun typeDef ->
|
||||
match Ast.getAttribute<GenerateMockAttribute> typeDef with
|
||||
| None -> None
|
||||
match SynTypeDefn.getAttribute typeof<GenerateMockAttribute>.Name typeDef with
|
||||
| None ->
|
||||
let name = SynTypeDefn.getName typeDef |> List.map _.idText |> String.concat "."
|
||||
|
||||
match Map.tryFind name targetedTypes with
|
||||
| Some desired ->
|
||||
desired
|
||||
|> List.tryPick (fun generator ->
|
||||
match generator with
|
||||
| DesiredGenerator.InterfaceMock arg ->
|
||||
let spec =
|
||||
{
|
||||
IsInternal =
|
||||
arg
|
||||
|> Option.defaultValue GenerateMockAttribute.DefaultIsInternal
|
||||
}
|
||||
|
||||
Some (typeDef, spec)
|
||||
| _ -> None
|
||||
)
|
||||
| _ -> None
|
||||
|
||||
| Some attr ->
|
||||
let arg =
|
||||
match SynExpr.stripOptionalParen attr.ArgExpr with
|
||||
|
@@ -4,6 +4,7 @@ open System
|
||||
open System.Text
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.SyntaxTrivia
|
||||
open WoofWare.Whippet.Fantomas
|
||||
|
||||
type internal JsonParseOutputSpec =
|
||||
{
|
||||
@@ -25,7 +26,7 @@ module internal JsonParseGenerator =
|
||||
}
|
||||
|
||||
/// (match {indexed} with | null -> raise (System.Collections.Generic.KeyNotFoundException ({propertyName} not found)) | v -> v)
|
||||
let assertNotNull (propertyName : SynExpr) (indexed : SynExpr) =
|
||||
let assertPropertyExists (propertyName : SynExpr) (indexed : SynExpr) =
|
||||
let raiseExpr =
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createIdent "sprintf")
|
||||
@@ -39,34 +40,34 @@ module internal JsonParseGenerator =
|
||||
|> SynExpr.applyFunction (SynExpr.createIdent "raise")
|
||||
|
||||
[
|
||||
SynMatchClause.create SynPat.createNull raiseExpr
|
||||
SynMatchClause.create (SynPat.named "v") (SynExpr.createIdent "v")
|
||||
SynMatchClause.create (SynPat.named "None") raiseExpr
|
||||
SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "v" ]) (SynExpr.createIdent "v")
|
||||
]
|
||||
|> SynExpr.createMatch indexed
|
||||
|> SynExpr.paren
|
||||
|
||||
/// {node}.AsValue().GetValue<{typeName}> ()
|
||||
/// If `propertyName` is Some, uses `assertNotNull {node}` instead of `{node}`.
|
||||
/// If `propertyName` is Some, uses `assertPropertyExists {node}` instead of `{node}`.
|
||||
let asValueGetValue (propertyName : SynExpr option) (typeName : string) (node : SynExpr) : SynExpr =
|
||||
match propertyName with
|
||||
| None -> node
|
||||
| Some propertyName -> assertNotNull propertyName node
|
||||
| Some propertyName -> assertPropertyExists propertyName node
|
||||
|> SynExpr.callMethod "AsValue"
|
||||
|> SynExpr.callGenericMethod' "GetValue" typeName
|
||||
|
||||
let asValueGetValueIdent (propertyName : SynExpr option) (typeName : LongIdent) (node : SynExpr) : SynExpr =
|
||||
match propertyName with
|
||||
| None -> node
|
||||
| Some propertyName -> assertNotNull propertyName node
|
||||
| Some propertyName -> assertPropertyExists propertyName node
|
||||
|> SynExpr.callMethod "AsValue"
|
||||
|> SynExpr.callGenericMethod (SynLongIdent.createS "GetValue") [ SynType.createLongIdent typeName ]
|
||||
|
||||
/// {node}.AsObject()
|
||||
/// If `propertyName` is Some, uses `assertNotNull {node}` instead of `{node}`.
|
||||
/// If `propertyName` is Some, uses `assertPropertyExists {node}` instead of `{node}`.
|
||||
let asObject (propertyName : SynExpr option) (node : SynExpr) : SynExpr =
|
||||
match propertyName with
|
||||
| None -> node
|
||||
| Some propertyName -> assertNotNull propertyName node
|
||||
| Some propertyName -> assertPropertyExists propertyName node
|
||||
|> SynExpr.callMethod "AsObject"
|
||||
|
||||
/// {type}.jsonParse {node}
|
||||
@@ -76,11 +77,12 @@ module internal JsonParseGenerator =
|
||||
|
||||
/// collectionType is e.g. "List"; we'll be calling `ofSeq` on it.
|
||||
/// body is the body of a lambda which takes a parameter `elt`.
|
||||
/// {assertNotNull node}.AsArray()
|
||||
/// |> Seq.map (fun elt -> {body})
|
||||
/// {assertPropertyExists node}.AsArray()
|
||||
/// |> Seq.map (fun elt -> {assertNotNull} {body})
|
||||
/// |> {collectionType}.ofSeq
|
||||
let asArrayMapped
|
||||
(propertyName : SynExpr option)
|
||||
(elementType : SynType)
|
||||
(collectionType : string)
|
||||
(node : SynExpr)
|
||||
(body : SynExpr)
|
||||
@@ -88,10 +90,23 @@ module internal JsonParseGenerator =
|
||||
=
|
||||
match propertyName with
|
||||
| None -> node
|
||||
| Some propertyName -> assertNotNull propertyName node
|
||||
| Some propertyName -> assertPropertyExists propertyName node
|
||||
|> SynExpr.callMethod "AsArray"
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction (SynExpr.createLongIdent [ "Seq" ; "map" ]) (SynExpr.createLambda "elt" body)
|
||||
body
|
||||
|> JsonSerializeGenerator.assertNotNull
|
||||
(Ident.create "elt")
|
||||
(match propertyName with
|
||||
| None ->
|
||||
SynExpr.CreateConst
|
||||
$"Expected element of array (element type %s{SynType.toHumanReadableString elementType}) to be non-null, but found a null element"
|
||||
| Some propertyName ->
|
||||
SynExpr.CreateConst
|
||||
$"Expected element of array (element type %s{SynType.toHumanReadableString elementType}) to be non-null, but found a null element, at %%s"
|
||||
|> SynExpr.applyFunction (SynExpr.createIdent "sprintf")
|
||||
|> SynExpr.applyTo propertyName)
|
||||
|> SynExpr.createLambda "elt"
|
||||
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ collectionType ; "ofSeq" ])
|
||||
|
||||
@@ -100,14 +115,41 @@ module internal JsonParseGenerator =
|
||||
|
||||
/// fun kvp -> let key = {key(kvp)} in let value = {value(kvp)} in (key, value))
|
||||
/// The inputs will be fed with appropriate SynExprs to apply them to the `kvp.Key` and `kvp.Value` args.
|
||||
let dictionaryMapper (key : SynExpr -> SynExpr) (value : SynExpr -> SynExpr) : SynExpr =
|
||||
let dictionaryMapper
|
||||
(propertyName : SynExpr option)
|
||||
(valueTypeIsNullable : bool)
|
||||
(key : SynExpr -> SynExpr)
|
||||
(valueType : SynType)
|
||||
(value : SynExpr -> SynExpr)
|
||||
: SynExpr
|
||||
=
|
||||
let keyArg = SynExpr.createLongIdent [ "kvp" ; "Key" ] |> SynExpr.paren
|
||||
|
||||
let valueArg = SynExpr.createLongIdent [ "kvp" ; "Value" ] |> SynExpr.paren
|
||||
let valueArg = SynExpr.createLongIdent [ "kvp" ; "Value" ]
|
||||
|
||||
let value =
|
||||
if valueTypeIsNullable then
|
||||
(value (SynExpr.createIdent "value"))
|
||||
else
|
||||
let errorMessage =
|
||||
match propertyName with
|
||||
| None ->
|
||||
SynExpr.CreateConst
|
||||
$"Expected dictionary value of type %s{SynType.toHumanReadableString valueType} to be non-null, but it was null"
|
||||
| Some propertyName ->
|
||||
SynExpr.CreateConst
|
||||
$"Expected dictionary value of type %s{SynType.toHumanReadableString valueType} to be non-null, but it was null, at key %%s"
|
||||
|> SynExpr.applyFunction (SynExpr.createIdent "sprintf")
|
||||
|> SynExpr.applyTo propertyName
|
||||
|
||||
JsonSerializeGenerator.assertNotNull
|
||||
(Ident.create "value")
|
||||
errorMessage
|
||||
(value (SynExpr.createIdent "value"))
|
||||
|
||||
// No need to paren here, we're on the LHS of a `let`
|
||||
SynExpr.tupleNoParen [ SynExpr.createIdent "key" ; SynExpr.createIdent "value" ]
|
||||
|> SynExpr.createLet [ SynBinding.basic [ Ident.create "value" ] [] (value valueArg) ]
|
||||
SynExpr.tupleNoParen [ SynExpr.createIdent "key" ; value ]
|
||||
|> SynExpr.createLet [ SynBinding.basic [ Ident.create "value" ] [] valueArg ]
|
||||
|> SynExpr.createLet [ SynBinding.basic [ Ident.create "key" ] [] (key keyArg) ]
|
||||
|> SynExpr.createLambda "kvp"
|
||||
|
||||
@@ -164,10 +206,61 @@ module internal JsonParseGenerator =
|
||||
))
|
||||
handler
|
||||
|
||||
let rec parseNullableNode
|
||||
// TODO: unused?!
|
||||
(propertyName : SynExpr option)
|
||||
(options : JsonParseOption)
|
||||
(fieldType : SynType)
|
||||
(node : SynExpr)
|
||||
: SynExpr
|
||||
=
|
||||
match fieldType with
|
||||
| OptionType ty ->
|
||||
match ty with
|
||||
| OptionType _
|
||||
| NullableType _ ->
|
||||
failwith
|
||||
$"Nested nullable types are not supported, because we can't distinguish between None and Some None. %s{SynType.toHumanReadableString ty}"
|
||||
| _ ->
|
||||
|
||||
let someClause =
|
||||
parseNonNullableNode None options ty (SynExpr.createIdent "v")
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "Some")
|
||||
|> SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "v" ])
|
||||
|
||||
[
|
||||
SynMatchClause.create (SynPat.named "None") (SynExpr.createIdent "None")
|
||||
someClause
|
||||
]
|
||||
|> SynExpr.createMatch node
|
||||
| NullableType ty ->
|
||||
match ty with
|
||||
| OptionType _
|
||||
| NullableType _ ->
|
||||
failwith
|
||||
$"Nested nullable types are not supported, because we can't distinguish between None and Some None. %s{SynType.toHumanReadableString ty}"
|
||||
| _ ->
|
||||
|
||||
let someClause =
|
||||
parseNonNullableNode None options ty (SynExpr.createIdent "v")
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Nullable" ])
|
||||
|> SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "v" ])
|
||||
|
||||
[
|
||||
SynMatchClause.create
|
||||
(SynPat.named "None")
|
||||
(SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "Nullable" ]) (SynExpr.CreateConst ()))
|
||||
someClause
|
||||
]
|
||||
|> SynExpr.createMatch node
|
||||
| _ ->
|
||||
failwith
|
||||
$"Encountered type %s{SynType.toHumanReadableString fieldType} which is expected to be nullable, but couldn't identify it"
|
||||
|
||||
/// Given `node.["town"]`, for example, choose how to obtain a JSON value from it.
|
||||
/// The property name is used in error messages at runtime to show where a JSON
|
||||
/// parse error occurred; supply `None` to indicate "don't validate".
|
||||
let rec parseNode
|
||||
and parseNonNullableNode
|
||||
(propertyName : SynExpr option)
|
||||
(options : JsonParseOption)
|
||||
(fieldType : SynType)
|
||||
@@ -176,101 +269,184 @@ module internal JsonParseGenerator =
|
||||
=
|
||||
// TODO: parsing format for DateTime etc
|
||||
match fieldType with
|
||||
| OptionType _
|
||||
| NullableType _ ->
|
||||
failwith
|
||||
$"Unexpectedly parsing nullable type %s{SynType.toHumanReadableString fieldType} as if it were non-nullable."
|
||||
// Struct types
|
||||
| DateOnly ->
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "DateOnly" ; "Parse" ])
|
||||
| Uri ->
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Uri" ])
|
||||
| Guid ->
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Guid" ; "Parse" ])
|
||||
| DateTime ->
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "DateTime" ; "Parse" ])
|
||||
| NumberType typeName -> parseNumberType options propertyName node typeName
|
||||
| Guid ->
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Guid" ; "Parse" ])
|
||||
// Reference types
|
||||
| Uri ->
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Uri" ])
|
||||
| DateTimeOffset ->
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "DateTimeOffset" ; "Parse" ])
|
||||
| NumberType typeName -> parseNumberType options propertyName node typeName
|
||||
| PrimitiveType typeName -> asValueGetValueIdent propertyName typeName node
|
||||
| OptionType ty ->
|
||||
let someClause =
|
||||
parseNode None options ty (SynExpr.createIdent "v")
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "Some")
|
||||
|> SynMatchClause.create (SynPat.named "v")
|
||||
|
||||
[
|
||||
SynMatchClause.create SynPat.createNull (SynExpr.createIdent "None")
|
||||
someClause
|
||||
]
|
||||
|> SynExpr.createMatch node
|
||||
| NullableType ty ->
|
||||
let someClause =
|
||||
parseNode None options ty (SynExpr.createIdent "v")
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Nullable" ])
|
||||
|> SynMatchClause.create (SynPat.named "v")
|
||||
|
||||
[
|
||||
SynMatchClause.create
|
||||
SynPat.createNull
|
||||
(SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "Nullable" ]) (SynExpr.CreateConst ()))
|
||||
someClause
|
||||
]
|
||||
|> SynExpr.createMatch node
|
||||
| ListType ty ->
|
||||
parseNode None options ty (SynExpr.createIdent "elt")
|
||||
|> asArrayMapped propertyName "List" node
|
||||
match JsonNodeWithNullability.Identify ty with
|
||||
| CannotBeNull ->
|
||||
parseNonNullableNode None options ty (SynExpr.createIdent "elt")
|
||||
|> asArrayMapped propertyName ty "List" node
|
||||
| Nullable ->
|
||||
parseNullableNode None options ty (SynExpr.createIdent "elt")
|
||||
|> asArrayMapped propertyName ty "List" node
|
||||
| ArrayType ty ->
|
||||
parseNode None options ty (SynExpr.createIdent "elt")
|
||||
|> asArrayMapped propertyName "Array" node
|
||||
match JsonNodeWithNullability.Identify ty with
|
||||
| CannotBeNull ->
|
||||
parseNonNullableNode None options ty (SynExpr.createIdent "elt")
|
||||
|> asArrayMapped propertyName ty "Array" node
|
||||
| Nullable ->
|
||||
parseNullableNode None options ty (SynExpr.createIdent "elt")
|
||||
|> asArrayMapped propertyName ty "Array" node
|
||||
| IDictionaryType (keyType, valueType) ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper (parseKeyString keyType) (parseNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "dict")
|
||||
match JsonNodeWithNullability.Identify valueType with
|
||||
| CannotBeNull ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
false
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNonNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "dict")
|
||||
| Nullable ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
true
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "dict")
|
||||
| DictionaryType (keyType, valueType) ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper (parseKeyString keyType) (parseNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "KeyValuePair" ])
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "Dictionary" ]
|
||||
)
|
||||
match JsonNodeWithNullability.Identify valueType with
|
||||
| CannotBeNull ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
false
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNonNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "KeyValuePair" ])
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "Dictionary" ]
|
||||
)
|
||||
| Nullable ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
true
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "KeyValuePair" ])
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "Dictionary" ]
|
||||
)
|
||||
| IReadOnlyDictionaryType (keyType, valueType) ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper (parseKeyString keyType) (parseNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "readOnlyDict")
|
||||
match JsonNodeWithNullability.Identify valueType with
|
||||
| CannotBeNull ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
false
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNonNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "readOnlyDict")
|
||||
| Nullable ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
true
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "readOnlyDict")
|
||||
| MapType (keyType, valueType) ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper (parseKeyString keyType) (parseNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Map" ; "ofSeq" ])
|
||||
match JsonNodeWithNullability.Identify valueType with
|
||||
| CannotBeNull ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
false
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNonNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Map" ; "ofSeq" ])
|
||||
| Nullable ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
true
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Map" ; "ofSeq" ])
|
||||
| BigInt ->
|
||||
node
|
||||
|> SynExpr.callMethod "ToJsonString"
|
||||
@@ -280,8 +456,8 @@ module internal JsonParseGenerator =
|
||||
parseNumberType options propertyName node primType
|
||||
|> SynExpr.pipeThroughFunction (Measure.getLanguagePrimitivesMeasure primType)
|
||||
| JsonNode -> node
|
||||
| Unit -> SynExpr.CreateConst ()
|
||||
| _ ->
|
||||
| UnitType -> SynExpr.CreateConst ()
|
||||
| fieldType ->
|
||||
// Let's just hope that we've also got our own type annotation!
|
||||
let typeName =
|
||||
match fieldType with
|
||||
@@ -290,14 +466,45 @@ module internal JsonParseGenerator =
|
||||
|
||||
match propertyName with
|
||||
| None -> node
|
||||
| Some propertyName -> assertNotNull propertyName node
|
||||
| Some propertyName -> assertPropertyExists propertyName node
|
||||
|> typeJsonParse typeName
|
||||
|
||||
/// propertyName is probably a string literal, but it could be a [<Literal>] variable
|
||||
/// The result of this function is the body of a let-binding (not including the LHS of that let-binding).
|
||||
let createParseRhs (options : JsonParseOption) (propertyName : SynExpr) (fieldType : SynType) : SynExpr =
|
||||
let objectToParse = SynExpr.createIdent "node" |> SynExpr.index propertyName
|
||||
parseNode (Some propertyName) options fieldType objectToParse
|
||||
match JsonNodeWithNullability.Identify fieldType with
|
||||
| Nullable ->
|
||||
let objectToParse =
|
||||
SynExpr.createIdent "node"
|
||||
|> SynExpr.index propertyName
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
|
||||
|
||||
parseNullableNode (Some propertyName) options fieldType objectToParse
|
||||
| CannotBeNull ->
|
||||
[
|
||||
SynMatchClause.create
|
||||
(SynPat.named "None")
|
||||
(SynExpr.applyFunction
|
||||
(SynExpr.createIdent "raise")
|
||||
(SynExpr.paren (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent
|
||||
[ "System" ; "Collections" ; "Generic" ; "KeyNotFoundException" ])
|
||||
(SynExpr.applyFunction
|
||||
(SynExpr.createIdent "sprintf")
|
||||
(SynExpr.CreateConst "Required key '%s' not found on JSON object")
|
||||
|> SynExpr.applyTo (SynExpr.paren propertyName)
|
||||
|> SynExpr.paren)
|
||||
)))
|
||||
SynMatchClause.create
|
||||
(SynPat.nameWithArgs "Some" [ SynPat.named "node" ])
|
||||
(parseNonNullableNode None options fieldType (SynExpr.createIdent "node"))
|
||||
]
|
||||
|> SynExpr.createMatch (
|
||||
SynExpr.createIdent "node"
|
||||
|> SynExpr.index propertyName
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
|
||||
)
|
||||
|
||||
let isJsonNumberHandling (literal : LongIdent) : bool =
|
||||
match List.rev literal |> List.map (fun ident -> ident.idText) with
|
||||
@@ -350,10 +557,7 @@ module internal JsonParseGenerator =
|
||||
let getParseOptions (fieldAttrs : SynAttribute list) =
|
||||
(JsonParseOption.None, fieldAttrs)
|
||||
||> List.fold (fun options attr ->
|
||||
if
|
||||
(SynLongIdent.toString attr.TypeName)
|
||||
.EndsWith ("JsonNumberHandling", StringComparison.Ordinal)
|
||||
then
|
||||
if (SynLongIdent.toString attr.TypeName).EndsWith ("JsonNumberHandling", StringComparison.Ordinal) then
|
||||
let qualifiedEnumValue =
|
||||
match SynExpr.stripOptionalParen attr.ArgExpr with
|
||||
| SynExpr.LongIdent (_, SynLongIdent (ident, _, _), _, _) when isJsonNumberHandling ident ->
|
||||
@@ -383,15 +587,13 @@ module internal JsonParseGenerator =
|
||||
let propertyNameAttr =
|
||||
fieldData.Attrs
|
||||
|> List.tryFind (fun attr ->
|
||||
(SynLongIdent.toString attr.TypeName)
|
||||
.EndsWith ("JsonPropertyName", StringComparison.Ordinal)
|
||||
(SynLongIdent.toString attr.TypeName).EndsWith ("JsonPropertyName", StringComparison.Ordinal)
|
||||
)
|
||||
|
||||
let extensionDataAttr =
|
||||
fieldData.Attrs
|
||||
|> List.tryFind (fun attr ->
|
||||
(SynLongIdent.toString attr.TypeName)
|
||||
.EndsWith ("JsonExtensionData", StringComparison.Ordinal)
|
||||
(SynLongIdent.toString attr.TypeName).EndsWith ("JsonExtensionData", StringComparison.Ordinal)
|
||||
)
|
||||
|
||||
let propertyName =
|
||||
@@ -484,7 +686,7 @@ module internal JsonParseGenerator =
|
||||
let finalConstruction =
|
||||
fields
|
||||
|> List.mapi (fun i fieldData -> SynLongIdent.createI fieldData.Ident, SynExpr.createIdent $"arg_%i{i}")
|
||||
|> AstHelper.instantiateRecord
|
||||
|> SynExpr.createRecord None
|
||||
|
||||
(finalConstruction, assignments)
|
||||
||> List.fold (fun final assignment -> SynExpr.createLet [ assignment ] final)
|
||||
@@ -509,7 +711,8 @@ module internal JsonParseGenerator =
|
||||
|> SynExpr.createLet
|
||||
[
|
||||
SynExpr.index (SynExpr.CreateConst "data") (SynExpr.createIdent "node")
|
||||
|> assertNotNull (SynExpr.CreateConst "data")
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
|
||||
|> assertPropertyExists (SynExpr.CreateConst "data")
|
||||
|> SynBinding.basic [ Ident.create "node" ] []
|
||||
]
|
||||
|
||||
@@ -557,7 +760,8 @@ module internal JsonParseGenerator =
|
||||
|
||||
SynExpr.createIdent "node"
|
||||
|> SynExpr.index property
|
||||
|> assertNotNull property
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
|
||||
|> assertPropertyExists property
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.createLambda "v" (SynExpr.callGenericMethod' "GetValue" "string" (SynExpr.createIdent "v"))
|
||||
)
|
||||
@@ -702,17 +906,21 @@ type JsonParseGenerator () =
|
||||
member _.ValidInputExtensions = [ ".fs" ]
|
||||
|
||||
member _.Generate (context : GeneratorContext) =
|
||||
let targetedTypes =
|
||||
MyriadParamParser.render context.AdditionalParameters
|
||||
|> Map.map (fun _ v -> v.Split '!' |> Array.toList |> List.map DesiredGenerator.Parse)
|
||||
|
||||
let ast, _ =
|
||||
Ast.fromFilename context.InputFilename |> Async.RunSynchronously |> Array.head
|
||||
|
||||
let relevantTypes =
|
||||
Ast.extractTypeDefn ast
|
||||
Ast.getTypes ast
|
||||
|> List.map (fun (name, defns) ->
|
||||
defns
|
||||
|> List.choose (fun defn ->
|
||||
if Ast.isRecord defn then Some defn
|
||||
elif Ast.isDu defn then Some defn
|
||||
elif AstHelper.isEnum defn then Some defn
|
||||
if SynTypeDefn.isRecord defn then Some defn
|
||||
elif SynTypeDefn.isDu defn then Some defn
|
||||
elif SynTypeDefn.isEnum defn then Some defn
|
||||
else None
|
||||
)
|
||||
|> fun defns -> name, defns
|
||||
@@ -723,8 +931,29 @@ type JsonParseGenerator () =
|
||||
|> List.choose (fun (ns, types) ->
|
||||
types
|
||||
|> List.choose (fun typeDef ->
|
||||
match Ast.getAttribute<JsonParseAttribute> typeDef with
|
||||
| None -> None
|
||||
match SynTypeDefn.getAttribute typeof<JsonParseAttribute>.Name typeDef with
|
||||
| None ->
|
||||
let name = SynTypeDefn.getName typeDef |> List.map _.idText |> String.concat "."
|
||||
|
||||
match Map.tryFind name targetedTypes with
|
||||
| Some desired ->
|
||||
desired
|
||||
|> List.tryPick (fun generator ->
|
||||
match generator with
|
||||
| DesiredGenerator.JsonParse arg ->
|
||||
let spec =
|
||||
{
|
||||
ExtensionMethods =
|
||||
arg
|
||||
|> Option.defaultValue
|
||||
JsonParseAttribute.DefaultIsExtensionMethod
|
||||
}
|
||||
|
||||
Some (typeDef, spec)
|
||||
| _ -> None
|
||||
)
|
||||
| _ -> None
|
||||
|
||||
| Some attr ->
|
||||
let arg =
|
||||
match SynExpr.stripOptionalParen attr.ArgExpr with
|
||||
|
@@ -3,30 +3,107 @@ namespace WoofWare.Myriad.Plugins
|
||||
open System
|
||||
open System.Text
|
||||
open Fantomas.FCS.Syntax
|
||||
open WoofWare.Whippet.Fantomas
|
||||
|
||||
type internal JsonSerializeOutputSpec =
|
||||
{
|
||||
ExtensionMethods : bool
|
||||
}
|
||||
|
||||
/// https://github.com/Smaug123/WoofWare.Myriad/issues/364
|
||||
/// The insane design of System.Text.Json is finally causing us to
|
||||
/// do vast amounts of coding rather than merely being very annoying.
|
||||
type internal JsonNodeWithNullability =
|
||||
| CannotBeNull
|
||||
| Nullable
|
||||
|
||||
static member Identify (ty : SynType) : JsonNodeWithNullability =
|
||||
match ty with
|
||||
| OptionType _
|
||||
| NullableType _ -> JsonNodeWithNullability.Nullable
|
||||
| _ -> JsonNodeWithNullability.CannotBeNull
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal JsonSerializeGenerator =
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
|
||||
// The absolutely galaxy-brained implementation of JsonValue has `JsonValue.Parse "null"`
|
||||
// identically equal to null. We have to work around this later, but we might as well just
|
||||
// be efficient here and whip up the null directly.
|
||||
let private jsonNull () =
|
||||
SynExpr.createNull ()
|
||||
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|
||||
// identically equal to null, so it's hard to use that type. We use `None` instead to represent
|
||||
// the JSON null value.
|
||||
let private jsonNull () = SynExpr.createIdent "None"
|
||||
|
||||
let assertNotNull (boundIdent : Ident) (message : SynExpr) (body : SynExpr) : SynExpr =
|
||||
let raiseExpr =
|
||||
message
|
||||
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "ArgumentNullException" ])
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.applyFunction (SynExpr.createIdent "raise")
|
||||
|
||||
[
|
||||
SynMatchClause.create SynPat.createNull raiseExpr
|
||||
SynMatchClause.create (SynPat.namedI boundIdent) body
|
||||
]
|
||||
|> SynExpr.createMatch (SynExpr.createIdent' boundIdent)
|
||||
|> SynExpr.paren
|
||||
|
||||
/// The output of this will be an *optional* JsonNode.
|
||||
let rec serializeNodeNullable (fieldType : SynType) : SynExpr * bool =
|
||||
match fieldType with
|
||||
| NullableType ty ->
|
||||
// fun field -> if field.HasValue then {serializeNode ty} field.Value else JsonValue.Create null
|
||||
match JsonNodeWithNullability.Identify ty with
|
||||
| JsonNodeWithNullability.Nullable ->
|
||||
failwith
|
||||
$"We don't support nested nullable types, because we can't tell the difference between None and Some None: %s{SynType.toHumanReadableString ty}"
|
||||
| JsonNodeWithNullability.CannotBeNull ->
|
||||
|
||||
let inner, innerIsJsonNode = serializeNodeNonNullable ty
|
||||
|
||||
SynExpr.applyFunction inner (SynExpr.createLongIdent [ "field" ; "Value" ])
|
||||
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "Some")
|
||||
|> SynExpr.ifThenElse (SynExpr.createLongIdent [ "field" ; "HasValue" ]) (jsonNull ())
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, innerIsJsonNode
|
||||
| OptionType ty ->
|
||||
// fun field -> match field with | None -> None | Some v -> {serializeNode ty} field |> Some
|
||||
match JsonNodeWithNullability.Identify ty with
|
||||
| JsonNodeWithNullability.Nullable ->
|
||||
failwith
|
||||
$"We don't support nested nullable types, because we can't tell the difference between None and Some None: %s{SynType.toHumanReadableString ty}"
|
||||
| JsonNodeWithNullability.CannotBeNull ->
|
||||
|
||||
let noneClause = jsonNull () |> SynMatchClause.create (SynPat.named "None")
|
||||
|
||||
let someClause =
|
||||
let inner, innerIsJsonNode = serializeNodeNonNullable ty
|
||||
let target = SynExpr.pipeThroughFunction inner (SynExpr.createIdent "field")
|
||||
|
||||
if innerIsJsonNode then
|
||||
target
|
||||
else
|
||||
target
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "Some")
|
||||
|> SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "field" ])
|
||||
|
||||
[ noneClause ; someClause ]
|
||||
|> SynExpr.createMatch (SynExpr.createIdent "field")
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, true
|
||||
| _ -> failwith $"Did not recognise type %s{SynType.toHumanReadableString fieldType} as nullable"
|
||||
|
||||
/// Given `input.Ident`, for example, choose how to add it to the ambient `node`.
|
||||
/// The result is a line like `(fun ident -> InnerType.toJsonNode ident)` or `(fun ident -> JsonValue.Create ident)`.
|
||||
/// Returns also a bool which is true if the resulting SynExpr represents something of type JsonNode.
|
||||
let rec serializeNode (fieldType : SynType) : SynExpr * bool =
|
||||
and serializeNodeNonNullable (fieldType : SynType) : SynExpr * bool =
|
||||
// TODO: serialization format for DateTime etc
|
||||
match fieldType with
|
||||
| OptionType _
|
||||
| NullableType _ ->
|
||||
failwith $"Tried to treat the type %s{SynType.toHumanReadableString fieldType} as non-nullable"
|
||||
| DateOnly
|
||||
| DateTime
|
||||
| NumberType _
|
||||
@@ -35,8 +112,21 @@ module internal JsonSerializeGenerator =
|
||||
| Guid
|
||||
| Uri ->
|
||||
// JsonValue.Create<type>
|
||||
SynExpr.createLongIdent [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonValue" ; "Create" ]
|
||||
|> SynExpr.typeApp [ fieldType ]
|
||||
(SynExpr.createIdent "field")
|
||||
|> assertNotNull
|
||||
(Ident.create "field")
|
||||
(SynExpr.CreateConst
|
||||
$"Expected type %s{SynType.toHumanReadableString fieldType} to be non-null, but received a null value when serialising")
|
||||
|> SynExpr.createLet
|
||||
[
|
||||
SynBinding.basic
|
||||
[ Ident.create "field" ]
|
||||
[]
|
||||
(SynExpr.createLongIdent [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonValue" ; "Create" ]
|
||||
|> SynExpr.typeApp [ fieldType ]
|
||||
|> SynExpr.applyTo (SynExpr.createIdent "field"))
|
||||
]
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, false
|
||||
| DateTimeOffset ->
|
||||
// fun field -> field.ToString("o") |> JsonValue.Create<string>
|
||||
@@ -49,41 +139,17 @@ module internal JsonSerializeGenerator =
|
||||
|> SynExpr.pipeThroughFunction create
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, false
|
||||
| NullableType ty ->
|
||||
// fun field -> if field.HasValue then {serializeNode ty} field.Value else JsonValue.Create null
|
||||
let inner, innerIsJsonNode = serializeNode ty
|
||||
|
||||
SynExpr.applyFunction inner (SynExpr.createLongIdent [ "field" ; "Value" ])
|
||||
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|
||||
|> SynExpr.ifThenElse (SynExpr.createLongIdent [ "field" ; "HasValue" ]) (jsonNull ())
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, innerIsJsonNode
|
||||
| OptionType ty ->
|
||||
// fun field -> match field with | None -> JsonValue.Create null | Some v -> {serializeNode ty} field
|
||||
let noneClause = jsonNull () |> SynMatchClause.create (SynPat.named "None")
|
||||
|
||||
let someClause =
|
||||
let inner, innerIsJsonNode = serializeNode ty
|
||||
let target = SynExpr.applyFunction inner (SynExpr.createIdent "field")
|
||||
|
||||
if innerIsJsonNode then
|
||||
target
|
||||
else
|
||||
target
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|
||||
|> SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "field" ])
|
||||
|
||||
[ noneClause ; someClause ]
|
||||
|> SynExpr.createMatch (SynExpr.createIdent "field")
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, true
|
||||
| ArrayType ty
|
||||
| ListType ty ->
|
||||
// fun field ->
|
||||
// let arr = JsonArray ()
|
||||
// for mem in field do arr.Add ({serializeNode} mem)
|
||||
// arr
|
||||
let isNullableChild =
|
||||
match JsonNodeWithNullability.Identify ty with
|
||||
| CannotBeNull -> false
|
||||
| Nullable -> true
|
||||
|
||||
[
|
||||
SynExpr.ForEach (
|
||||
DebugPointAtFor.Yes range0,
|
||||
@@ -94,7 +160,17 @@ module internal JsonSerializeGenerator =
|
||||
SynExpr.createIdent "field",
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "arr" ; "Add" ])
|
||||
(SynExpr.paren (SynExpr.applyFunction (fst (serializeNode ty)) (SynExpr.createIdent "mem"))),
|
||||
(SynExpr.paren (
|
||||
SynExpr.applyFunction
|
||||
(fst (
|
||||
(if isNullableChild then
|
||||
serializeNodeNullable
|
||||
else
|
||||
serializeNodeNonNullable)
|
||||
ty
|
||||
))
|
||||
(SynExpr.createIdent "mem")
|
||||
)),
|
||||
range0
|
||||
)
|
||||
SynExpr.createIdent "arr"
|
||||
@@ -108,15 +184,28 @@ module internal JsonSerializeGenerator =
|
||||
]
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, false
|
||||
| IDictionaryType (_keyType, valueType)
|
||||
| DictionaryType (_keyType, valueType)
|
||||
| IReadOnlyDictionaryType (_keyType, valueType)
|
||||
| MapType (_keyType, valueType) ->
|
||||
| IDictionaryType (keyType, valueType)
|
||||
| DictionaryType (keyType, valueType)
|
||||
| IReadOnlyDictionaryType (keyType, valueType)
|
||||
| MapType (keyType, valueType) ->
|
||||
// fun field ->
|
||||
// let ret = JsonObject ()
|
||||
// for (KeyValue(key, value)) in field do
|
||||
// ret.Add (key.ToString (), {serializeNode} value)
|
||||
// ret
|
||||
let isNullableValueField =
|
||||
match JsonNodeWithNullability.Identify valueType with
|
||||
| CannotBeNull -> false
|
||||
| Nullable -> true
|
||||
|
||||
// TODO: this is a bit dubious, because user-defined types will
|
||||
// by default have non-null ToString
|
||||
let keyTypeHasNonNullToString =
|
||||
match keyType with
|
||||
| String
|
||||
| Uri -> true
|
||||
| _ -> false
|
||||
|
||||
[
|
||||
SynExpr.ForEach (
|
||||
DebugPointAtFor.Yes range0,
|
||||
@@ -129,10 +218,33 @@ module internal JsonSerializeGenerator =
|
||||
(SynExpr.createLongIdent [ "ret" ; "Add" ])
|
||||
(SynExpr.tuple
|
||||
[
|
||||
SynExpr.createLongIdent [ "key" ; "ToString" ]
|
||||
|> SynExpr.applyTo (SynExpr.CreateConst ())
|
||||
SynExpr.applyFunction (fst (serializeNode valueType)) (SynExpr.createIdent "value")
|
||||
]),
|
||||
SynExpr.createIdent "key"
|
||||
|> if keyTypeHasNonNullToString then
|
||||
id
|
||||
else
|
||||
assertNotNull
|
||||
(Ident.create "key")
|
||||
(SynExpr.CreateConst
|
||||
"A map key unexpectedly yielded null when we `ToString`'ed it. Map keys must yield non-null strings on `ToString`.")
|
||||
|
||||
SynExpr.applyFunction
|
||||
(fst (
|
||||
(if isNullableValueField then
|
||||
serializeNodeNullable
|
||||
else
|
||||
serializeNodeNonNullable)
|
||||
valueType
|
||||
))
|
||||
(SynExpr.createIdent "value")
|
||||
])
|
||||
|> SynExpr.createLet
|
||||
[
|
||||
SynBinding.basic
|
||||
[ Ident.create "key" ]
|
||||
[]
|
||||
(SynExpr.createLongIdent [ "key" ; "ToString" ]
|
||||
|> SynExpr.applyTo (SynExpr.CreateConst ()))
|
||||
],
|
||||
range0
|
||||
)
|
||||
SynExpr.createIdent "ret"
|
||||
@@ -147,7 +259,7 @@ module internal JsonSerializeGenerator =
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, false
|
||||
| JsonNode -> SynExpr.createIdent "id", true
|
||||
| Unit ->
|
||||
| UnitType ->
|
||||
SynExpr.createLambda
|
||||
"value"
|
||||
(SynExpr.createLongIdent [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonObject" ]
|
||||
@@ -165,13 +277,24 @@ module internal JsonSerializeGenerator =
|
||||
/// propertyName is probably a string literal, but it could be a [<Literal>] variable
|
||||
/// `node.Add ({propertyName}, {toJsonNode})`
|
||||
let createSerializeRhsRecord (propertyName : SynExpr) (fieldId : Ident) (fieldType : SynType) : SynExpr =
|
||||
[
|
||||
propertyName
|
||||
SynExpr.pipeThroughFunction
|
||||
(fst (serializeNode fieldType))
|
||||
(SynExpr.createLongIdent' [ Ident.create "input" ; fieldId ])
|
||||
|> SynExpr.paren
|
||||
]
|
||||
let isNullableField =
|
||||
match JsonNodeWithNullability.Identify fieldType with
|
||||
| CannotBeNull -> false
|
||||
| Nullable -> true
|
||||
|
||||
let serialised =
|
||||
if isNullableField then
|
||||
let value =
|
||||
serializeNodeNullable fieldType
|
||||
|> fst
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "toObj" ])
|
||||
|
||||
SynExpr.pipeThroughFunction value (SynExpr.createLongIdent' [ Ident.create "input" ; fieldId ])
|
||||
else
|
||||
let value = serializeNodeNonNullable fieldType |> fst
|
||||
SynExpr.pipeThroughFunction value (SynExpr.createLongIdent' [ Ident.create "input" ; fieldId ])
|
||||
|
||||
[ propertyName ; SynExpr.paren serialised ]
|
||||
|> SynExpr.tuple
|
||||
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "node" ; "Add" ])
|
||||
|
||||
@@ -179,8 +302,7 @@ module internal JsonSerializeGenerator =
|
||||
let propertyNameAttr =
|
||||
attrs
|
||||
|> List.tryFind (fun attr ->
|
||||
(SynLongIdent.toString attr.TypeName)
|
||||
.EndsWith ("JsonPropertyName", StringComparison.Ordinal)
|
||||
(SynLongIdent.toString attr.TypeName).EndsWith ("JsonPropertyName", StringComparison.Ordinal)
|
||||
)
|
||||
|
||||
match propertyNameAttr with
|
||||
@@ -197,8 +319,7 @@ module internal JsonSerializeGenerator =
|
||||
let getIsJsonExtension (attrs : SynAttribute list) : bool =
|
||||
attrs
|
||||
|> List.tryFind (fun attr ->
|
||||
(SynLongIdent.toString attr.TypeName)
|
||||
.EndsWith ("JsonExtensionData", StringComparison.Ordinal)
|
||||
(SynLongIdent.toString attr.TypeName).EndsWith ("JsonExtensionData", StringComparison.Ordinal)
|
||||
)
|
||||
|> Option.isSome
|
||||
|
||||
@@ -279,7 +400,10 @@ module internal JsonSerializeGenerator =
|
||||
| DictionaryType (String, v) -> v
|
||||
| _ -> failwith "Expected JsonExtensionData to be a Dictionary<string, something>"
|
||||
|
||||
let serialise = fst (serializeNode valType)
|
||||
let serialise =
|
||||
match JsonNodeWithNullability.Identify valType with
|
||||
| CannotBeNull -> fst (serializeNodeNonNullable valType)
|
||||
| Nullable -> fst (serializeNodeNullable valType)
|
||||
|
||||
SynExpr.createIdent "node"
|
||||
|> SynExpr.callMethodArg
|
||||
@@ -344,7 +468,15 @@ module internal JsonSerializeGenerator =
|
||||
let propertyName = getPropertyName (Option.get fieldData.Ident) fieldData.Attrs
|
||||
|
||||
let node =
|
||||
SynExpr.applyFunction (fst (serializeNode fieldData.Type)) (SynExpr.createIdent caseName)
|
||||
match JsonNodeWithNullability.Identify fieldData.Type with
|
||||
| CannotBeNull ->
|
||||
SynExpr.applyFunction
|
||||
(fst (serializeNodeNonNullable fieldData.Type))
|
||||
(SynExpr.createIdent caseName)
|
||||
| Nullable ->
|
||||
SynExpr.applyFunction
|
||||
(fst (serializeNodeNullable fieldData.Type))
|
||||
(SynExpr.createIdent caseName)
|
||||
|
||||
[ propertyName ; node ]
|
||||
|> SynExpr.tuple
|
||||
@@ -519,17 +651,21 @@ type JsonSerializeGenerator () =
|
||||
member _.ValidInputExtensions = [ ".fs" ]
|
||||
|
||||
member _.Generate (context : GeneratorContext) =
|
||||
let targetedTypes =
|
||||
MyriadParamParser.render context.AdditionalParameters
|
||||
|> Map.map (fun _ v -> v.Split '!' |> Array.toList |> List.map DesiredGenerator.Parse)
|
||||
|
||||
let ast, _ =
|
||||
Ast.fromFilename context.InputFilename |> Async.RunSynchronously |> Array.head
|
||||
|
||||
let relevantTypes =
|
||||
Ast.extractTypeDefn ast
|
||||
Ast.getTypes ast
|
||||
|> List.map (fun (name, defns) ->
|
||||
defns
|
||||
|> List.choose (fun defn ->
|
||||
if Ast.isRecord defn then Some defn
|
||||
elif Ast.isDu defn then Some defn
|
||||
elif AstHelper.isEnum defn then Some defn
|
||||
if SynTypeDefn.isRecord defn then Some defn
|
||||
elif SynTypeDefn.isDu defn then Some defn
|
||||
elif SynTypeDefn.isEnum defn then Some defn
|
||||
else None
|
||||
)
|
||||
|> fun defns -> name, defns
|
||||
@@ -540,8 +676,29 @@ type JsonSerializeGenerator () =
|
||||
|> List.choose (fun (ns, types) ->
|
||||
types
|
||||
|> List.choose (fun typeDef ->
|
||||
match Ast.getAttribute<JsonSerializeAttribute> typeDef with
|
||||
| None -> None
|
||||
match SynTypeDefn.getAttribute typeof<JsonSerializeAttribute>.Name typeDef with
|
||||
| None ->
|
||||
let name = SynTypeDefn.getName typeDef |> List.map _.idText |> String.concat "."
|
||||
|
||||
match Map.tryFind name targetedTypes with
|
||||
| Some desired ->
|
||||
desired
|
||||
|> List.tryPick (fun generator ->
|
||||
match generator with
|
||||
| DesiredGenerator.JsonSerialize arg ->
|
||||
let spec =
|
||||
{
|
||||
ExtensionMethods =
|
||||
arg
|
||||
|> Option.defaultValue
|
||||
JsonSerializeAttribute.DefaultIsExtensionMethod
|
||||
}
|
||||
|
||||
Some (typeDef, spec)
|
||||
| _ -> None
|
||||
)
|
||||
| _ -> None
|
||||
|
||||
| Some attr ->
|
||||
let arg =
|
||||
match SynExpr.stripOptionalParen attr.ArgExpr with
|
||||
|
@@ -1,6 +1,7 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open WoofWare.Whippet.Fantomas
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal Measure =
|
||||
@@ -20,5 +21,4 @@ module internal Measure =
|
||||
| l ->
|
||||
let l = String.concat "." l
|
||||
failwith $"unrecognised type for measure: %s{l}"
|
||||
|
||||
|> SynExpr.createLongIdent
|
||||
|
42
WoofWare.Myriad.Plugins/MyriadParamParser.fs
Normal file
42
WoofWare.Myriad.Plugins/MyriadParamParser.fs
Normal file
@@ -0,0 +1,42 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open System.Collections.Generic
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal MyriadParamParser =
|
||||
(*
|
||||
An apparent bug in Myriad's argument parsing means that this:
|
||||
|
||||
<MyriadParams>
|
||||
<Foo>bar</Foo>
|
||||
<Baz>quux</Baz>
|
||||
</MyriadParams>
|
||||
|
||||
leads to this:
|
||||
|
||||
Foo = "bar;Baz=quux"
|
||||
|
||||
I'm not going to put effort into fixing Myriad, though, because I want
|
||||
to build something much more powerful instead.
|
||||
*)
|
||||
|
||||
/// Call this with `context.AdditionalParameters`.
|
||||
let render (pars : IDictionary<string, string>) : Map<string, string> =
|
||||
match pars.Count with
|
||||
| 0 -> Map.empty
|
||||
| 1 ->
|
||||
let (KeyValue (key, value)) = pars |> Seq.exactlyOne
|
||||
|
||||
match value.Split ';' |> Seq.toList with
|
||||
| [] -> failwith "LOGIC ERROR"
|
||||
| value :: rest ->
|
||||
rest
|
||||
|> Seq.map (fun v ->
|
||||
let split = v.Split '='
|
||||
split.[0], String.concat "=" split.[1..]
|
||||
)
|
||||
|> Seq.append (Seq.singleton (key, value))
|
||||
|> Map.ofSeq
|
||||
| _ ->
|
||||
// assume the Myriad bug is fixed!
|
||||
pars |> Seq.map (fun (KeyValue (k, v)) -> k, v) |> Map.ofSeq
|
23
WoofWare.Myriad.Plugins/Parameters.fs
Normal file
23
WoofWare.Myriad.Plugins/Parameters.fs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
type internal DesiredGenerator =
|
||||
| InterfaceMock of isInternal : bool option
|
||||
| JsonParse of extensionMethod : bool option
|
||||
| JsonSerialize of extensionMethod : bool option
|
||||
| HttpClient of extensionMethod : bool option
|
||||
|
||||
static member Parse (s : string) =
|
||||
match s with
|
||||
| "GenerateMock" -> DesiredGenerator.InterfaceMock None
|
||||
| "GenerateMock(true)" -> DesiredGenerator.InterfaceMock (Some true)
|
||||
| "GenerateMock(false)" -> DesiredGenerator.InterfaceMock (Some false)
|
||||
| "JsonParse" -> DesiredGenerator.JsonParse None
|
||||
| "JsonParse(true)" -> DesiredGenerator.JsonParse (Some true)
|
||||
| "JsonParse(false)" -> DesiredGenerator.JsonParse (Some false)
|
||||
| "JsonSerialize" -> DesiredGenerator.JsonSerialize None
|
||||
| "JsonSerialize(true)" -> DesiredGenerator.JsonSerialize (Some true)
|
||||
| "JsonSerialize(false)" -> DesiredGenerator.JsonSerialize (Some false)
|
||||
| "HttpClient" -> DesiredGenerator.HttpClient None
|
||||
| "HttpClient(true)" -> DesiredGenerator.HttpClient (Some true)
|
||||
| "HttpClient(false)" -> DesiredGenerator.HttpClient (Some false)
|
||||
| _ -> failwith $"Failed to parse as a generator specification: %s{s}"
|
@@ -1,32 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal Primitives =
|
||||
/// Given e.g. "byte", returns "System.Byte".
|
||||
let qualifyType (typeName : string) : LongIdent option =
|
||||
match typeName with
|
||||
| "float32"
|
||||
| "single" -> [ "System" ; "Single" ] |> Some
|
||||
| "float"
|
||||
| "double" -> [ "System" ; "Double" ] |> Some
|
||||
| "byte"
|
||||
| "uint8" -> [ "System" ; "Byte" ] |> Some
|
||||
| "sbyte"
|
||||
| "int8" -> [ "System" ; "SByte" ] |> Some
|
||||
| "int16" -> [ "System" ; "Int16" ] |> Some
|
||||
| "int"
|
||||
| "int32" -> [ "System" ; "Int32" ] |> Some
|
||||
| "int64" -> [ "System" ; "Int64" ] |> Some
|
||||
| "uint16" -> [ "System" ; "UInt16" ] |> Some
|
||||
| "uint"
|
||||
| "uint32" -> [ "System" ; "UInt32" ] |> Some
|
||||
| "uint64" -> [ "System" ; "UInt64" ] |> Some
|
||||
| "char" -> [ "System" ; "Char" ] |> Some
|
||||
| "decimal" -> [ "System" ; "Decimal" ] |> Some
|
||||
| "string" -> [ "System" ; "String" ] |> Some
|
||||
| "bool" -> [ "System" ; "Boolean" ] |> Some
|
||||
| _ -> None
|
||||
|> Option.map (List.map (fun i -> (Ident (i, range0))))
|
@@ -1,7 +1,9 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open System
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Xml
|
||||
open WoofWare.Whippet.Fantomas
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal RemoveOptionsGenerator =
|
||||
@@ -58,7 +60,7 @@ module internal RemoveOptionsGenerator =
|
||||
Attributes = []
|
||||
}
|
||||
|
||||
let typeDecl = AstHelper.defineRecordType record
|
||||
let typeDecl = RecordType.ToAst record
|
||||
|
||||
SynModuleDecl.Types ([ typeDecl ], range0)
|
||||
|
||||
@@ -95,7 +97,7 @@ module internal RemoveOptionsGenerator =
|
||||
|
||||
SynLongIdent.createI fieldData.Ident, body
|
||||
)
|
||||
|> AstHelper.instantiateRecord
|
||||
|> SynExpr.createRecord None
|
||||
|
||||
SynBinding.basic
|
||||
[ functionName ]
|
||||
@@ -145,41 +147,31 @@ type RemoveOptionsGenerator () =
|
||||
let ast, _ =
|
||||
Ast.fromFilename context.InputFilename |> Async.RunSynchronously |> Array.head
|
||||
|
||||
let records = Ast.extractRecords ast
|
||||
let records = Ast.getRecords ast
|
||||
|
||||
let namespaceAndRecords =
|
||||
records
|
||||
|> List.choose (fun (ns, types) ->
|
||||
match types |> List.filter Ast.hasAttribute<RemoveOptionsAttribute> with
|
||||
| [] -> None
|
||||
| types ->
|
||||
let types =
|
||||
types
|
||||
|> List.map (fun ty ->
|
||||
match ty with
|
||||
| SynTypeDefn.SynTypeDefn (sci,
|
||||
SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Record (access,
|
||||
fields,
|
||||
_),
|
||||
_),
|
||||
smd,
|
||||
smdo,
|
||||
_,
|
||||
_) -> RecordType.OfRecord sci smd access fields
|
||||
| _ -> failwith "unexpectedly not a record"
|
||||
)
|
||||
|
||||
Some (ns, types)
|
||||
|> List.collect (fun (ns, ty) ->
|
||||
ty
|
||||
|> List.filter (fun record ->
|
||||
record.Attributes
|
||||
|> List.exists (fun attr ->
|
||||
attr.TypeName.LongIdent
|
||||
|> List.last
|
||||
|> _.idText
|
||||
|> fun s ->
|
||||
if s.EndsWith ("Attribute", StringComparison.Ordinal) then
|
||||
s
|
||||
else
|
||||
$"%s{s}Attribute"
|
||||
|> (=) typeof<RemoveOptionsAttribute>.Name
|
||||
)
|
||||
)
|
||||
|> List.map (fun ty -> ns, ty)
|
||||
)
|
||||
|
||||
let modules =
|
||||
namespaceAndRecords
|
||||
|> List.collect (fun (ns, records) ->
|
||||
records
|
||||
|> List.map (fun record ->
|
||||
let recordModule = RemoveOptionsGenerator.createRecordModule ns record
|
||||
recordModule
|
||||
)
|
||||
)
|
||||
|> List.map (fun (ns, record) -> RemoveOptionsGenerator.createRecordModule ns record)
|
||||
|
||||
Output.Ast modules
|
||||
|
@@ -292,27 +292,4 @@ WoofWare.Myriad.Plugins.SwaggerParameter.In [property]: [read-only] WoofWare.Myr
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.Name [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.Parse [static method]: System.Text.Json.Nodes.JsonObject -> WoofWare.Myriad.Plugins.SwaggerParameter
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.Required [property]: [read-only] bool option
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.Type [property]: [read-only] WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.SynFieldData`1 inherit obj
|
||||
WoofWare.Myriad.Plugins.SynFieldData`1..ctor [constructor]: (Fantomas.FCS.Syntax.SynAttribute list, 'Ident, Fantomas.FCS.Syntax.SynType)
|
||||
WoofWare.Myriad.Plugins.SynFieldData`1.Attrs [property]: [read-only] Fantomas.FCS.Syntax.SynAttribute list
|
||||
WoofWare.Myriad.Plugins.SynFieldData`1.get_Attrs [method]: unit -> Fantomas.FCS.Syntax.SynAttribute list
|
||||
WoofWare.Myriad.Plugins.SynFieldData`1.get_Ident [method]: unit -> 'Ident
|
||||
WoofWare.Myriad.Plugins.SynFieldData`1.get_Type [method]: unit -> Fantomas.FCS.Syntax.SynType
|
||||
WoofWare.Myriad.Plugins.SynFieldData`1.Ident [property]: [read-only] 'Ident
|
||||
WoofWare.Myriad.Plugins.SynFieldData`1.Type [property]: [read-only] Fantomas.FCS.Syntax.SynType
|
||||
WoofWare.Myriad.Plugins.UnionCase inherit obj
|
||||
WoofWare.Myriad.Plugins.UnionCase.mapIdentFields [static method]: ('a -> 'b) -> 'a WoofWare.Myriad.Plugins.UnionCase -> 'b WoofWare.Myriad.Plugins.UnionCase
|
||||
WoofWare.Myriad.Plugins.UnionCase.ofSynUnionCase [static method]: Fantomas.FCS.Syntax.SynUnionCase -> Fantomas.FCS.Syntax.Ident option WoofWare.Myriad.Plugins.UnionCase
|
||||
WoofWare.Myriad.Plugins.UnionCase`1 inherit obj
|
||||
WoofWare.Myriad.Plugins.UnionCase`1..ctor [constructor]: (Fantomas.FCS.Syntax.Ident, Fantomas.FCS.Xml.PreXmlDoc option, Fantomas.FCS.Syntax.SynAccess option, Fantomas.FCS.Syntax.SynAttribute list, 'ident WoofWare.Myriad.Plugins.SynFieldData list)
|
||||
WoofWare.Myriad.Plugins.UnionCase`1.Access [property]: [read-only] Fantomas.FCS.Syntax.SynAccess option
|
||||
WoofWare.Myriad.Plugins.UnionCase`1.Attributes [property]: [read-only] Fantomas.FCS.Syntax.SynAttribute list
|
||||
WoofWare.Myriad.Plugins.UnionCase`1.Fields [property]: [read-only] 'ident WoofWare.Myriad.Plugins.SynFieldData list
|
||||
WoofWare.Myriad.Plugins.UnionCase`1.get_Access [method]: unit -> Fantomas.FCS.Syntax.SynAccess option
|
||||
WoofWare.Myriad.Plugins.UnionCase`1.get_Attributes [method]: unit -> Fantomas.FCS.Syntax.SynAttribute list
|
||||
WoofWare.Myriad.Plugins.UnionCase`1.get_Fields [method]: unit -> 'ident WoofWare.Myriad.Plugins.SynFieldData list
|
||||
WoofWare.Myriad.Plugins.UnionCase`1.get_Name [method]: unit -> Fantomas.FCS.Syntax.Ident
|
||||
WoofWare.Myriad.Plugins.UnionCase`1.get_XmlDoc [method]: unit -> Fantomas.FCS.Xml.PreXmlDoc option
|
||||
WoofWare.Myriad.Plugins.UnionCase`1.Name [property]: [read-only] Fantomas.FCS.Syntax.Ident
|
||||
WoofWare.Myriad.Plugins.UnionCase`1.XmlDoc [property]: [read-only] Fantomas.FCS.Xml.PreXmlDoc option
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.Type [property]: [read-only] WoofWare.Myriad.Plugins.Definition
|
@@ -198,7 +198,14 @@ and ObjectTypeDefinition =
|
||||
|> Map.ofSeq
|
||||
|> Some
|
||||
|
||||
let example = asObjOpt node "example"
|
||||
let example =
|
||||
match node.["example"] with
|
||||
| null -> None
|
||||
| :? JsonObject as o -> Some o
|
||||
| _ ->
|
||||
// Gitea returns a stringified and malformed JSON object here.
|
||||
// Don't throw; just omit.
|
||||
None
|
||||
|
||||
let required = asArrOpt'<string> node "required"
|
||||
|
||||
|
@@ -1,11 +1,11 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open System.Collections.Generic
|
||||
open System.IO
|
||||
open System.Threading
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Xml
|
||||
open Fantomas.FCS.Text.Range
|
||||
open WoofWare.Whippet.Fantomas
|
||||
|
||||
type internal SwaggerClientConfig =
|
||||
{
|
||||
@@ -18,6 +18,7 @@ type internal SwaggerClientConfig =
|
||||
type internal Produces =
|
||||
// TODO: this will cope with decoding JSON, plain text, etc
|
||||
| Produces of string
|
||||
| OctetStream
|
||||
|
||||
type internal Endpoint =
|
||||
{
|
||||
@@ -46,16 +47,8 @@ type internal Types =
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SwaggerClientGenerator =
|
||||
let outputFile = FileInfo "/tmp/output.txt"
|
||||
|
||||
// do
|
||||
// use _ = File.Create outputFile.FullName
|
||||
// ()
|
||||
|
||||
let log (line : string) =
|
||||
// use w = outputFile.AppendText ()
|
||||
// w.WriteLine line
|
||||
()
|
||||
let internal log (_ : string) = ()
|
||||
|
||||
let renderType (types : Types) (defn : Definition) : SynType option =
|
||||
match types.ByDefinition.TryGetValue defn with
|
||||
@@ -476,6 +469,15 @@ module internal SwaggerClientGenerator =
|
||||
(SynLongIdent.createS' [ "RestEase" ; "Header" ])
|
||||
// Gitea, at least, starts with a `/`, which `Uri` then takes to indicate an absolute path.
|
||||
(SynExpr.tuple [ SynExpr.CreateConst "Content-Type" ; SynExpr.CreateConst contentType ])
|
||||
| Produces.OctetStream ->
|
||||
SynAttribute.create
|
||||
(SynLongIdent.createS' [ "RestEase" ; "Header" ])
|
||||
// Gitea, at least, starts with a `/`, which `Uri` then takes to indicate an absolute path.
|
||||
(SynExpr.tuple
|
||||
[
|
||||
SynExpr.CreateConst "Content-Type"
|
||||
SynExpr.CreateConst "application/octet-stream"
|
||||
])
|
||||
]
|
||||
|
||||
returnType
|
||||
@@ -511,6 +513,7 @@ module internal SwaggerClientGenerator =
|
||||
|> List.singleton
|
||||
|
||||
open Myriad.Core
|
||||
open System.IO
|
||||
|
||||
/// Myriad generator that stamps out an interface and class to access a Swagger-specified API.
|
||||
[<MyriadGenerator("swagger-client")>]
|
||||
@@ -621,10 +624,11 @@ type SwaggerClientGenerator () =
|
||||
|
||||
let produces =
|
||||
match endpoint.Produces with
|
||||
| None -> Produces "json"
|
||||
| None -> Produces.Produces "json"
|
||||
| Some [] -> failwith $"API specified empty Produces: %s{path} (%O{method})"
|
||||
| Some [ MimeType "application/json" ] -> Produces "json"
|
||||
| Some [ MimeType (StartsWith "text/" t) ] -> Produces t
|
||||
| Some [ MimeType "application/octet-stream" ] -> Produces.OctetStream
|
||||
| Some [ MimeType "application/json" ] -> Produces.Produces "json"
|
||||
| Some [ MimeType (StartsWith "text/" t) ] -> Produces.Produces t
|
||||
| Some [ MimeType s ] ->
|
||||
failwithf
|
||||
$"we don't support non-JSON Produces right now, got: %s{s} (%s{path} %O{method})"
|
||||
@@ -672,31 +676,16 @@ type SwaggerClientGenerator () =
|
||||
|> Seq.toList
|
||||
|
||||
let config =
|
||||
// Bug in Myriad, their arg parsing is borked.
|
||||
let pars =
|
||||
context.AdditionalParameters
|
||||
|> Seq.map (fun (KeyValue (k, v)) -> k, v)
|
||||
|> Seq.toList
|
||||
let pars = MyriadParamParser.render context.AdditionalParameters
|
||||
|
||||
let pars =
|
||||
match pars with
|
||||
| [] ->
|
||||
failwith "No parameters given. You must supply the <ClassName /> parameter in <MyriadParams />."
|
||||
| [ key, value ] ->
|
||||
let semicolon = value.IndexOf ';'
|
||||
pars
|
||||
|> Map.toSeq
|
||||
|> Seq.map (fun (k, v) -> k.ToUpperInvariant (), v)
|
||||
|> Map.ofSeq
|
||||
|
||||
if semicolon >= 0 then
|
||||
let equals = value.IndexOf ('=', semicolon)
|
||||
|
||||
[
|
||||
key, value.Substring (0, semicolon)
|
||||
value.Substring (semicolon + 1, equals - semicolon - 1), value.Substring (equals + 1)
|
||||
]
|
||||
else
|
||||
[ key, value ]
|
||||
| rest -> rest
|
||||
|> List.map (fun (key, value) -> key.ToUpperInvariant (), value)
|
||||
|> Map.ofList
|
||||
if pars.IsEmpty then
|
||||
failwith "No parameters given. You must supply the <ClassName /> parameter in <MyriadParams />."
|
||||
|
||||
let createMock =
|
||||
match Map.tryFind "GENERATEMOCKVISIBILITY" pars with
|
||||
|
@@ -1,49 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
|
||||
type internal CompExprBinding =
|
||||
| LetBang of varName : string * rhs : SynExpr
|
||||
| Let of varName : string * rhs : SynExpr
|
||||
| Use of varName : string * rhs : SynExpr
|
||||
| Do of body : SynExpr
|
||||
|
||||
(*
|
||||
Potential API!
|
||||
type internal CompExprBindings =
|
||||
private
|
||||
{
|
||||
/// These are stored in reverse.
|
||||
Bindings : CompExprBinding list
|
||||
CompExprName : string
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal CompExprBindings =
|
||||
let make (name : string) : CompExprBindings =
|
||||
{
|
||||
Bindings = []
|
||||
CompExprName = name
|
||||
}
|
||||
|
||||
let thenDo (body : SynExpr) (bindings : CompExprBindings) =
|
||||
{ bindings with
|
||||
Bindings = (Do body :: bindings.Bindings)
|
||||
}
|
||||
|
||||
let thenLet (varName : string) (value : SynExpr) (bindings : CompExprBindings) =
|
||||
{ bindings with
|
||||
Bindings = (Let (varName, value) :: bindings.Bindings)
|
||||
}
|
||||
|
||||
let thenLetBang (varName : string) (value : SynExpr) (bindings : CompExprBindings) =
|
||||
{ bindings with
|
||||
Bindings = (LetBang (varName, value) :: bindings.Bindings)
|
||||
}
|
||||
|
||||
|
||||
let thenUse (varName : string) (value : SynExpr) (bindings : CompExprBindings) =
|
||||
{ bindings with
|
||||
Bindings = (LetBang (varName, value) :: bindings.Bindings)
|
||||
}
|
||||
*)
|
@@ -1,65 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open System
|
||||
open System.Text
|
||||
open System.Text.RegularExpressions
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal Ident =
|
||||
let inline create (s : string) = Ident (s, range0)
|
||||
|
||||
/// Fantomas bug, perhaps? "type" is not rendered as ``type``, although the ASTs are identical
|
||||
/// apart from the ranges?
|
||||
/// Awful hack: here is a function that does this sort of thing.
|
||||
let createSanitisedParamName (s : string) =
|
||||
match s with
|
||||
| "type" -> create "type'"
|
||||
| "private" -> create "private'"
|
||||
| _ ->
|
||||
|
||||
let result = StringBuilder ()
|
||||
|
||||
for i = 0 to s.Length - 1 do
|
||||
if Char.IsLetter s.[i] then
|
||||
result.Append s.[i] |> ignore<StringBuilder>
|
||||
elif Char.IsNumber s.[i] then
|
||||
if result.Length > 0 then
|
||||
result.Append s.[i] |> ignore<StringBuilder>
|
||||
elif s.[i] = '_' || s.[i] = '-' then
|
||||
result.Append '_' |> ignore<StringBuilder>
|
||||
else
|
||||
failwith $"could not convert to ident: %s{s}"
|
||||
|
||||
create (result.ToString ())
|
||||
|
||||
let private alnum = Regex @"^[a-zA-Z][a-zA-Z0-9]*$"
|
||||
|
||||
let createSanitisedTypeName (s : string) =
|
||||
let result = StringBuilder ()
|
||||
let mutable capitalize = true
|
||||
|
||||
for i = 0 to s.Length - 1 do
|
||||
if Char.IsLetter s.[i] then
|
||||
if capitalize then
|
||||
result.Append (Char.ToUpperInvariant s.[i]) |> ignore<StringBuilder>
|
||||
capitalize <- false
|
||||
else
|
||||
result.Append s.[i] |> ignore<StringBuilder>
|
||||
elif Char.IsNumber s.[i] then
|
||||
if result.Length > 0 then
|
||||
result.Append s.[i] |> ignore<StringBuilder>
|
||||
elif s.[i] = '_' then
|
||||
capitalize <- true
|
||||
|
||||
if result.Length = 0 then
|
||||
failwith $"String %s{s} was not suitable as a type identifier"
|
||||
|
||||
Ident (result.ToString (), range0)
|
||||
|
||||
let lowerFirstLetter (x : Ident) : Ident =
|
||||
let result = StringBuilder x.idText.Length
|
||||
result.Append (Char.ToLowerInvariant x.idText.[0]) |> ignore
|
||||
result.Append x.idText.[1..] |> ignore
|
||||
create ((result : StringBuilder).ToString ())
|
@@ -1,17 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Xml
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal PreXmlDoc =
|
||||
let create (s : string) : PreXmlDoc =
|
||||
let s = s.Split "\n"
|
||||
|
||||
for i = 0 to s.Length - 1 do
|
||||
s.[i] <- " " + s.[i]
|
||||
|
||||
PreXmlDoc.Create (s, range0)
|
||||
|
||||
let create' (s : string seq) : PreXmlDoc =
|
||||
PreXmlDoc.Create (Array.ofSeq s, range0)
|
@@ -1,30 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynArgPats =
|
||||
let createNamed (caseNames : string list) : SynArgPats =
|
||||
match caseNames.Length with
|
||||
| 0 -> SynArgPats.Pats []
|
||||
| 1 ->
|
||||
SynPat.Named (SynIdent.createS caseNames.[0], false, None, range0)
|
||||
|> List.singleton
|
||||
|> SynArgPats.Pats
|
||||
| len ->
|
||||
caseNames
|
||||
|> List.map (fun name -> SynPat.Named (SynIdent.createS name, false, None, range0))
|
||||
|> fun t -> SynPat.Tuple (false, t, List.replicate (len - 1) range0, range0)
|
||||
|> fun t -> SynPat.Paren (t, range0)
|
||||
|> List.singleton
|
||||
|> SynArgPats.Pats
|
||||
|
||||
let create (pats : SynPat list) : SynArgPats =
|
||||
match pats.Length with
|
||||
| 0 -> SynArgPats.Pats []
|
||||
| 1 -> [ pats.[0] ] |> SynArgPats.Pats
|
||||
| len ->
|
||||
SynPat.Paren (SynPat.Tuple (false, pats, List.replicate (len - 1) range0, range0), range0)
|
||||
|> List.singleton
|
||||
|> SynArgPats.Pats
|
@@ -1,27 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynAttribute =
|
||||
let inline create (typeName : SynLongIdent) (arg : SynExpr) : SynAttribute =
|
||||
{
|
||||
TypeName = typeName
|
||||
ArgExpr = arg
|
||||
Target = None
|
||||
AppliesToGetterAndSetter = false
|
||||
Range = range0
|
||||
}
|
||||
|
||||
let internal compilationRepresentation : SynAttribute =
|
||||
[ "CompilationRepresentationFlags" ; "ModuleSuffix" ]
|
||||
|> SynExpr.createLongIdent
|
||||
|> SynExpr.paren
|
||||
|> create (SynLongIdent.createS "CompilationRepresentation")
|
||||
|
||||
let internal requireQualifiedAccess : SynAttribute =
|
||||
create (SynLongIdent.createS "RequireQualifiedAccess") (SynExpr.CreateConst ())
|
||||
|
||||
let internal autoOpen : SynAttribute =
|
||||
create (SynLongIdent.createS "AutoOpen") (SynExpr.CreateConst ())
|
@@ -1,15 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynAttributes =
|
||||
let ofAttrs (attrs : SynAttribute list) : SynAttributes =
|
||||
attrs
|
||||
|> List.map (fun a ->
|
||||
{
|
||||
Attributes = [ a ]
|
||||
Range = range0
|
||||
}
|
||||
)
|
@@ -1,233 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.SyntaxTrivia
|
||||
open Fantomas.FCS.Xml
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynBinding =
|
||||
|
||||
let rec private stripParen (pat : SynPat) =
|
||||
match pat with
|
||||
| SynPat.Paren (p, _) -> stripParen p
|
||||
| _ -> pat
|
||||
|
||||
let rec private getName (pat : SynPat) : Ident option =
|
||||
match stripParen pat with
|
||||
| SynPat.Named (SynIdent.SynIdent (name, _), _, _, _) -> Some name
|
||||
| SynPat.Typed (pat, _, _) -> getName pat
|
||||
| SynPat.LongIdent (SynLongIdent.SynLongIdent (longIdent, _, _), _, _, _, _, _) ->
|
||||
match longIdent with
|
||||
| [ x ] -> Some x
|
||||
| _ -> failwithf "got long ident %O ; can only get the name of a long ident with one component" longIdent
|
||||
| _ -> None
|
||||
|
||||
let private getArgInfo (pat : SynPat) : SynArgInfo list =
|
||||
// TODO: this only copes with one layer of tupling
|
||||
match stripParen pat with
|
||||
| SynPat.Tuple (_, pats, _, _) -> pats |> List.map (fun pat -> SynArgInfo.SynArgInfo ([], false, getName pat))
|
||||
| pat -> [ SynArgInfo.SynArgInfo (SynAttributes.Empty, false, getName pat) ]
|
||||
|
||||
let triviaZero (isMember : bool) =
|
||||
{
|
||||
SynBindingTrivia.EqualsRange = Some range0
|
||||
InlineKeyword = None
|
||||
LeadingKeyword =
|
||||
if isMember then
|
||||
SynLeadingKeyword.Member range0
|
||||
else
|
||||
SynLeadingKeyword.Let range0
|
||||
}
|
||||
|
||||
let basic (name : LongIdent) (args : SynPat list) (body : SynExpr) : SynBinding =
|
||||
let valInfo : SynValInfo =
|
||||
args
|
||||
|> List.map getArgInfo
|
||||
|> fun x -> SynValInfo.SynValInfo (x, SynArgInfo.SynArgInfo ([], false, None))
|
||||
|
||||
SynBinding.SynBinding (
|
||||
None,
|
||||
SynBindingKind.Normal,
|
||||
false,
|
||||
false,
|
||||
[],
|
||||
PreXmlDoc.Empty,
|
||||
SynValData.SynValData (None, valInfo, None),
|
||||
SynPat.identWithArgs name (SynArgPats.Pats args),
|
||||
None,
|
||||
body,
|
||||
range0,
|
||||
DebugPointAtBinding.Yes range0,
|
||||
triviaZero false
|
||||
)
|
||||
|
||||
let withMutability (mut : bool) (binding : SynBinding) : SynBinding =
|
||||
match binding with
|
||||
| SynBinding (pat, kind, inl, _, attrs, xml, valData, headPat, returnInfo, expr, range, debugPoint, trivia) ->
|
||||
SynBinding (pat, kind, inl, mut, attrs, xml, valData, headPat, returnInfo, expr, range, debugPoint, trivia)
|
||||
|
||||
let withRecursion (isRec : bool) (binding : SynBinding) : SynBinding =
|
||||
match binding with
|
||||
| SynBinding (pat, kind, inl, mut, attrs, xml, valData, headPat, returnInfo, expr, range, debugPoint, trivia) ->
|
||||
let trivia =
|
||||
{ trivia with
|
||||
LeadingKeyword =
|
||||
match trivia.LeadingKeyword with
|
||||
| SynLeadingKeyword.Let _ ->
|
||||
if isRec then
|
||||
SynLeadingKeyword.LetRec (range0, range0)
|
||||
else
|
||||
trivia.LeadingKeyword
|
||||
| SynLeadingKeyword.LetRec _ ->
|
||||
if isRec then
|
||||
trivia.LeadingKeyword
|
||||
else
|
||||
trivia.LeadingKeyword
|
||||
| existing ->
|
||||
failwith
|
||||
$"WoofWare.Myriad doesn't yet let you adjust the recursion modifier on a binding with modifier %O{existing}"
|
||||
}
|
||||
|
||||
SynBinding (pat, kind, inl, mut, attrs, xml, valData, headPat, returnInfo, expr, range, debugPoint, trivia)
|
||||
|
||||
let withAccessibility (acc : SynAccess option) (binding : SynBinding) : SynBinding =
|
||||
match binding with
|
||||
| SynBinding (_, kind, inl, mut, attrs, xml, valData, headPat, returnInfo, expr, range, debugPoint, trivia) ->
|
||||
let headPat =
|
||||
match headPat with
|
||||
| SynPat.LongIdent (ident, extra, options, argPats, _, range) ->
|
||||
SynPat.LongIdent (ident, extra, options, argPats, acc, range)
|
||||
| _ -> failwithf "unrecognised head pattern: %O" headPat
|
||||
|
||||
SynBinding (acc, kind, inl, mut, attrs, xml, valData, headPat, returnInfo, expr, range, debugPoint, trivia)
|
||||
|
||||
let withXmlDoc (doc : PreXmlDoc) (binding : SynBinding) : SynBinding =
|
||||
match binding with
|
||||
| SynBinding (acc, kind, inl, mut, attrs, _, valData, headPat, returnInfo, expr, range, debugPoint, trivia) ->
|
||||
SynBinding (acc, kind, inl, mut, attrs, doc, valData, headPat, returnInfo, expr, range, debugPoint, trivia)
|
||||
|
||||
let withReturnAnnotation (ty : SynType) (binding : SynBinding) : SynBinding =
|
||||
match binding with
|
||||
| SynBinding (acc, kind, inl, mut, attrs, doc, valData, headPat, _, expr, range, debugPoint, trivia) ->
|
||||
let retInfo =
|
||||
SynBindingReturnInfo.SynBindingReturnInfo (
|
||||
ty,
|
||||
range0,
|
||||
[],
|
||||
{
|
||||
ColonRange = Some range0
|
||||
}
|
||||
)
|
||||
|
||||
SynBinding (
|
||||
acc,
|
||||
kind,
|
||||
inl,
|
||||
mut,
|
||||
attrs,
|
||||
doc,
|
||||
valData,
|
||||
headPat,
|
||||
Some retInfo,
|
||||
expr,
|
||||
range,
|
||||
debugPoint,
|
||||
trivia
|
||||
)
|
||||
|
||||
let inline makeInline (binding : SynBinding) : SynBinding =
|
||||
match binding with
|
||||
| SynBinding (acc, kind, _, mut, attrs, doc, valData, headPat, ret, expr, range, debugPoint, trivia) ->
|
||||
SynBinding (
|
||||
acc,
|
||||
kind,
|
||||
true,
|
||||
mut,
|
||||
attrs,
|
||||
doc,
|
||||
valData,
|
||||
headPat,
|
||||
ret,
|
||||
expr,
|
||||
range,
|
||||
debugPoint,
|
||||
{ trivia with
|
||||
InlineKeyword = Some range0
|
||||
}
|
||||
)
|
||||
|
||||
let inline makeNotInline (binding : SynBinding) : SynBinding =
|
||||
match binding with
|
||||
| SynBinding (acc, kind, _, mut, attrs, doc, valData, headPat, ret, expr, range, debugPoint, trivia) ->
|
||||
SynBinding (
|
||||
acc,
|
||||
kind,
|
||||
false,
|
||||
mut,
|
||||
attrs,
|
||||
doc,
|
||||
valData,
|
||||
headPat,
|
||||
ret,
|
||||
expr,
|
||||
range,
|
||||
debugPoint,
|
||||
{ trivia with
|
||||
InlineKeyword = None
|
||||
}
|
||||
)
|
||||
|
||||
let inline setInline (isInline : bool) (binding : SynBinding) : SynBinding =
|
||||
if isInline then
|
||||
makeInline binding
|
||||
else
|
||||
makeNotInline binding
|
||||
|
||||
let makeStaticMember (binding : SynBinding) : SynBinding =
|
||||
let memberFlags =
|
||||
{
|
||||
SynMemberFlags.IsInstance = false
|
||||
SynMemberFlags.IsDispatchSlot = false
|
||||
SynMemberFlags.IsOverrideOrExplicitImpl = false
|
||||
SynMemberFlags.IsFinal = false
|
||||
SynMemberFlags.GetterOrSetterIsCompilerGenerated = false
|
||||
SynMemberFlags.MemberKind = SynMemberKind.Member
|
||||
}
|
||||
|
||||
match binding with
|
||||
| SynBinding (acc, kind, inl, mut, attrs, doc, valData, headPat, ret, expr, range, debugPoint, trivia) ->
|
||||
let valData =
|
||||
match valData with
|
||||
| SynValData.SynValData (_, valInfo, _) -> SynValData.SynValData (Some memberFlags, valInfo, None)
|
||||
|
||||
let trivia =
|
||||
{ trivia with
|
||||
LeadingKeyword = SynLeadingKeyword.StaticMember (range0, range0)
|
||||
}
|
||||
|
||||
SynBinding (acc, kind, inl, mut, attrs, doc, valData, headPat, ret, expr, range, debugPoint, trivia)
|
||||
|
||||
let makeInstanceMember (binding : SynBinding) : SynBinding =
|
||||
let memberFlags =
|
||||
{
|
||||
SynMemberFlags.IsInstance = true
|
||||
SynMemberFlags.IsDispatchSlot = false
|
||||
SynMemberFlags.IsOverrideOrExplicitImpl = true
|
||||
SynMemberFlags.IsFinal = false
|
||||
SynMemberFlags.GetterOrSetterIsCompilerGenerated = false
|
||||
SynMemberFlags.MemberKind = SynMemberKind.Member
|
||||
}
|
||||
|
||||
match binding with
|
||||
| SynBinding (acc, kind, inl, mut, attrs, doc, valData, headPat, ret, expr, range, debugPoint, trivia) ->
|
||||
let valData =
|
||||
match valData with
|
||||
| SynValData.SynValData (_, valInfo, _) -> SynValData.SynValData (Some memberFlags, valInfo, None)
|
||||
|
||||
let trivia =
|
||||
{ trivia with
|
||||
LeadingKeyword = SynLeadingKeyword.Member range0
|
||||
}
|
||||
|
||||
SynBinding (acc, kind, inl, mut, attrs, doc, valData, headPat, ret, expr, range, debugPoint, trivia)
|
@@ -1,50 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Xml
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynComponentInfo =
|
||||
let inline createLong (name : LongIdent) =
|
||||
SynComponentInfo.SynComponentInfo ([], None, [], name, PreXmlDoc.Empty, false, None, range0)
|
||||
|
||||
let inline create (name : Ident) = createLong [ name ]
|
||||
|
||||
let inline withDocString (doc : PreXmlDoc) (i : SynComponentInfo) : SynComponentInfo =
|
||||
match i with
|
||||
| SynComponentInfo.SynComponentInfo (attrs, typars, constraints, name, _, postfix, access, range) ->
|
||||
SynComponentInfo (attrs, typars, constraints, name, doc, postfix, access, range)
|
||||
|
||||
let inline setGenerics (typars : SynTyparDecls option) (i : SynComponentInfo) : SynComponentInfo =
|
||||
match i with
|
||||
| SynComponentInfo.SynComponentInfo (attrs, _, constraints, name, doc, postfix, access, range) ->
|
||||
SynComponentInfo (attrs, typars, constraints, name, doc, postfix, access, range)
|
||||
|
||||
let inline withGenerics (typars : SynTyparDecl list) (i : SynComponentInfo) : SynComponentInfo =
|
||||
let inner =
|
||||
if typars.IsEmpty then
|
||||
None
|
||||
else
|
||||
Some (SynTyparDecls.PostfixList (typars, [], range0))
|
||||
|
||||
setGenerics inner i
|
||||
|
||||
let inline setAccessibility (acc : SynAccess option) (i : SynComponentInfo) : SynComponentInfo =
|
||||
match i with
|
||||
| SynComponentInfo.SynComponentInfo (attrs, typars, constraints, name, doc, postfix, _, range) ->
|
||||
SynComponentInfo.SynComponentInfo (attrs, typars, constraints, name, doc, postfix, acc, range)
|
||||
|
||||
let inline withAccessibility (acc : SynAccess) (i : SynComponentInfo) : SynComponentInfo =
|
||||
setAccessibility (Some acc) i
|
||||
|
||||
let inline addAttributes (attrs : SynAttribute list) (i : SynComponentInfo) : SynComponentInfo =
|
||||
match i with
|
||||
| SynComponentInfo.SynComponentInfo (oldAttrs, typars, constraints, name, doc, postfix, acc, range) ->
|
||||
let attrs =
|
||||
{
|
||||
SynAttributeList.Attributes = attrs
|
||||
SynAttributeList.Range = range0
|
||||
}
|
||||
|
||||
SynComponentInfo.SynComponentInfo ((attrs :: oldAttrs), typars, constraints, name, doc, postfix, acc, range)
|
@@ -1,379 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.SyntaxTrivia
|
||||
open Myriad.Core
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<AutoOpen>]
|
||||
module internal SynExprExtensions =
|
||||
type SynExpr with
|
||||
static member CreateConst (s : string) : SynExpr =
|
||||
SynExpr.Const (SynConst.String (s, SynStringKind.Regular, range0), range0)
|
||||
|
||||
static member CreateConst () : SynExpr = SynExpr.Const (SynConst.Unit, range0)
|
||||
|
||||
static member CreateConst (b : bool) : SynExpr = SynExpr.Const (SynConst.Bool b, range0)
|
||||
|
||||
static member CreateConst (c : char) : SynExpr =
|
||||
// apparent Myriad bug: `IndexOf '?'` gets formatted as `IndexOf ?` which is clearly wrong
|
||||
SynExpr.CreateApp (SynExpr.Ident (Ident.Create "char"), SynExpr.CreateConst (int c))
|
||||
|> fun e -> SynExpr.Paren (e, range0, Some range0, range0)
|
||||
|
||||
static member CreateConst (i : int32) : SynExpr =
|
||||
SynExpr.Const (SynConst.Int32 i, range0)
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynExpr =
|
||||
|
||||
/// {f} {x}
|
||||
let applyFunction (f : SynExpr) (x : SynExpr) : SynExpr = SynExpr.CreateApp (f, x)
|
||||
|
||||
/// {f} {x}
|
||||
let inline applyTo (x : SynExpr) (f : SynExpr) : SynExpr = applyFunction f x
|
||||
|
||||
/// {expr} |> {func}
|
||||
let pipeThroughFunction (func : SynExpr) (expr : SynExpr) : SynExpr =
|
||||
SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.pipe, expr)
|
||||
|> applyTo func
|
||||
|
||||
/// if {cond} then {trueBranch} else {falseBranch}
|
||||
/// Note that this function puts the trueBranch last, for pipelining convenience:
|
||||
/// we assume that the `else` branch is more like an error case and is less interesting.
|
||||
let ifThenElse (cond : SynExpr) (falseBranch : SynExpr) (trueBranch : SynExpr) : SynExpr =
|
||||
SynExpr.IfThenElse (
|
||||
cond,
|
||||
trueBranch,
|
||||
Some falseBranch,
|
||||
DebugPointAtBinding.Yes range0,
|
||||
false,
|
||||
range0,
|
||||
{
|
||||
IfKeyword = range0
|
||||
IsElif = false
|
||||
ThenKeyword = range0
|
||||
ElseKeyword = Some range0
|
||||
IfToThenRange = range0
|
||||
}
|
||||
)
|
||||
|
||||
/// try {body} with | {exc} as exc -> {handler}
|
||||
let pipeThroughTryWith (exc : SynPat) (handler : SynExpr) (body : SynExpr) : SynExpr =
|
||||
let clause =
|
||||
SynMatchClause.create (SynPat.As (exc, SynPat.named "exc", range0)) handler
|
||||
|
||||
SynExpr.TryWith (
|
||||
body,
|
||||
[ clause ],
|
||||
range0,
|
||||
DebugPointAtTry.Yes range0,
|
||||
DebugPointAtWith.Yes range0,
|
||||
{
|
||||
TryKeyword = range0
|
||||
TryToWithRange = range0
|
||||
WithKeyword = range0
|
||||
WithToEndRange = range0
|
||||
}
|
||||
)
|
||||
|
||||
/// {a} = {b}
|
||||
let equals (a : SynExpr) (b : SynExpr) =
|
||||
SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.eq, a) |> applyTo b
|
||||
|
||||
/// {a} && {b}
|
||||
let booleanAnd (a : SynExpr) (b : SynExpr) =
|
||||
SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.booleanAnd, a)
|
||||
|> applyTo b
|
||||
|
||||
/// {a} || {b}
|
||||
let booleanOr (a : SynExpr) (b : SynExpr) =
|
||||
SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.booleanOr, a)
|
||||
|> applyTo b
|
||||
|
||||
/// {a} + {b}
|
||||
let plus (a : SynExpr) (b : SynExpr) =
|
||||
SynExpr.CreateAppInfix (
|
||||
SynExpr.CreateLongIdent (
|
||||
SynLongIdent.SynLongIdent (
|
||||
Ident.CreateLong "op_Addition",
|
||||
[],
|
||||
[ Some (IdentTrivia.OriginalNotation "+") ]
|
||||
)
|
||||
),
|
||||
a
|
||||
)
|
||||
|> applyTo b
|
||||
|
||||
/// {a} * {b}
|
||||
let times (a : SynExpr) (b : SynExpr) =
|
||||
SynExpr.CreateAppInfix (
|
||||
SynExpr.CreateLongIdent (
|
||||
SynLongIdent.SynLongIdent (
|
||||
Ident.CreateLong "op_Multiply",
|
||||
[],
|
||||
[ Some (IdentTrivia.OriginalNotation "*") ]
|
||||
)
|
||||
),
|
||||
a
|
||||
)
|
||||
|> applyTo b
|
||||
|
||||
let rec stripOptionalParen (expr : SynExpr) : SynExpr =
|
||||
match expr with
|
||||
| SynExpr.Paren (expr, _, _, _) -> stripOptionalParen expr
|
||||
| expr -> expr
|
||||
|
||||
let dotGet (field : string) (obj : SynExpr) : SynExpr =
|
||||
SynExpr.DotGet (
|
||||
obj,
|
||||
range0,
|
||||
SynLongIdent.SynLongIdent (id = [ Ident.create field ], dotRanges = [], trivia = [ None ]),
|
||||
range0
|
||||
)
|
||||
|
||||
/// {obj}.{meth} {arg}
|
||||
let callMethodArg (meth : string) (arg : SynExpr) (obj : SynExpr) : SynExpr = dotGet meth obj |> applyTo arg
|
||||
|
||||
/// {obj}.{meth}()
|
||||
let callMethod (meth : string) (obj : SynExpr) : SynExpr =
|
||||
callMethodArg meth (SynExpr.CreateConst ()) obj
|
||||
|
||||
let typeApp (types : SynType list) (operand : SynExpr) =
|
||||
SynExpr.TypeApp (operand, range0, types, List.replicate (types.Length - 1) range0, Some range0, range0, range0)
|
||||
|
||||
/// {obj}.{meth}<types,...>()
|
||||
let callGenericMethod (meth : SynLongIdent) (types : SynType list) (obj : SynExpr) : SynExpr =
|
||||
SynExpr.DotGet (obj, range0, meth, range0)
|
||||
|> typeApp types
|
||||
|> applyTo (SynExpr.CreateConst ())
|
||||
|
||||
/// {obj}.{meth}<ty>()
|
||||
let callGenericMethod' (meth : string) (ty : string) (obj : SynExpr) : SynExpr =
|
||||
callGenericMethod (SynLongIdent.createS meth) [ SynType.createLongIdent' [ ty ] ] obj
|
||||
|
||||
let inline index (property : SynExpr) (obj : SynExpr) : SynExpr =
|
||||
SynExpr.DotIndexedGet (obj, property, range0, range0)
|
||||
|
||||
let inline arrayIndexRange (start : SynExpr option) (endRange : SynExpr option) (arr : SynExpr) : SynExpr =
|
||||
SynExpr.DotIndexedGet (
|
||||
arr,
|
||||
(SynExpr.IndexRange (start, range0, endRange, range0, range0, range0)),
|
||||
range0,
|
||||
range0
|
||||
)
|
||||
|
||||
let inline paren (e : SynExpr) : SynExpr =
|
||||
SynExpr.Paren (e, range0, Some range0, range0)
|
||||
|
||||
/// (fun {varName} -> {body})
|
||||
let createLambda (varName : string) (body : SynExpr) : SynExpr =
|
||||
let parsedDataPat = [ SynPat.named varName ]
|
||||
|
||||
SynExpr.Lambda (
|
||||
false,
|
||||
false,
|
||||
SynSimplePats.Create [ SynSimplePat.CreateId (Ident.Create varName) ],
|
||||
body,
|
||||
Some (parsedDataPat, body),
|
||||
range0,
|
||||
{
|
||||
ArrowRange = Some range0
|
||||
}
|
||||
)
|
||||
|> paren
|
||||
|
||||
let createThunk (body : SynExpr) : SynExpr =
|
||||
SynExpr.Lambda (
|
||||
false,
|
||||
false,
|
||||
SynSimplePats.Create [],
|
||||
body,
|
||||
Some ([ SynPat.unit ], body),
|
||||
range0,
|
||||
{
|
||||
ArrowRange = Some range0
|
||||
}
|
||||
)
|
||||
|> paren
|
||||
|
||||
let inline createIdent (s : string) : SynExpr = SynExpr.Ident (Ident (s, range0))
|
||||
|
||||
let inline createIdent' (i : Ident) : SynExpr = SynExpr.Ident i
|
||||
|
||||
let inline createLongIdent' (ident : Ident list) : SynExpr =
|
||||
SynExpr.LongIdent (false, SynLongIdent.create ident, None, range0)
|
||||
|
||||
let inline createLongIdent (ident : string list) : SynExpr =
|
||||
createLongIdent' (ident |> List.map Ident.create)
|
||||
|
||||
let tupleNoParen (args : SynExpr list) : SynExpr =
|
||||
SynExpr.Tuple (false, args, List.replicate (args.Length - 1) range0, range0)
|
||||
|
||||
let inline tuple (args : SynExpr list) = args |> tupleNoParen |> paren
|
||||
|
||||
/// {body} |> fun a -> Async.StartAsTask (a, ?cancellationToken=ct)
|
||||
let startAsTask (ct : Ident) (body : SynExpr) =
|
||||
let lambda =
|
||||
[
|
||||
createIdent "a"
|
||||
equals
|
||||
(SynExpr.LongIdent (true, SynLongIdent.createS "cancellationToken", None, range0))
|
||||
(createIdent' ct)
|
||||
]
|
||||
|> tuple
|
||||
|> applyFunction (createLongIdent [ "Async" ; "StartAsTask" ])
|
||||
|> createLambda "a"
|
||||
|
||||
pipeThroughFunction lambda body
|
||||
|
||||
let inline createForEach (pat : SynPat) (enumExpr : SynExpr) (body : SynExpr) : SynExpr =
|
||||
SynExpr.ForEach (
|
||||
DebugPointAtFor.No,
|
||||
DebugPointAtInOrTo.No,
|
||||
SeqExprOnly.SeqExprOnly false,
|
||||
true,
|
||||
pat,
|
||||
enumExpr,
|
||||
body,
|
||||
range0
|
||||
)
|
||||
|
||||
let inline createLet (bindings : SynBinding list) (body : SynExpr) : SynExpr =
|
||||
SynExpr.LetOrUse (false, false, bindings, body, range0, SynExprLetOrUseTrivia.empty)
|
||||
|
||||
let inline createDo (body : SynExpr) : SynExpr = SynExpr.Do (body, range0)
|
||||
|
||||
let inline createMatch (matchOn : SynExpr) (cases : SynMatchClause list) : SynExpr =
|
||||
SynExpr.Match (
|
||||
DebugPointAtBinding.Yes range0,
|
||||
matchOn,
|
||||
cases,
|
||||
range0,
|
||||
{
|
||||
MatchKeyword = range0
|
||||
WithKeyword = range0
|
||||
}
|
||||
)
|
||||
|
||||
let typeAnnotate (ty : SynType) (expr : SynExpr) : SynExpr = SynExpr.Typed (expr, ty, range0)
|
||||
|
||||
let inline createNew (ty : SynType) (args : SynExpr) : SynExpr =
|
||||
SynExpr.New (false, ty, paren args, range0)
|
||||
|
||||
let inline createWhile (cond : SynExpr) (body : SynExpr) : SynExpr =
|
||||
SynExpr.While (DebugPointAtWhile.Yes range0, cond, body, range0)
|
||||
|
||||
let inline createNull () : SynExpr = SynExpr.Null range0
|
||||
|
||||
let reraise : SynExpr = createIdent "reraise" |> applyTo (SynExpr.CreateConst ())
|
||||
|
||||
let sequential (exprs : SynExpr list) : SynExpr =
|
||||
exprs
|
||||
|> List.reduce (fun a b -> SynExpr.Sequential (DebugPointAtSequential.SuppressNeither, false, a, b, range0))
|
||||
|
||||
let listLiteral (elts : SynExpr list) : SynExpr =
|
||||
SynExpr.ArrayOrListComputed (false, sequential elts, range0)
|
||||
|
||||
let arrayLiteral (elts : SynExpr list) : SynExpr =
|
||||
SynExpr.ArrayOrListComputed (true, sequential elts, range0)
|
||||
|
||||
/// {compExpr} { {lets} ; return {ret} }
|
||||
let createCompExpr (compExpr : string) (retBody : SynExpr) (lets : CompExprBinding list) : SynExpr =
|
||||
let retStatement = SynExpr.YieldOrReturn ((false, true), retBody, range0)
|
||||
|
||||
let contents : SynExpr =
|
||||
(retStatement, List.rev lets)
|
||||
||> List.fold (fun state binding ->
|
||||
match binding with
|
||||
| LetBang (lhs, rhs) ->
|
||||
SynExpr.LetOrUseBang (
|
||||
DebugPointAtBinding.Yes range0,
|
||||
false,
|
||||
true,
|
||||
SynPat.named lhs,
|
||||
rhs,
|
||||
[],
|
||||
state,
|
||||
range0,
|
||||
{
|
||||
EqualsRange = Some range0
|
||||
}
|
||||
)
|
||||
| Let (lhs, rhs) -> createLet [ SynBinding.basic [ Ident.create lhs ] [] rhs ] state
|
||||
| Use (lhs, rhs) ->
|
||||
SynExpr.LetOrUse (
|
||||
false,
|
||||
true,
|
||||
[ SynBinding.basic [ Ident.create lhs ] [] rhs ],
|
||||
state,
|
||||
range0,
|
||||
{
|
||||
SynExprLetOrUseTrivia.InKeyword = None
|
||||
}
|
||||
)
|
||||
| Do body -> sequential [ SynExpr.Do (body, range0) ; state ]
|
||||
)
|
||||
|
||||
applyFunction (createIdent compExpr) (SynExpr.ComputationExpr (false, contents, range0))
|
||||
|
||||
/// {expr} |> Async.AwaitTask
|
||||
let awaitTask (expr : SynExpr) : SynExpr =
|
||||
expr |> pipeThroughFunction (createLongIdent [ "Async" ; "AwaitTask" ])
|
||||
|
||||
/// {ident}.ToString ()
|
||||
/// with special casing for some types like DateTime
|
||||
let toString (ty : SynType) (ident : SynExpr) =
|
||||
match ty with
|
||||
| DateOnly -> ident |> callMethodArg "ToString" (SynExpr.CreateConst "yyyy-MM-dd")
|
||||
| DateTime -> ident |> callMethodArg "ToString" (SynExpr.CreateConst "yyyy-MM-ddTHH:mm:ss")
|
||||
| _ -> callMethod "ToString" ident
|
||||
|
||||
let upcast' (ty : SynType) (e : SynExpr) = SynExpr.Upcast (e, ty, range0)
|
||||
|
||||
/// {ident} - {rhs}
|
||||
let minus (ident : SynLongIdent) (rhs : SynExpr) : SynExpr =
|
||||
SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.sub, SynExpr.CreateLongIdent ident)
|
||||
|> applyTo rhs
|
||||
|
||||
/// {ident} - {n}
|
||||
let minusN (ident : SynLongIdent) (n : int) : SynExpr = minus ident (SynExpr.CreateConst n)
|
||||
|
||||
/// {y} > {x}
|
||||
let greaterThan (x : SynExpr) (y : SynExpr) : SynExpr =
|
||||
SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.gt, y) |> applyTo x
|
||||
|
||||
/// {y} < {x}
|
||||
let lessThan (x : SynExpr) (y : SynExpr) : SynExpr =
|
||||
SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.lt, y) |> applyTo x
|
||||
|
||||
/// {y} >= {x}
|
||||
let greaterThanOrEqual (x : SynExpr) (y : SynExpr) : SynExpr =
|
||||
SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.geq, y)
|
||||
|> applyTo x
|
||||
|
||||
/// {y} <= {x}
|
||||
let lessThanOrEqual (x : SynExpr) (y : SynExpr) : SynExpr =
|
||||
SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.leq, y)
|
||||
|> applyTo x
|
||||
|
||||
/// {x} :: {y}
|
||||
let listCons (x : SynExpr) (y : SynExpr) : SynExpr =
|
||||
SynExpr.CreateAppInfix (
|
||||
SynExpr.LongIdent (
|
||||
false,
|
||||
SynLongIdent.SynLongIdent (
|
||||
[ Ident.create "op_ColonColon" ],
|
||||
[],
|
||||
[ Some (IdentTrivia.OriginalNotation "::") ]
|
||||
),
|
||||
None,
|
||||
range0
|
||||
),
|
||||
tupleNoParen [ x ; y ]
|
||||
)
|
||||
|> paren
|
||||
|
||||
let assign (lhs : SynLongIdent) (rhs : SynExpr) : SynExpr = SynExpr.LongIdentSet (lhs, rhs, range0)
|
||||
|
||||
let assignIndex (lhs : SynExpr) (index : SynExpr) (rhs : SynExpr) : SynExpr =
|
||||
SynExpr.DotIndexedSet (lhs, index, rhs, range0, range0, range0)
|
@@ -1,10 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.SyntaxTrivia
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynExprLetOrUseTrivia =
|
||||
let empty : SynExprLetOrUseTrivia =
|
||||
{
|
||||
InKeyword = None
|
||||
}
|
@@ -1,76 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Text.Range
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.SyntaxTrivia
|
||||
open Fantomas.FCS.Xml
|
||||
|
||||
/// The data needed to reconstitute a single piece of data within a union field, or a single record field.
|
||||
/// This is generic on whether the field is identified. For example, in `type Foo = Blah of int`, the `int`
|
||||
/// field is not identified; whereas in `type Foo = Blah of baz : int`, it is identified.
|
||||
type SynFieldData<'Ident> =
|
||||
{
|
||||
/// Attributes on this field. I think you can only get these if this is a *record* field.
|
||||
Attrs : SynAttribute list
|
||||
/// The identifier of this field (see docstring for SynFieldData).
|
||||
Ident : 'Ident
|
||||
/// The type of the data contained in this field. For example, `type Foo = { Blah : int }`
|
||||
/// has this being `int`.
|
||||
Type : SynType
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynField =
|
||||
/// Get the useful information out of a SynField.
|
||||
let extract (SynField (attrs, _, id, fieldType, _, _, _, _, _)) : SynFieldData<Ident option> =
|
||||
{
|
||||
Attrs = attrs |> List.collect (fun l -> l.Attributes)
|
||||
Ident = id
|
||||
Type = fieldType
|
||||
}
|
||||
|
||||
let mapIdent<'a, 'b> (f : 'a -> 'b) (x : SynFieldData<'a>) : SynFieldData<'b> =
|
||||
let ident = f x.Ident
|
||||
|
||||
{
|
||||
Attrs = x.Attrs
|
||||
Ident = ident
|
||||
Type = x.Type
|
||||
}
|
||||
|
||||
/// Throws if the field has no identifier.
|
||||
let extractWithIdent (f : SynField) : SynFieldData<Ident> =
|
||||
f
|
||||
|> extract
|
||||
|> mapIdent (fun ident ->
|
||||
match ident with
|
||||
| None -> failwith "expected field identifier to have a value, but it did not"
|
||||
| Some i -> i
|
||||
)
|
||||
|
||||
let make (data : SynFieldData<Ident option>) : SynField =
|
||||
let attrs : SynAttributeList list =
|
||||
data.Attrs
|
||||
|> List.map (fun l ->
|
||||
{
|
||||
Attributes = [ l ]
|
||||
Range = range0
|
||||
}
|
||||
)
|
||||
|
||||
SynField.SynField (
|
||||
attrs,
|
||||
false,
|
||||
data.Ident,
|
||||
data.Type,
|
||||
false,
|
||||
PreXmlDoc.Empty,
|
||||
None,
|
||||
range0,
|
||||
SynFieldTrivia.Zero
|
||||
)
|
||||
|
||||
let withDocString (doc : PreXmlDoc) (f : SynField) : SynField =
|
||||
match f with
|
||||
| SynField (attributes, isStatic, idOpt, fieldType, isMutable, _, accessibility, range, trivia) ->
|
||||
SynField (attributes, isStatic, idOpt, fieldType, isMutable, doc, accessibility, range, trivia)
|
@@ -1,10 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynIdent =
|
||||
let inline createI (i : Ident) : SynIdent = SynIdent.SynIdent (i, None)
|
||||
|
||||
let inline createS (i : string) : SynIdent =
|
||||
SynIdent.SynIdent (Ident.create i, None)
|
@@ -1,134 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.SyntaxTrivia
|
||||
open Fantomas.FCS.Text.Range
|
||||
open Fantomas.FCS.Syntax
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynLongIdent =
|
||||
|
||||
let geq =
|
||||
SynLongIdent.SynLongIdent (
|
||||
[ Ident.create "op_GreaterThanOrEqual" ],
|
||||
[],
|
||||
[ Some (IdentTrivia.OriginalNotation ">=") ]
|
||||
)
|
||||
|
||||
let leq =
|
||||
SynLongIdent.SynLongIdent (
|
||||
[ Ident.create "op_LessThanOrEqual" ],
|
||||
[],
|
||||
[ Some (IdentTrivia.OriginalNotation "<=") ]
|
||||
)
|
||||
|
||||
let gt =
|
||||
SynLongIdent.SynLongIdent ([ Ident.create "op_GreaterThan" ], [], [ Some (IdentTrivia.OriginalNotation ">") ])
|
||||
|
||||
let lt =
|
||||
SynLongIdent.SynLongIdent ([ Ident.create "op_LessThan" ], [], [ Some (IdentTrivia.OriginalNotation "<") ])
|
||||
|
||||
let sub =
|
||||
SynLongIdent.SynLongIdent ([ Ident.create "op_Subtraction" ], [], [ Some (IdentTrivia.OriginalNotation "-") ])
|
||||
|
||||
let eq =
|
||||
SynLongIdent.SynLongIdent ([ Ident.create "op_Equality" ], [], [ Some (IdentTrivia.OriginalNotation "=") ])
|
||||
|
||||
let booleanAnd =
|
||||
SynLongIdent.SynLongIdent ([ Ident.create "op_BooleanAnd" ], [], [ Some (IdentTrivia.OriginalNotation "&&") ])
|
||||
|
||||
let booleanOr =
|
||||
SynLongIdent.SynLongIdent ([ Ident.create "op_BooleanOr" ], [], [ Some (IdentTrivia.OriginalNotation "||") ])
|
||||
|
||||
let pipe =
|
||||
SynLongIdent.SynLongIdent ([ Ident.create "op_PipeRight" ], [], [ Some (IdentTrivia.OriginalNotation "|>") ])
|
||||
|
||||
let toString (sli : SynLongIdent) : string =
|
||||
sli.LongIdent |> List.map _.idText |> String.concat "."
|
||||
|
||||
let create (ident : LongIdent) : SynLongIdent =
|
||||
let commas =
|
||||
match ident with
|
||||
| [] -> []
|
||||
| _ :: commas -> commas |> List.map (fun _ -> range0)
|
||||
|
||||
SynLongIdent.SynLongIdent (ident, commas, List.replicate ident.Length None)
|
||||
|
||||
let inline createI (i : Ident) : SynLongIdent = create [ i ]
|
||||
|
||||
let inline createS (s : string) : SynLongIdent = createI (Ident (s, range0))
|
||||
|
||||
let inline createS' (s : string list) : SynLongIdent =
|
||||
create (s |> List.map (fun i -> Ident (i, range0)))
|
||||
|
||||
let isUnit (ident : SynLongIdent) : bool =
|
||||
match ident.LongIdent with
|
||||
| [ i ] when System.String.Equals (i.idText, "unit", System.StringComparison.OrdinalIgnoreCase) -> true
|
||||
| _ -> false
|
||||
|
||||
let isList (ident : SynLongIdent) : bool =
|
||||
match ident.LongIdent with
|
||||
| [ i ] when System.String.Equals (i.idText, "list", System.StringComparison.OrdinalIgnoreCase) -> true
|
||||
// TODO: consider FSharpList or whatever it is
|
||||
| _ -> false
|
||||
|
||||
let isArray (ident : SynLongIdent) : bool =
|
||||
match ident.LongIdent with
|
||||
| [ i ] when
|
||||
System.String.Equals (i.idText, "array", System.StringComparison.OrdinalIgnoreCase)
|
||||
|| System.String.Equals (i.idText, "[]", System.StringComparison.Ordinal)
|
||||
->
|
||||
true
|
||||
| _ -> false
|
||||
|
||||
let isOption (ident : SynLongIdent) : bool =
|
||||
match ident.LongIdent with
|
||||
| [ i ] when System.String.Equals (i.idText, "option", System.StringComparison.OrdinalIgnoreCase) -> true
|
||||
// TODO: consider Microsoft.FSharp.Option or whatever it is
|
||||
| _ -> false
|
||||
|
||||
let isChoice (ident : SynLongIdent) : bool =
|
||||
match ident.LongIdent with
|
||||
| [ i ] when System.String.Equals (i.idText, "Choice", System.StringComparison.Ordinal) -> true
|
||||
// TODO: consider Microsoft.FSharp.Choice or whatever it is
|
||||
| _ -> false
|
||||
|
||||
let isNullable (ident : SynLongIdent) : bool =
|
||||
match ident.LongIdent |> List.map _.idText with
|
||||
| [ "System" ; "Nullable" ]
|
||||
| [ "Nullable" ] -> true
|
||||
| _ -> false
|
||||
|
||||
let isResponse (ident : SynLongIdent) : bool =
|
||||
match ident.LongIdent |> List.map _.idText with
|
||||
| [ "Response" ]
|
||||
| [ "RestEase" ; "Response" ] -> true
|
||||
| _ -> false
|
||||
|
||||
let isMap (ident : SynLongIdent) : bool =
|
||||
match ident.LongIdent |> List.map _.idText with
|
||||
| [ "Map" ] -> true
|
||||
| _ -> false
|
||||
|
||||
let isReadOnlyDictionary (ident : SynLongIdent) : bool =
|
||||
match ident.LongIdent |> List.map _.idText with
|
||||
| [ "IReadOnlyDictionary" ]
|
||||
| [ "Generic" ; "IReadOnlyDictionary" ]
|
||||
| [ "Collections" ; "Generic" ; "IReadOnlyDictionary" ]
|
||||
| [ "System" ; "Collections" ; "Generic" ; "IReadOnlyDictionary" ] -> true
|
||||
| _ -> false
|
||||
|
||||
let isDictionary (ident : SynLongIdent) : bool =
|
||||
match ident.LongIdent |> List.map _.idText with
|
||||
| [ "Dictionary" ]
|
||||
| [ "Generic" ; "Dictionary" ]
|
||||
| [ "Collections" ; "Generic" ; "Dictionary" ]
|
||||
| [ "System" ; "Collections" ; "Generic" ; "Dictionary" ] -> true
|
||||
| _ -> false
|
||||
|
||||
let isIDictionary (ident : SynLongIdent) : bool =
|
||||
match ident.LongIdent |> List.map _.idText with
|
||||
| [ "IDictionary" ]
|
||||
| [ "Generic" ; "IDictionary" ]
|
||||
| [ "Collections" ; "Generic" ; "IDictionary" ]
|
||||
| [ "System" ; "Collections" ; "Generic" ; "IDictionary" ] -> true
|
||||
| _ -> false
|
@@ -1,24 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynMatchClause =
|
||||
let create (lhs : SynPat) (rhs : SynExpr) : SynMatchClause =
|
||||
SynMatchClause.SynMatchClause (
|
||||
lhs,
|
||||
None,
|
||||
rhs,
|
||||
range0,
|
||||
DebugPointAtTarget.Yes,
|
||||
{
|
||||
ArrowRange = Some range0
|
||||
BarRange = Some range0
|
||||
}
|
||||
)
|
||||
|
||||
let withWhere (where : SynExpr) (m : SynMatchClause) : SynMatchClause =
|
||||
match m with
|
||||
| SynMatchClause (synPat, _, resultExpr, range, debugPointAtTarget, synMatchClauseTrivia) ->
|
||||
SynMatchClause (synPat, Some where, resultExpr, range, debugPointAtTarget, synMatchClauseTrivia)
|
@@ -1,71 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.SyntaxTrivia
|
||||
open Fantomas.FCS.Text.Range
|
||||
open Fantomas.FCS.Xml
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynMemberDefn =
|
||||
let private interfaceMemberSlotFlags =
|
||||
{
|
||||
SynMemberFlags.IsInstance = true
|
||||
SynMemberFlags.IsDispatchSlot = true
|
||||
SynMemberFlags.IsOverrideOrExplicitImpl = false
|
||||
SynMemberFlags.IsFinal = false
|
||||
SynMemberFlags.GetterOrSetterIsCompilerGenerated = false
|
||||
SynMemberFlags.MemberKind = SynMemberKind.Member
|
||||
}
|
||||
|
||||
let abstractMember
|
||||
(attrs : SynAttribute list)
|
||||
(ident : SynIdent)
|
||||
(typars : SynTyparDecls option)
|
||||
(arity : SynValInfo)
|
||||
(xmlDoc : PreXmlDoc)
|
||||
(returnType : SynType)
|
||||
: SynMemberDefn
|
||||
=
|
||||
let slot =
|
||||
SynValSig.SynValSig (
|
||||
attrs
|
||||
|> List.map (fun attr ->
|
||||
{
|
||||
Attributes = [ attr ]
|
||||
Range = range0
|
||||
}
|
||||
),
|
||||
ident,
|
||||
SynValTyparDecls.SynValTyparDecls (typars, true),
|
||||
returnType,
|
||||
arity,
|
||||
false,
|
||||
false,
|
||||
xmlDoc,
|
||||
None,
|
||||
None,
|
||||
range0,
|
||||
{
|
||||
EqualsRange = None
|
||||
WithKeyword = None
|
||||
InlineKeyword = None
|
||||
LeadingKeyword = SynLeadingKeyword.Abstract range0
|
||||
}
|
||||
)
|
||||
|
||||
SynMemberDefn.AbstractSlot (
|
||||
slot,
|
||||
interfaceMemberSlotFlags,
|
||||
range0,
|
||||
{
|
||||
GetSetKeywords = None
|
||||
}
|
||||
)
|
||||
|
||||
let staticMember (binding : SynBinding) : SynMemberDefn =
|
||||
let binding = SynBinding.makeStaticMember binding
|
||||
SynMemberDefn.Member (binding, range0)
|
||||
|
||||
let memberImplementation (binding : SynBinding) : SynMemberDefn =
|
||||
let binding = SynBinding.makeInstanceMember binding
|
||||
SynMemberDefn.Member (binding, range0)
|
@@ -1,30 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.SyntaxTrivia
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynModuleDecl =
|
||||
|
||||
let inline openAny (ident : SynOpenDeclTarget) : SynModuleDecl = SynModuleDecl.Open (ident, range0)
|
||||
|
||||
let inline createLets (bindings : SynBinding list) : SynModuleDecl =
|
||||
SynModuleDecl.Let (false, bindings, range0)
|
||||
|
||||
let inline createLet (binding : SynBinding) : SynModuleDecl = createLets [ binding ]
|
||||
|
||||
let inline createTypes (tys : SynTypeDefn list) : SynModuleDecl = SynModuleDecl.Types (tys, range0)
|
||||
|
||||
let nestedModule (info : SynComponentInfo) (decls : SynModuleDecl list) : SynModuleDecl =
|
||||
SynModuleDecl.NestedModule (
|
||||
info,
|
||||
false,
|
||||
decls,
|
||||
false,
|
||||
range0,
|
||||
{
|
||||
ModuleKeyword = Some range0
|
||||
EqualsRange = Some range0
|
||||
}
|
||||
)
|
@@ -1,24 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.SyntaxTrivia
|
||||
open Fantomas.FCS.Xml
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynModuleOrNamespace =
|
||||
|
||||
let createNamespace (name : LongIdent) (decls : SynModuleDecl list) =
|
||||
SynModuleOrNamespace.SynModuleOrNamespace (
|
||||
name,
|
||||
false,
|
||||
SynModuleOrNamespaceKind.DeclaredNamespace,
|
||||
decls,
|
||||
PreXmlDoc.Empty,
|
||||
[],
|
||||
None,
|
||||
range0,
|
||||
{
|
||||
LeadingKeyword = SynModuleOrNamespaceLeadingKeyword.Namespace range0
|
||||
}
|
||||
)
|
@@ -1,54 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynPat =
|
||||
let inline paren (pat : SynPat) : SynPat = SynPat.Paren (pat, range0)
|
||||
|
||||
let anon : SynPat = SynPat.Wild range0
|
||||
|
||||
let inline annotateTypeNoParen (ty : SynType) (pat : SynPat) = SynPat.Typed (pat, ty, range0)
|
||||
|
||||
let inline annotateType (ty : SynType) (pat : SynPat) = paren (annotateTypeNoParen ty pat)
|
||||
|
||||
let inline named (s : string) : SynPat =
|
||||
SynPat.Named (SynIdent.SynIdent (Ident (s, range0), None), false, None, range0)
|
||||
|
||||
let inline namedI (i : Ident) : SynPat =
|
||||
SynPat.Named (SynIdent.SynIdent (i, None), false, None, range0)
|
||||
|
||||
let inline identWithArgs (i : LongIdent) (args : SynArgPats) : SynPat =
|
||||
SynPat.LongIdent (SynLongIdent.create i, None, None, args, None, range0)
|
||||
|
||||
let inline nameWithArgs (i : string) (args : SynPat list) : SynPat =
|
||||
identWithArgs [ Ident.create i ] (SynArgPats.create args)
|
||||
|
||||
let inline tupleNoParen (elements : SynPat list) : SynPat =
|
||||
match elements with
|
||||
| [] -> failwith "Can't tuple no elements in a pattern"
|
||||
| [ p ] -> p
|
||||
| elements -> SynPat.Tuple (false, elements, List.replicate (elements.Length - 1) range0, range0)
|
||||
|
||||
let inline tuple (elements : SynPat list) : SynPat = tupleNoParen elements |> paren
|
||||
|
||||
let inline createConst (c : SynConst) = SynPat.Const (c, range0)
|
||||
|
||||
let unit = createConst SynConst.Unit
|
||||
|
||||
let createNull = SynPat.Null range0
|
||||
|
||||
let emptyList = SynPat.ArrayOrList (false, [], range0)
|
||||
|
||||
let listCons (lhs : SynPat) (rhs : SynPat) =
|
||||
SynPat.ListCons (
|
||||
lhs,
|
||||
rhs,
|
||||
range0,
|
||||
{
|
||||
ColonColonRange = range0
|
||||
}
|
||||
)
|
||||
|
||||
let emptyArray = SynPat.ArrayOrList (true, [], range0)
|
@@ -1,539 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open System
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<AutoOpen>]
|
||||
module internal SynTypePatterns =
|
||||
let (|OptionType|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.App (SynType.LongIdent ident, _, [ innerType ], _, _, _, _) when SynLongIdent.isOption ident ->
|
||||
Some innerType
|
||||
| _ -> None
|
||||
|
||||
let (|ChoiceType|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.App (SynType.LongIdent ident, _, inner, _, _, _, _) when SynLongIdent.isChoice ident -> Some inner
|
||||
| _ -> None
|
||||
|
||||
let (|NullableType|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.App (SynType.LongIdent ident, _, [ innerType ], _, _, _, _) when SynLongIdent.isNullable ident ->
|
||||
Some innerType
|
||||
| _ -> None
|
||||
|
||||
let (|UnitType|_|) (fieldType : SynType) : unit option =
|
||||
match fieldType with
|
||||
| SynType.LongIdent ident when SynLongIdent.isUnit ident -> Some ()
|
||||
| _ -> None
|
||||
|
||||
let (|ListType|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.App (SynType.LongIdent ident, _, [ innerType ], _, _, _, _) when SynLongIdent.isList ident ->
|
||||
Some innerType
|
||||
| _ -> None
|
||||
|
||||
let (|ArrayType|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.App (SynType.LongIdent ident, _, [ innerType ], _, _, _, _) when SynLongIdent.isArray ident ->
|
||||
Some innerType
|
||||
| SynType.Array (1, innerType, _) -> Some innerType
|
||||
| _ -> None
|
||||
|
||||
let (|RestEaseResponseType|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.App (SynType.LongIdent ident, _, [ innerType ], _, _, _, _) when SynLongIdent.isResponse ident ->
|
||||
Some innerType
|
||||
| _ -> None
|
||||
|
||||
let (|DictionaryType|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.App (SynType.LongIdent ident, _, [ key ; value ], _, _, _, _) when SynLongIdent.isDictionary ident ->
|
||||
Some (key, value)
|
||||
| _ -> None
|
||||
|
||||
let (|IDictionaryType|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.App (SynType.LongIdent ident, _, [ key ; value ], _, _, _, _) when SynLongIdent.isIDictionary ident ->
|
||||
Some (key, value)
|
||||
| _ -> None
|
||||
|
||||
let (|IReadOnlyDictionaryType|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.App (SynType.LongIdent ident, _, [ key ; value ], _, _, _, _) when
|
||||
SynLongIdent.isReadOnlyDictionary ident
|
||||
->
|
||||
Some (key, value)
|
||||
| _ -> None
|
||||
|
||||
let (|MapType|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.App (SynType.LongIdent ident, _, [ key ; value ], _, _, _, _) when SynLongIdent.isMap ident ->
|
||||
Some (key, value)
|
||||
| _ -> None
|
||||
|
||||
let (|BigInt|_|) (fieldType : SynType) : unit option =
|
||||
match fieldType with
|
||||
| SynType.LongIdent ident ->
|
||||
match ident.LongIdent |> List.map _.idText with
|
||||
| [ "bigint" ]
|
||||
| [ "BigInteger" ]
|
||||
| [ "Numerics" ; "BigInteger" ]
|
||||
| [ "System" ; "Numerics" ; "BigInteger" ] -> Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
/// Returns the type, qualified as in e.g. `System.Boolean`.
|
||||
let (|PrimitiveType|_|) (fieldType : SynType) : LongIdent option =
|
||||
match fieldType with
|
||||
| SynType.LongIdent ident ->
|
||||
match ident.LongIdent with
|
||||
| [ i ] -> Primitives.qualifyType i.idText
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|String|_|) (fieldType : SynType) : unit option =
|
||||
match fieldType with
|
||||
| SynType.LongIdent ident ->
|
||||
match ident.LongIdent with
|
||||
| [ i ] ->
|
||||
[ "string" ]
|
||||
|> List.tryFind (fun s -> s = i.idText)
|
||||
|> Option.map ignore<string>
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|Byte|_|) (fieldType : SynType) : unit option =
|
||||
match fieldType with
|
||||
| SynType.LongIdent ident ->
|
||||
match ident.LongIdent with
|
||||
| [ i ] -> [ "byte" ] |> List.tryFind (fun s -> s = i.idText) |> Option.map ignore<string>
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|Guid|_|) (fieldType : SynType) : unit option =
|
||||
match fieldType with
|
||||
| SynType.LongIdent ident ->
|
||||
match ident.LongIdent |> List.map (fun i -> i.idText) with
|
||||
| [ "System" ; "Guid" ]
|
||||
| [ "Guid" ] -> Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|HttpResponseMessage|_|) (fieldType : SynType) : unit option =
|
||||
match fieldType with
|
||||
| SynType.LongIdent ident ->
|
||||
match ident.LongIdent |> List.map (fun i -> i.idText) with
|
||||
| [ "System" ; "Net" ; "Http" ; "HttpResponseMessage" ]
|
||||
| [ "Net" ; "Http" ; "HttpResponseMessage" ]
|
||||
| [ "Http" ; "HttpResponseMessage" ]
|
||||
| [ "HttpResponseMessage" ] -> Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|HttpContent|_|) (fieldType : SynType) : unit option =
|
||||
match fieldType with
|
||||
| SynType.LongIdent ident ->
|
||||
match ident.LongIdent |> List.map (fun i -> i.idText) with
|
||||
| [ "System" ; "Net" ; "Http" ; "HttpContent" ]
|
||||
| [ "Net" ; "Http" ; "HttpContent" ]
|
||||
| [ "Http" ; "HttpContent" ]
|
||||
| [ "HttpContent" ] -> Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|Stream|_|) (fieldType : SynType) : unit option =
|
||||
match fieldType with
|
||||
| SynType.LongIdent ident ->
|
||||
match ident.LongIdent |> List.map (fun i -> i.idText) with
|
||||
| [ "System" ; "IO" ; "Stream" ]
|
||||
| [ "IO" ; "Stream" ]
|
||||
| [ "Stream" ] -> Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|NumberType|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.LongIdent ident ->
|
||||
match ident.LongIdent with
|
||||
| [ i ] ->
|
||||
// We won't bother with the case that the user has done e.g. `Single` (relying on `System` being open).
|
||||
match Primitives.qualifyType i.idText with
|
||||
| Some qualified ->
|
||||
match i.idText with
|
||||
| "char"
|
||||
| "string" -> None
|
||||
| _ -> Some qualified
|
||||
| None -> None
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
/// Returns the name of the measure, and the outer type.
|
||||
let (|Measure|_|) (fieldType : SynType) : (Ident * LongIdent) option =
|
||||
match fieldType with
|
||||
| SynType.App (NumberType outer,
|
||||
_,
|
||||
[ SynType.LongIdent (SynLongIdent.SynLongIdent ([ ident ], _, _)) ],
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_) -> Some (ident, outer)
|
||||
| _ -> None
|
||||
|
||||
let (|JsonNode|_|) (fieldType : SynType) : unit option =
|
||||
match fieldType with
|
||||
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
|
||||
match ident |> List.map (fun i -> i.idText) with
|
||||
| [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ]
|
||||
| [ "Text" ; "Json" ; "Nodes" ; "JsonNode" ]
|
||||
| [ "Json" ; "Nodes" ; "JsonNode" ]
|
||||
| [ "Nodes" ; "JsonNode" ]
|
||||
| [ "JsonNode" ] -> Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|Unit|_|) (fieldType : SynType) : unit option =
|
||||
match fieldType with
|
||||
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
|
||||
match ident |> List.map (fun i -> i.idText.ToLowerInvariant ()) with
|
||||
| [ "microsoft" ; "fsharp" ; "core" ; "unit" ]
|
||||
| [ "fsharp" ; "core" ; "unit" ]
|
||||
| [ "core" ; "unit" ]
|
||||
| [ "unit" ] -> Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|DateOnly|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
|
||||
match ident |> List.map (fun i -> i.idText) with
|
||||
| [ "System" ; "DateOnly" ]
|
||||
| [ "DateOnly" ] -> Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|DateTime|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
|
||||
match ident |> List.map (fun i -> i.idText) with
|
||||
| [ "System" ; "DateTime" ]
|
||||
| [ "DateTime" ] -> Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|DateTimeOffset|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
|
||||
match ident |> List.map (fun i -> i.idText) with
|
||||
| [ "System" ; "DateTimeOffset" ]
|
||||
| [ "DateTimeOffset" ] -> Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|Uri|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
|
||||
match ident |> List.map (fun i -> i.idText) with
|
||||
| [ "System" ; "Uri" ]
|
||||
| [ "Uri" ] -> Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|Task|_|) (fieldType : SynType) : SynType option =
|
||||
match fieldType with
|
||||
| SynType.App (SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)), _, args, _, _, _, _) ->
|
||||
match ident |> List.map (fun i -> i.idText) with
|
||||
| [ "Task" ]
|
||||
| [ "Tasks" ; "Task" ]
|
||||
| [ "Threading" ; "Tasks" ; "Task" ]
|
||||
| [ "System" ; "Threading" ; "Tasks" ; "Task" ] ->
|
||||
match args with
|
||||
| [ arg ] -> Some arg
|
||||
| _ -> failwithf "Expected Task to be applied to exactly one arg, but got: %+A" args
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|DirectoryInfo|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
|
||||
match ident |> List.map (fun i -> i.idText) with
|
||||
| [ "System" ; "IO" ; "DirectoryInfo" ]
|
||||
| [ "IO" ; "DirectoryInfo" ]
|
||||
| [ "DirectoryInfo" ] -> Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|FileInfo|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
|
||||
match ident |> List.map (fun i -> i.idText) with
|
||||
| [ "System" ; "IO" ; "FileInfo" ]
|
||||
| [ "IO" ; "FileInfo" ]
|
||||
| [ "FileInfo" ] -> Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|TimeSpan|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
|
||||
match ident |> List.map (fun i -> i.idText) with
|
||||
| [ "System" ; "TimeSpan" ]
|
||||
| [ "TimeSpan" ] -> Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynType =
|
||||
let rec stripOptionalParen (ty : SynType) : SynType =
|
||||
match ty with
|
||||
| SynType.Paren (ty, _) -> stripOptionalParen ty
|
||||
| ty -> ty
|
||||
|
||||
let inline paren (ty : SynType) : SynType = SynType.Paren (ty, range0)
|
||||
|
||||
let inline createLongIdent (ident : LongIdent) : SynType =
|
||||
SynType.LongIdent (SynLongIdent.create ident)
|
||||
|
||||
let inline createLongIdent' (ident : string list) : SynType =
|
||||
SynType.LongIdent (SynLongIdent.createS' ident)
|
||||
|
||||
let inline named (name : string) = createLongIdent' [ name ]
|
||||
|
||||
let inline app' (name : SynType) (args : SynType list) : SynType =
|
||||
if args.IsEmpty then
|
||||
failwith "Type cannot be applied to no arguments"
|
||||
|
||||
SynType.App (name, Some range0, args, List.replicate (args.Length - 1) range0, Some range0, false, range0)
|
||||
|
||||
let inline app (name : string) (args : SynType list) : SynType = app' (named name) args
|
||||
|
||||
/// Returns None if the input list was empty.
|
||||
let inline tupleNoParen (ty : SynType list) : SynType option =
|
||||
match List.rev ty with
|
||||
| [] -> None
|
||||
| [ t ] -> Some t
|
||||
| t :: rest ->
|
||||
([ SynTupleTypeSegment.Type t ], rest)
|
||||
||> List.fold (fun ty nextArg -> SynTupleTypeSegment.Type nextArg :: SynTupleTypeSegment.Star range0 :: ty)
|
||||
|> fun segs -> SynType.Tuple (false, segs, range0)
|
||||
|> Some
|
||||
|
||||
let inline appPostfix (name : string) (arg : SynType) : SynType =
|
||||
SynType.App (named name, None, [ arg ], [], None, true, range0)
|
||||
|
||||
let inline appPostfix' (name : string list) (arg : SynType) : SynType =
|
||||
SynType.App (createLongIdent' name, None, [ arg ], [], None, true, range0)
|
||||
|
||||
let inline funFromDomain (domain : SynType) (range : SynType) : SynType =
|
||||
SynType.Fun (
|
||||
domain,
|
||||
range,
|
||||
range0,
|
||||
{
|
||||
ArrowRange = range0
|
||||
}
|
||||
)
|
||||
|
||||
let inline signatureParamOfType
|
||||
(attrs : SynAttribute list)
|
||||
(ty : SynType)
|
||||
(optional : bool)
|
||||
(name : Ident option)
|
||||
: SynType
|
||||
=
|
||||
SynType.SignatureParameter (
|
||||
attrs
|
||||
|> List.map (fun attr ->
|
||||
{
|
||||
Attributes = [ attr ]
|
||||
Range = range0
|
||||
}
|
||||
),
|
||||
optional,
|
||||
name,
|
||||
ty,
|
||||
range0
|
||||
)
|
||||
|
||||
let inline var (ty : SynTypar) : SynType = SynType.Var (ty, range0)
|
||||
|
||||
let unit : SynType = named "unit"
|
||||
let obj : SynType = named "obj"
|
||||
let bool : SynType = named "bool"
|
||||
let int : SynType = named "int"
|
||||
let array (elt : SynType) : SynType = SynType.Array (1, elt, range0)
|
||||
|
||||
let list (elt : SynType) : SynType =
|
||||
SynType.App (named "list", None, [ elt ], [], None, true, range0)
|
||||
|
||||
let option (elt : SynType) : SynType =
|
||||
SynType.App (named "option", None, [ elt ], [], None, true, range0)
|
||||
|
||||
let anon : SynType = SynType.Anon range0
|
||||
|
||||
let task (elt : SynType) : SynType =
|
||||
SynType.App (
|
||||
createLongIdent' [ "System" ; "Threading" ; "Tasks" ; "Task" ],
|
||||
None,
|
||||
[ elt ],
|
||||
[],
|
||||
None,
|
||||
true,
|
||||
range0
|
||||
)
|
||||
|
||||
let string : SynType = named "string"
|
||||
|
||||
/// Given ['a1, 'a2] and 'ret, returns 'a1 -> 'a2 -> 'ret.
|
||||
let toFun (inputs : SynType list) (ret : SynType) : SynType =
|
||||
(ret, List.rev inputs) ||> List.fold (fun ty input -> funFromDomain input ty)
|
||||
|
||||
let primitiveToHumanReadableString (name : LongIdent) : string =
|
||||
match name |> List.map _.idText with
|
||||
| [ "System" ; "Single" ] -> "single"
|
||||
| [ "System" ; "Double" ] -> "double"
|
||||
| [ "System" ; "Byte" ] -> "byte"
|
||||
| [ "System" ; "SByte" ] -> "signed byte"
|
||||
| [ "System" ; "Int16" ] -> "int16"
|
||||
| [ "System" ; "Int32" ] -> "int32"
|
||||
| [ "System" ; "Int64" ] -> "int64"
|
||||
| [ "System" ; "UInt16" ] -> "uint16"
|
||||
| [ "System" ; "UInt32" ] -> "uint32"
|
||||
| [ "System" ; "UInt64" ] -> "uint64"
|
||||
| [ "System" ; "Char" ] -> "char"
|
||||
| [ "System" ; "Decimal" ] -> "decimal"
|
||||
| [ "System" ; "String" ] -> "string"
|
||||
| [ "System" ; "Boolean" ] -> "bool"
|
||||
| ty ->
|
||||
ty
|
||||
|> String.concat "."
|
||||
|> failwithf "could not create human-readable string for primitive type %s"
|
||||
|
||||
let rec toHumanReadableString (ty : SynType) : string =
|
||||
match ty with
|
||||
| PrimitiveType t1 -> primitiveToHumanReadableString t1
|
||||
| OptionType t1 -> toHumanReadableString t1 + " option"
|
||||
| NullableType t1 -> toHumanReadableString t1 + " Nullable"
|
||||
| ChoiceType ts ->
|
||||
ts
|
||||
|> List.map toHumanReadableString
|
||||
|> String.concat ", "
|
||||
|> sprintf "Choice<%s>"
|
||||
| MapType (k, v)
|
||||
| DictionaryType (k, v)
|
||||
| IDictionaryType (k, v)
|
||||
| IReadOnlyDictionaryType (k, v) -> sprintf "map<%s, %s>" (toHumanReadableString k) (toHumanReadableString v)
|
||||
| ListType t1 -> toHumanReadableString t1 + " list"
|
||||
| ArrayType t1 -> toHumanReadableString t1 + " array"
|
||||
| Task t1 -> toHumanReadableString t1 + " Task"
|
||||
| UnitType -> "unit"
|
||||
| FileInfo -> "FileInfo"
|
||||
| DirectoryInfo -> "DirectoryInfo"
|
||||
| Uri -> "URI"
|
||||
| Stream -> "Stream"
|
||||
| Guid -> "GUID"
|
||||
| BigInt -> "bigint"
|
||||
| DateTimeOffset -> "DateTimeOffset"
|
||||
| DateOnly -> "DateOnly"
|
||||
| TimeSpan -> "TimeSpan"
|
||||
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) -> ident |> List.map _.idText |> String.concat "."
|
||||
| ty -> failwithf "could not compute human-readable string for type: %O" ty
|
||||
|
||||
/// Guess whether the types are equal. We err on the side of saying "no, they're different".
|
||||
let rec provablyEqual (ty1 : SynType) (ty2 : SynType) : bool =
|
||||
if Object.ReferenceEquals (ty1, ty2) then
|
||||
true
|
||||
else
|
||||
|
||||
match ty1 with
|
||||
| PrimitiveType t1 ->
|
||||
match ty2 with
|
||||
| PrimitiveType t2 -> (t1 |> List.map _.idText) = (t2 |> List.map _.idText)
|
||||
| _ -> false
|
||||
| OptionType t1 ->
|
||||
match ty2 with
|
||||
| OptionType t2 -> provablyEqual t1 t2
|
||||
| _ -> false
|
||||
| NullableType t1 ->
|
||||
match ty2 with
|
||||
| NullableType t2 -> provablyEqual t1 t2
|
||||
| _ -> false
|
||||
| ChoiceType t1 ->
|
||||
match ty2 with
|
||||
| ChoiceType t2 ->
|
||||
t1.Length = t2.Length
|
||||
&& List.forall (fun (a, b) -> provablyEqual a b) (List.zip t1 t2)
|
||||
| _ -> false
|
||||
| DictionaryType (k1, v1) ->
|
||||
match ty2 with
|
||||
| DictionaryType (k2, v2) -> provablyEqual k1 k2 && provablyEqual v1 v2
|
||||
| _ -> false
|
||||
| IDictionaryType (k1, v1) ->
|
||||
match ty2 with
|
||||
| IDictionaryType (k2, v2) -> provablyEqual k1 k2 && provablyEqual v1 v2
|
||||
| _ -> false
|
||||
| IReadOnlyDictionaryType (k1, v1) ->
|
||||
match ty2 with
|
||||
| IReadOnlyDictionaryType (k2, v2) -> provablyEqual k1 k2 && provablyEqual v1 v2
|
||||
| _ -> false
|
||||
| MapType (k1, v1) ->
|
||||
match ty2 with
|
||||
| MapType (k2, v2) -> provablyEqual k1 k2 && provablyEqual v1 v2
|
||||
| _ -> false
|
||||
| ListType t1 ->
|
||||
match ty2 with
|
||||
| ListType t2 -> provablyEqual t1 t2
|
||||
| _ -> false
|
||||
| ArrayType t1 ->
|
||||
match ty2 with
|
||||
| ArrayType t2 -> provablyEqual t1 t2
|
||||
| _ -> false
|
||||
| Task t1 ->
|
||||
match ty2 with
|
||||
| Task t2 -> provablyEqual t1 t2
|
||||
| _ -> false
|
||||
| UnitType ->
|
||||
match ty2 with
|
||||
| UnitType -> true
|
||||
| _ -> false
|
||||
| FileInfo ->
|
||||
match ty2 with
|
||||
| FileInfo -> true
|
||||
| _ -> false
|
||||
| DirectoryInfo ->
|
||||
match ty2 with
|
||||
| DirectoryInfo -> true
|
||||
| _ -> false
|
||||
| Uri ->
|
||||
match ty2 with
|
||||
| Uri -> true
|
||||
| _ -> false
|
||||
| Stream ->
|
||||
match ty2 with
|
||||
| Stream -> true
|
||||
| _ -> false
|
||||
| Guid ->
|
||||
match ty2 with
|
||||
| Guid -> true
|
||||
| _ -> false
|
||||
| BigInt ->
|
||||
match ty2 with
|
||||
| BigInt -> true
|
||||
| _ -> false
|
||||
| DateTimeOffset ->
|
||||
match ty2 with
|
||||
| DateTimeOffset -> true
|
||||
| _ -> false
|
||||
| DateOnly ->
|
||||
match ty2 with
|
||||
| DateOnly -> true
|
||||
| _ -> false
|
||||
| _ ->
|
||||
|
||||
match ty1, ty2 with
|
||||
| SynType.LongIdent (SynLongIdent (ident1, _, _)), SynType.LongIdent (SynLongIdent (ident2, _, _)) ->
|
||||
let ident1 = ident1 |> List.map _.idText
|
||||
let ident2 = ident2 |> List.map _.idText
|
||||
ident1 = ident2
|
||||
| _, _ -> false
|
@@ -1,27 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.SyntaxTrivia
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynTypeDefn =
|
||||
|
||||
let inline create (componentInfo : SynComponentInfo) (repr : SynTypeDefnRepr) : SynTypeDefn =
|
||||
SynTypeDefn.SynTypeDefn (
|
||||
componentInfo,
|
||||
repr,
|
||||
[],
|
||||
None,
|
||||
range0,
|
||||
{
|
||||
LeadingKeyword = SynTypeDefnLeadingKeyword.Type range0
|
||||
EqualsRange = Some range0
|
||||
WithKeyword = None
|
||||
}
|
||||
)
|
||||
|
||||
let inline withMemberDefns (members : SynMemberDefn list) (r : SynTypeDefn) : SynTypeDefn =
|
||||
match r with
|
||||
| SynTypeDefn (typeInfo, typeRepr, _, ctor, range, trivia) ->
|
||||
SynTypeDefn.SynTypeDefn (typeInfo, typeRepr, members, ctor, range, trivia)
|
@@ -1,24 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynTypeDefnRepr =
|
||||
|
||||
let inline interfaceType (mems : SynMemberDefns) : SynTypeDefnRepr =
|
||||
SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.Unspecified, mems, range0)
|
||||
|
||||
/// Indicates the body of a `type Foo with {body}` extension type declaration.
|
||||
let inline augmentation () : SynTypeDefnRepr =
|
||||
SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.Augmentation range0, [], range0)
|
||||
|
||||
let inline unionWithAccess (implAccess : SynAccess option) (cases : SynUnionCase list) : SynTypeDefnRepr =
|
||||
SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Union (implAccess, cases, range0), range0)
|
||||
|
||||
let inline union (cases : SynUnionCase list) : SynTypeDefnRepr = unionWithAccess None cases
|
||||
|
||||
let inline recordWithAccess (implAccess : SynAccess option) (fields : SynField list) : SynTypeDefnRepr =
|
||||
SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Record (implAccess, fields, range0), range0)
|
||||
|
||||
let inline record (fields : SynField list) : SynTypeDefnRepr = recordWithAccess None fields
|
@@ -1,55 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Text.Range
|
||||
open Fantomas.FCS.Xml
|
||||
open Fantomas.FCS.SyntaxTrivia
|
||||
|
||||
/// Represents everything you need to know about a union case.
|
||||
/// This is generic on whether each field of this case must be named.
|
||||
type UnionCase<'ident> =
|
||||
{
|
||||
/// The name of the case: e.g. `| Foo of blah` has this being `Foo`.
|
||||
Name : Ident
|
||||
/// Any docstring associated with this case.
|
||||
XmlDoc : PreXmlDoc option
|
||||
/// Any accessibility modifier: e.g. `type Foo = private | Blah`.
|
||||
Access : SynAccess option
|
||||
/// Attributes on the case: for example, `| [<Attr>] Foo of blah`.
|
||||
Attributes : SynAttribute list
|
||||
/// The data contained within the case: for example, `[blah]` in `| Foo of blah`.
|
||||
Fields : SynFieldData<'ident> list
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SynUnionCase =
|
||||
let create (case : UnionCase<Ident>) : SynUnionCase =
|
||||
let fields =
|
||||
case.Fields
|
||||
|> List.map (fun field ->
|
||||
SynField.SynField (
|
||||
SynAttributes.ofAttrs field.Attrs,
|
||||
false,
|
||||
Some field.Ident,
|
||||
field.Type,
|
||||
false,
|
||||
PreXmlDoc.Empty,
|
||||
None,
|
||||
range0,
|
||||
{
|
||||
LeadingKeyword = None
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
SynUnionCase.SynUnionCase (
|
||||
SynAttributes.ofAttrs case.Attributes,
|
||||
SynIdent.createI case.Name,
|
||||
SynUnionCaseKind.Fields fields,
|
||||
case.XmlDoc |> Option.defaultValue PreXmlDoc.Empty,
|
||||
case.Access,
|
||||
range0,
|
||||
{
|
||||
BarRange = Some range0
|
||||
}
|
||||
)
|
@@ -1,18 +0,0 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
// Extracted from https://github.com/G-Research/TypeEquality
|
||||
// which is Apache-2.0 licenced. See `TeqLicence.txt`.
|
||||
// We inline this code because Myriad doesn't seem to reliably load package references in the generator.
|
||||
// I have reformatted a little, and stripped out all the code I don't use.
|
||||
|
||||
type internal Teq<'a, 'b> = private | Teq of ('a -> 'b) * ('b -> 'a)
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal Teq =
|
||||
|
||||
let refl<'a> : Teq<'a, 'a> = Teq (id, id)
|
||||
let cast (Teq (f, _)) a = f a
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module Cong =
|
||||
let believeMe<'a, 'b, 'a2, 'b2> (_ : Teq<'a, 'b>) : Teq<'a2, 'b2> = unbox <| (refl : Teq<'a2, 'a2>)
|
@@ -15,10 +15,14 @@
|
||||
<WarnOn>FS3559</WarnOn>
|
||||
<PackageId>WoofWare.Myriad.Plugins</PackageId>
|
||||
<PackageIcon>logo.png</PackageIcon>
|
||||
<NoWarn>NU5118</NoWarn>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Myriad.Core" Version="0.8.3" />
|
||||
<PackageReference Include="TypeEquality" Version="0.3.0" />
|
||||
<PackageReference Include="WoofWare.Whippet.Fantomas" Version="0.6.3" />
|
||||
<!-- the lowest version allowed by Myriad.Core -->
|
||||
<PackageReference Update="FSharp.Core" Version="6.0.1" PrivateAssets="all"/>
|
||||
</ItemGroup>
|
||||
@@ -26,33 +30,11 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="List.fs"/>
|
||||
<Compile Include="Text.fs" />
|
||||
<Compile Include="Teq.fs" />
|
||||
<Compile Include="Primitives.fs" />
|
||||
<Compile Include="SynExpr\SynAttributes.fs" />
|
||||
<Compile Include="SynExpr\PreXmlDoc.fs" />
|
||||
<Compile Include="SynExpr\Ident.fs" />
|
||||
<Compile Include="SynExpr\SynIdent.fs" />
|
||||
<Compile Include="SynExpr\SynLongIdent.fs" />
|
||||
<Compile Include="SynExpr\SynExprLetOrUseTrivia.fs" />
|
||||
<Compile Include="SynExpr\SynArgPats.fs" />
|
||||
<Compile Include="SynExpr\SynPat.fs" />
|
||||
<Compile Include="SynExpr\SynBinding.fs" />
|
||||
<Compile Include="SynExpr\SynType.fs" />
|
||||
<Compile Include="SynExpr\SynMatchClause.fs" />
|
||||
<Compile Include="SynExpr\CompExpr.fs" />
|
||||
<Compile Include="SynExpr\SynExpr.fs" />
|
||||
<Compile Include="SynExpr\SynField.fs" />
|
||||
<Compile Include="SynExpr\SynUnionCase.fs" />
|
||||
<Compile Include="SynExpr\SynTypeDefnRepr.fs" />
|
||||
<Compile Include="SynExpr\SynTypeDefn.fs" />
|
||||
<Compile Include="SynExpr\SynComponentInfo.fs" />
|
||||
<Compile Include="SynExpr\SynMemberDefn.fs" />
|
||||
<Compile Include="SynExpr\SynAttribute.fs" />
|
||||
<Compile Include="SynExpr\SynModuleDecl.fs" />
|
||||
<Compile Include="SynExpr\SynModuleOrNamespace.fs" />
|
||||
<Compile Include="Measure.fs" />
|
||||
<Compile Include="AstHelper.fs" />
|
||||
<Compile Include="Parameters.fs" />
|
||||
<Compile Include="RemoveOptionsGenerator.fs"/>
|
||||
<Compile Include="MyriadParamParser.fs" />
|
||||
<Compile Include="InterfaceMockGenerator.fs"/>
|
||||
<Compile Include="JsonSerializeGenerator.fs"/>
|
||||
<Compile Include="JsonParseGenerator.fs"/>
|
||||
@@ -61,7 +43,7 @@
|
||||
<Compile Include="ArgParserGenerator.fs" />
|
||||
<Compile Include="Swagger.fs" />
|
||||
<Compile Include="SwaggerClientGenerator.fs" />
|
||||
<None Include="TeqLicence.txt" />
|
||||
<None Include="ApacheLicence.txt" />
|
||||
<EmbeddedResource Include="version.json"/>
|
||||
<EmbeddedResource Include="SurfaceBaseline.txt"/>
|
||||
<None Include="..\README.md">
|
||||
@@ -78,7 +60,7 @@
|
||||
<ProjectReference Include="..\WoofWare.Myriad.Plugins.Attributes\WoofWare.Myriad.Plugins.Attributes.fsproj"/>
|
||||
<!-- NuGet is such a clown package manager! Get the DLLs into the Nupkg artefact, I have no idea why this is needed,
|
||||
but without this line, we don't get any dependency at all packaged into the resulting artefact. -->
|
||||
<None Include="$(OutputPath)\WoofWare.Myriad.Plugins.Attributes.dll" Pack="true" PackagePath="lib\$(TargetFramework)"/>
|
||||
<None Include="$(OutputPath)\*.dll" Pack="true" PackagePath="lib\$(TargetFramework)"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "3.1",
|
||||
"version": "7.0",
|
||||
"publicReleaseRefSpec": [
|
||||
"^refs/heads/main$"
|
||||
],
|
||||
@@ -11,4 +11,4 @@
|
||||
":/README.md",
|
||||
":/Directory.Build.props"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageDownload Include="G-Research.FSharp.Analyzers" Version="[0.11.0]" />
|
||||
<PackageDownload Include="G-Research.FSharp.Analyzers" Version="[0.14.0]" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
12
flake.lock
generated
12
flake.lock
generated
@@ -5,11 +5,11 @@
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -20,11 +20,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1725534445,
|
||||
"narHash": "sha256-Yd0FK9SkWy+ZPuNqUgmVPXokxDgMJoGuNpMEtkfcf84=",
|
||||
"lastModified": 1744868846,
|
||||
"narHash": "sha256-5RJTdUHDmj12Qsv7XOhuospjAjATNiTMElplWnJE9Hs=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9bb1e7571aadf31ddb4af77fc64b2d59580f9a39",
|
||||
"rev": "ebe4301cbd8f81c4f8d3244b3632338bbeb6d49c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
32
flake.nix
32
flake.nix
@@ -14,8 +14,8 @@
|
||||
flake-utils.lib.eachDefaultSystem (system: let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
pname = "WoofWare.Myriad.Plugins";
|
||||
dotnet-sdk = pkgs.dotnet-sdk_8;
|
||||
dotnet-runtime = pkgs.dotnetCorePackages.runtime_8_0;
|
||||
dotnet-sdk = pkgs.dotnetCorePackages.sdk_9_0;
|
||||
dotnet-runtime = pkgs.dotnetCorePackages.runtime_9_0;
|
||||
version = "0.1";
|
||||
dotnetTool = dllOverride: toolName: toolVersion: hash:
|
||||
pkgs.stdenvNoCC.mkDerivation rec {
|
||||
@@ -26,25 +26,29 @@
|
||||
pname = name;
|
||||
version = version;
|
||||
hash = hash;
|
||||
installPhase = ''mkdir -p $out/bin && cp -r tools/net6.0/any/* $out/bin'';
|
||||
installPhase = ''mkdir -p $out/bin && cp -r tools/net*/any/* $out/bin'';
|
||||
};
|
||||
installPhase = let
|
||||
dll =
|
||||
if isNull dllOverride
|
||||
then name
|
||||
else dllOverride;
|
||||
in ''
|
||||
runHook preInstall
|
||||
mkdir -p "$out/lib"
|
||||
cp -r ./bin/* "$out/lib"
|
||||
makeWrapper "${dotnet-runtime}/bin/dotnet" "$out/bin/${name}" --add-flags "$out/lib/${dll}.dll"
|
||||
runHook postInstall
|
||||
'';
|
||||
in
|
||||
# fsharp-analyzers requires the .NET SDK at runtime, so we use that instead of dotnet-runtime.
|
||||
''
|
||||
runHook preInstall
|
||||
mkdir -p "$out/lib"
|
||||
cp -r ./bin/* "$out/lib"
|
||||
makeWrapper "${dotnet-sdk}/bin/dotnet" "$out/bin/${name}" --set DOTNET_HOST_PATH "${dotnet-sdk}/bin/dotnet" --add-flags "$out/lib/${dll}.dll"
|
||||
runHook postInstall
|
||||
'';
|
||||
};
|
||||
in {
|
||||
packages = {
|
||||
fantomas = dotnetTool null "fantomas" (builtins.fromJSON (builtins.readFile ./.config/dotnet-tools.json)).tools.fantomas.version (builtins.head (builtins.filter (elem: elem.pname == "fantomas") ((import ./nix/deps.nix) {fetchNuGet = x: x;}))).hash;
|
||||
fsharp-analyzers = dotnetTool "FSharp.Analyzers.Cli" "fsharp-analyzers" (builtins.fromJSON (builtins.readFile ./.config/dotnet-tools.json)).tools.fsharp-analyzers.version (builtins.head (builtins.filter (elem: elem.pname == "fsharp-analyzers") ((import ./nix/deps.nix) {fetchNuGet = x: x;}))).hash;
|
||||
packages = let
|
||||
deps = builtins.fromJSON (builtins.readFile ./nix/deps.json);
|
||||
in {
|
||||
fantomas = dotnetTool null "fantomas" (builtins.fromJSON (builtins.readFile ./.config/dotnet-tools.json)).tools.fantomas.version (builtins.head (builtins.filter (elem: elem.pname == "fantomas") deps)).hash;
|
||||
fsharp-analyzers = dotnetTool "FSharp.Analyzers.Cli" "fsharp-analyzers" (builtins.fromJSON (builtins.readFile ./.config/dotnet-tools.json)).tools.fsharp-analyzers.version (builtins.head (builtins.filter (elem: elem.pname == "fsharp-analyzers") deps)).hash;
|
||||
default = pkgs.buildDotnetModule {
|
||||
inherit pname version dotnet-sdk dotnet-runtime;
|
||||
name = "WoofWare.Myriad.Plugins";
|
||||
@@ -52,7 +56,7 @@
|
||||
projectFile = "./WoofWare.Myriad.Plugins/WoofWare.Myriad.Plugins.fsproj";
|
||||
testProjectFile = "./WoofWare.Myriad.Plugins.Test/WoofWare.Myriad.Plugins.Test.fsproj";
|
||||
disabledTests = ["WoofWare.Myriad.Plugins.Test.TestSurface.CheckVersionAgainstRemote"];
|
||||
nugetDeps = ./nix/deps.nix; # `nix build .#default.passthru.fetch-deps && ./result` and put the result here
|
||||
nugetDeps = ./nix/deps.json; # `nix build .#default.fetch-deps && ./result nix/deps.json`
|
||||
doCheck = true;
|
||||
};
|
||||
};
|
||||
|
12
global.json
12
global.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "8.0.100",
|
||||
"rollForward": "latestMajor"
|
||||
}
|
||||
}
|
||||
{
|
||||
"sdk": {
|
||||
"version": "9.0.100",
|
||||
"rollForward": "latestMajor"
|
||||
}
|
||||
}
|
||||
|
387
nix/deps.json
Normal file
387
nix/deps.json
Normal file
@@ -0,0 +1,387 @@
|
||||
[
|
||||
{
|
||||
"pname": "ApiSurface",
|
||||
"version": "4.1.20",
|
||||
"hash": "sha256-koWgO9FC9ax+Ij56ug8kxeyknl0yhLqnNLOUdxtqqo4="
|
||||
},
|
||||
{
|
||||
"pname": "fantomas",
|
||||
"version": "7.0.1",
|
||||
"hash": "sha256-2aGD6Kjh83gmssRqqZ/Uihi7VbNqNUelX4otIfCuhTI="
|
||||
},
|
||||
{
|
||||
"pname": "Fantomas.Core",
|
||||
"version": "6.1.1",
|
||||
"hash": "sha256-FcTLHQFvKkQY/kV08jhhy/St/+FmXpp3epp/R3zUXMA="
|
||||
},
|
||||
{
|
||||
"pname": "Fantomas.FCS",
|
||||
"version": "6.1.1",
|
||||
"hash": "sha256-NuZ8msPEHYA8T3EYREB28F1RcNgUU8V54eg2+UttYxw="
|
||||
},
|
||||
{
|
||||
"pname": "FsCheck",
|
||||
"version": "3.2.0",
|
||||
"hash": "sha256-ksZ4vLgWwyQOzFuK2BczdtDtWWYmedG7UBAg4pYuI8g="
|
||||
},
|
||||
{
|
||||
"pname": "fsharp-analyzers",
|
||||
"version": "0.30.0",
|
||||
"hash": "sha256-7oaSwpHAU1opzpz4szLU/gDaJC/ww9eiFkPu0nr4Mj4="
|
||||
},
|
||||
{
|
||||
"pname": "FSharp.Core",
|
||||
"version": "4.3.4",
|
||||
"hash": "sha256-styyo+6mJy+yxE0NZG/b1hxkAjPOnJfMgd9zWzCJ5uk="
|
||||
},
|
||||
{
|
||||
"pname": "FSharp.Core",
|
||||
"version": "6.0.1",
|
||||
"hash": "sha256-Ehsgt3nCJijpaVuJguC1TPVEKSkJd6PSc07D2ZQSemI="
|
||||
},
|
||||
{
|
||||
"pname": "FSharp.Core",
|
||||
"version": "9.0.202",
|
||||
"hash": "sha256-64Gub0qemmCoMa1tDus6TeTuB1+5sHfE6KD2j4o84mA="
|
||||
},
|
||||
{
|
||||
"pname": "FsUnit",
|
||||
"version": "7.0.1",
|
||||
"hash": "sha256-K85CIdxMeFSHEKZk6heIXp/oFjWAn7dBILKrw49pJUY="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.ApplicationInsights",
|
||||
"version": "2.22.0",
|
||||
"hash": "sha256-mUQ63atpT00r49ca50uZu2YCiLg3yd6r3HzTryqcuEA="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "6.0.36",
|
||||
"hash": "sha256-9jDkWbjw/nd8yqdzVTagCuqr6owJ/DUMi4BlUZT4hWU="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.AspNetCore.App.Runtime.linux-arm64",
|
||||
"version": "6.0.36",
|
||||
"hash": "sha256-JQULJyF0ivLoUU1JaFfK/HHg+/qzpN7V2RR2Cc+WlQ4="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.AspNetCore.App.Runtime.linux-x64",
|
||||
"version": "6.0.36",
|
||||
"hash": "sha256-zUsVIpV481vMLAXaLEEUpEMA9/f1HGOnvaQnaWdzlyY="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.AspNetCore.App.Runtime.osx-arm64",
|
||||
"version": "6.0.36",
|
||||
"hash": "sha256-2seqZcz0JeUjkzh3QcGa9TcJ4LUafpFjTRk+Nm8T6T0="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.AspNetCore.App.Runtime.osx-x64",
|
||||
"version": "6.0.36",
|
||||
"hash": "sha256-yxLafxiBKkvfkDggPk0P9YZIHBkDJOsFTO7/V9mEHuU="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.CodeCoverage",
|
||||
"version": "17.13.0",
|
||||
"hash": "sha256-GKrIxeyQo5Az1mztfQgea1kGtJwonnNOrXK/0ULfu8o="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NET.Test.Sdk",
|
||||
"version": "17.13.0",
|
||||
"hash": "sha256-sc2wvyV8cGm1FrNP2GGHEI584RCvRPu15erYCsgw5QY="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.App.Host.linux-arm64",
|
||||
"version": "6.0.36",
|
||||
"hash": "sha256-9lC/LYnthYhjkWWz2kkFCvlA5LJOv11jdt59SDnpdy0="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.App.Host.linux-x64",
|
||||
"version": "6.0.36",
|
||||
"hash": "sha256-VFRDzx7LJuvI5yzKdGmw/31NYVbwHWPKQvueQt5xc10="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.App.Host.osx-arm64",
|
||||
"version": "6.0.36",
|
||||
"hash": "sha256-DaSWwYACJGolEBuMhzDVCj/rQTdDt061xCVi+gyQnuo="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.App.Host.osx-x64",
|
||||
"version": "6.0.36",
|
||||
"hash": "sha256-FrRny9EI6HKCKQbu6mcLj5w4ooSRrODD4Vj2ZMGnMd4="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.App.Ref",
|
||||
"version": "6.0.36",
|
||||
"hash": "sha256-9LZgVoIFF8qNyUu8kdJrYGLutMF/cL2K82HN2ywwlx8="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.App.Runtime.linux-arm64",
|
||||
"version": "6.0.36",
|
||||
"hash": "sha256-k3rxvUhCEU0pVH8KgEMtkPiSOibn+nBh+0zT2xIfId8="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.App.Runtime.linux-x64",
|
||||
"version": "6.0.36",
|
||||
"hash": "sha256-U8wJ2snSDFqeAgDVLXjnniidC7Cr5aJ1/h/BMSlyu0c="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.App.Runtime.osx-arm64",
|
||||
"version": "6.0.36",
|
||||
"hash": "sha256-UfLcrL2Gj/OLz0s92Oo+OCJeDpZFAcQLPLiSNND8D5Y="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.App.Runtime.osx-x64",
|
||||
"version": "6.0.36",
|
||||
"hash": "sha256-0xIJYFzxdMcnCj3wzkFRQZSnQcPHzPHMzePRIOA3oJs="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.Platforms",
|
||||
"version": "1.1.0",
|
||||
"hash": "sha256-FeM40ktcObQJk4nMYShB61H/E8B7tIKfl9ObJ0IOcCM="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.Platforms",
|
||||
"version": "1.1.1",
|
||||
"hash": "sha256-8hLiUKvy/YirCWlFwzdejD2Db3DaXhHxT7GSZx/znJg="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.Platforms",
|
||||
"version": "2.0.0",
|
||||
"hash": "sha256-IEvBk6wUXSdyCnkj6tHahOJv290tVVT8tyemYcR0Yro="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.Targets",
|
||||
"version": "1.1.0",
|
||||
"hash": "sha256-0AqQ2gMS8iNlYkrD+BxtIg7cXMnr9xZHtKAuN4bjfaQ="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.Targets",
|
||||
"version": "1.1.3",
|
||||
"hash": "sha256-WLsf1NuUfRWyr7C7Rl9jiua9jximnVvzy6nk2D2bVRc="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Extensions.Telemetry",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-bIXwPSa3jkr2b6xINOqMUs6/uj/r4oVFM7xq3uVIZDU="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Extensions.TrxReport.Abstractions",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-IfMRfcyaIKEMRtx326ICKtinDBEfGw/Sv8ZHawJ96Yc="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Extensions.VSTestBridge",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-XpM/yFjhLSsuzyDV+xKubs4V1zVVYiV05E0+N4S1h0g="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Platform",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-y61Iih6w5D79dmrj2V675mcaeIiHoj1HSa1FRit2BLM="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Platform.MSBuild",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-YspvjE5Jfi587TAfsvfDVJXNrFOkx1B3y1CKV6m7YLY="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.TestPlatform.ObjectModel",
|
||||
"version": "17.12.0",
|
||||
"hash": "sha256-3XBHBSuCxggAIlHXmKNQNlPqMqwFlM952Av6RrLw1/w="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.TestPlatform.ObjectModel",
|
||||
"version": "17.13.0",
|
||||
"hash": "sha256-6S0fjfj8vA+h6dJVNwLi6oZhYDO/I/6hBZaq2VTW+Uk="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.TestPlatform.TestHost",
|
||||
"version": "17.13.0",
|
||||
"hash": "sha256-L/CJzou7dhmShUgXq3aXL3CaLTJll17Q+JY2DBdUUpo="
|
||||
},
|
||||
{
|
||||
"pname": "Myriad.Core",
|
||||
"version": "0.8.3",
|
||||
"hash": "sha256-vBOxfq8QriX/yUtaXN69rEQaY/psRNJWxqATLidrt2g="
|
||||
},
|
||||
{
|
||||
"pname": "Myriad.Sdk",
|
||||
"version": "0.8.3",
|
||||
"hash": "sha256-7O397WKhskKOvE3MkJT37BvxorDWngDR6gTUogtDZ2M="
|
||||
},
|
||||
{
|
||||
"pname": "Nerdbank.GitVersioning",
|
||||
"version": "3.8.38-alpha",
|
||||
"hash": "sha256-gPMrVbjOZxXoofczF/pn6eVkLhjVSJIyQrLO2oljrDc="
|
||||
},
|
||||
{
|
||||
"pname": "NETStandard.Library",
|
||||
"version": "2.0.3",
|
||||
"hash": "sha256-Prh2RPebz/s8AzHb2sPHg3Jl8s31inv9k+Qxd293ybo="
|
||||
},
|
||||
{
|
||||
"pname": "Newtonsoft.Json",
|
||||
"version": "13.0.1",
|
||||
"hash": "sha256-K2tSVW4n4beRPzPu3rlVaBEMdGvWSv/3Q1fxaDh4Mjo="
|
||||
},
|
||||
{
|
||||
"pname": "Newtonsoft.Json",
|
||||
"version": "13.0.3",
|
||||
"hash": "sha256-hy/BieY4qxBWVVsDqqOPaLy1QobiIapkbrESm6v2PHc="
|
||||
},
|
||||
{
|
||||
"pname": "NuGet.Common",
|
||||
"version": "6.13.2",
|
||||
"hash": "sha256-ASLa/Jigg5Eop0ZrXPl98RW2rxnJRC7pbbxhuV74hFw="
|
||||
},
|
||||
{
|
||||
"pname": "NuGet.Configuration",
|
||||
"version": "6.13.2",
|
||||
"hash": "sha256-z8VW1YdRDanyyRTDYRvRkSv/XPR3c/hMM1y8cNNjx0Y="
|
||||
},
|
||||
{
|
||||
"pname": "NuGet.Frameworks",
|
||||
"version": "6.13.2",
|
||||
"hash": "sha256-caDyc+WgYOo43AUTjtbP0MyvYDb6JweEKDdIul61Cac="
|
||||
},
|
||||
{
|
||||
"pname": "NuGet.Packaging",
|
||||
"version": "6.13.2",
|
||||
"hash": "sha256-lhO+SFwIYZ4aPHxIGm5ubkkE2a5Ve2xgtroRbNh7hpw="
|
||||
},
|
||||
{
|
||||
"pname": "NuGet.Protocol",
|
||||
"version": "6.13.2",
|
||||
"hash": "sha256-5lnAHHZjy7A4vgv65AeBAs64mSNpuoUjxW3HnrMpuzY="
|
||||
},
|
||||
{
|
||||
"pname": "NuGet.Versioning",
|
||||
"version": "6.13.2",
|
||||
"hash": "sha256-gmpyBpKnt+GHqgx/2uFKp+J2csbxEAy1E7WdVT117sw="
|
||||
},
|
||||
{
|
||||
"pname": "NUnit",
|
||||
"version": "4.3.2",
|
||||
"hash": "sha256-0RWe8uFoxYp6qhPlDDEghOMcKJgyw2ybvEoAqBLebeE="
|
||||
},
|
||||
{
|
||||
"pname": "NUnit3TestAdapter",
|
||||
"version": "5.0.0",
|
||||
"hash": "sha256-7jZM4qAbIzne3AcdFfMbvbgogqpxvVe6q2S7Ls8xQy0="
|
||||
},
|
||||
{
|
||||
"pname": "RestEase",
|
||||
"version": "1.6.4",
|
||||
"hash": "sha256-FFmqFwlHhIln46k56Z8KM1G+xuPEh/bceKCQnJcdcdc="
|
||||
},
|
||||
{
|
||||
"pname": "runtime.any.System.Runtime",
|
||||
"version": "4.3.0",
|
||||
"hash": "sha256-qwhNXBaJ1DtDkuRacgHwnZmOZ1u9q7N8j0cWOLYOELM="
|
||||
},
|
||||
{
|
||||
"pname": "runtime.native.System",
|
||||
"version": "4.3.0",
|
||||
"hash": "sha256-ZBZaodnjvLXATWpXXakFgcy6P+gjhshFXmglrL5xD5Y="
|
||||
},
|
||||
{
|
||||
"pname": "runtime.unix.System.Private.Uri",
|
||||
"version": "4.3.0",
|
||||
"hash": "sha256-c5tXWhE/fYbJVl9rXs0uHh3pTsg44YD1dJvyOA0WoMs="
|
||||
},
|
||||
{
|
||||
"pname": "System.Collections.Immutable",
|
||||
"version": "8.0.0",
|
||||
"hash": "sha256-F7OVjKNwpqbUh8lTidbqJWYi476nsq9n+6k0+QVRo3w="
|
||||
},
|
||||
{
|
||||
"pname": "System.Diagnostics.DiagnosticSource",
|
||||
"version": "5.0.0",
|
||||
"hash": "sha256-6mW3N6FvcdNH/pB58pl+pFSCGWgyaP4hfVtC/SMWDV4="
|
||||
},
|
||||
{
|
||||
"pname": "System.Diagnostics.DiagnosticSource",
|
||||
"version": "7.0.0",
|
||||
"hash": "sha256-9Wk8cHSkjKtqkN6xW7KnXoQVtF/VNbKeBq79WqDesMs="
|
||||
},
|
||||
{
|
||||
"pname": "System.Formats.Asn1",
|
||||
"version": "6.0.0",
|
||||
"hash": "sha256-KaMHgIRBF7Nf3VwOo+gJS1DcD+41cJDPWFh+TDQ8ee8="
|
||||
},
|
||||
{
|
||||
"pname": "System.Formats.Asn1",
|
||||
"version": "8.0.1",
|
||||
"hash": "sha256-may/Wg+esmm1N14kQTG4ESMBi+GQKPp0ZrrBo/o6OXM="
|
||||
},
|
||||
{
|
||||
"pname": "System.IO.Abstractions",
|
||||
"version": "4.2.13",
|
||||
"hash": "sha256-nkC/PiqE6+c1HJ2yTwg3x+qdBh844Z8n3ERWDW8k6Gg="
|
||||
},
|
||||
{
|
||||
"pname": "System.IO.FileSystem.AccessControl",
|
||||
"version": "4.5.0",
|
||||
"hash": "sha256-ck44YBQ0M+2Im5dw0VjBgFD1s0XuY54cujrodjjSBL8="
|
||||
},
|
||||
{
|
||||
"pname": "System.Memory",
|
||||
"version": "4.5.5",
|
||||
"hash": "sha256-EPQ9o1Kin7KzGI5O3U3PUQAZTItSbk9h/i4rViN3WiI="
|
||||
},
|
||||
{
|
||||
"pname": "System.Private.Uri",
|
||||
"version": "4.3.0",
|
||||
"hash": "sha256-fVfgcoP4AVN1E5wHZbKBIOPYZ/xBeSIdsNF+bdukIRM="
|
||||
},
|
||||
{
|
||||
"pname": "System.Reflection.Metadata",
|
||||
"version": "1.6.0",
|
||||
"hash": "sha256-JJfgaPav7UfEh4yRAQdGhLZF1brr0tUWPl6qmfNWq/E="
|
||||
},
|
||||
{
|
||||
"pname": "System.Runtime",
|
||||
"version": "4.3.1",
|
||||
"hash": "sha256-R9T68AzS1PJJ7v6ARz9vo88pKL1dWqLOANg4pkQjkA0="
|
||||
},
|
||||
{
|
||||
"pname": "System.Runtime.CompilerServices.Unsafe",
|
||||
"version": "6.0.0",
|
||||
"hash": "sha256-bEG1PnDp7uKYz/OgLOWs3RWwQSVYm+AnPwVmAmcgp2I="
|
||||
},
|
||||
{
|
||||
"pname": "System.Security.AccessControl",
|
||||
"version": "4.5.0",
|
||||
"hash": "sha256-AFsKPb/nTk2/mqH/PYpaoI8PLsiKKimaXf+7Mb5VfPM="
|
||||
},
|
||||
{
|
||||
"pname": "System.Security.Cryptography.Pkcs",
|
||||
"version": "6.0.4",
|
||||
"hash": "sha256-2e0aRybote+OR66bHaNiYpF//4fCiaO3zbR2e9GABUI="
|
||||
},
|
||||
{
|
||||
"pname": "System.Security.Cryptography.ProtectedData",
|
||||
"version": "4.4.0",
|
||||
"hash": "sha256-Ri53QmFX8I8UH0x4PikQ1ZA07ZSnBUXStd5rBfGWFOE="
|
||||
},
|
||||
{
|
||||
"pname": "System.Security.Principal.Windows",
|
||||
"version": "4.5.0",
|
||||
"hash": "sha256-BkUYNguz0e4NJp1kkW7aJBn3dyH9STwB5N8XqnlCsmY="
|
||||
},
|
||||
{
|
||||
"pname": "System.Text.Json",
|
||||
"version": "8.0.5",
|
||||
"hash": "sha256-yKxo54w5odWT6nPruUVsaX53oPRe+gKzGvLnnxtwP68="
|
||||
},
|
||||
{
|
||||
"pname": "TypeEquality",
|
||||
"version": "0.3.0",
|
||||
"hash": "sha256-V50xAOzzyUJrY+MYPRxtnqW5MVeATXCes89wPprv1r4="
|
||||
},
|
||||
{
|
||||
"pname": "WoofWare.Whippet.Fantomas",
|
||||
"version": "0.6.3",
|
||||
"hash": "sha256-FkW/HtVp8/HE2k6d7yFpnJcnP3FNNe9kGlkoIWmNgDw="
|
||||
}
|
||||
]
|
329
nix/deps.nix
329
nix/deps.nix
@@ -1,329 +0,0 @@
|
||||
# This file was automatically generated by passthru.fetch-deps.
|
||||
# Please dont edit it manually, your changes might get overwritten!
|
||||
{fetchNuGet}: [
|
||||
(fetchNuGet {
|
||||
pname = "ApiSurface";
|
||||
version = "4.1.5";
|
||||
hash = "sha256-Kbt18XLk1gvZfzGca885HaXZB119APay85KzI546PYM=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "fantomas";
|
||||
version = "6.3.15";
|
||||
hash = "sha256-Gjw7MxjUNckMWSfnOye4UTe5fZWnor6RHCls3PNsuG8=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Fantomas.Core";
|
||||
version = "6.1.1";
|
||||
hash = "sha256-FcTLHQFvKkQY/kV08jhhy/St/+FmXpp3epp/R3zUXMA=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Fantomas.FCS";
|
||||
version = "6.1.1";
|
||||
hash = "sha256-NuZ8msPEHYA8T3EYREB28F1RcNgUU8V54eg2+UttYxw=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "FsCheck";
|
||||
version = "2.16.6";
|
||||
hash = "sha256-1hR2SaJTkqBzU3D955MvLNVzkQHkx0Z/QzOXZfzk2Zw=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "fsharp-analyzers";
|
||||
version = "0.27.0";
|
||||
hash = "sha256-QhLi2veTY1wZlQKJLTyVPgx/ImkaZugQNjSN5VJCNEA=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "FSharp.Core";
|
||||
version = "4.3.4";
|
||||
hash = "sha256-styyo+6mJy+yxE0NZG/b1hxkAjPOnJfMgd9zWzCJ5uk=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "FSharp.Core";
|
||||
version = "6.0.1";
|
||||
hash = "sha256-Ehsgt3nCJijpaVuJguC1TPVEKSkJd6PSc07D2ZQSemI=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "FSharp.Core";
|
||||
version = "8.0.400";
|
||||
hash = "sha256-wlrcAjjvI5YtnHR7kFH8uRUA4GomJYmqr41K5LYjCGs=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "FsUnit";
|
||||
version = "6.0.1";
|
||||
hash = "sha256-vka/aAgWhDCl5tu+kgO7GtSaHOOvlSaWxG+tExwGXpI=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.AspNetCore.App.Ref";
|
||||
version = "6.0.33";
|
||||
hash = "sha256-GcPiO+iI0JsHYlqURAmzWjOnDX2jDCUY4jYaIwr8ojs=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.AspNetCore.App.Runtime.linux-arm64";
|
||||
version = "6.0.33";
|
||||
hash = "sha256-g5zbB1DnCSKuCOWtF09GEqGn1uJLdlTN6kqdnSCzRjQ=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.AspNetCore.App.Runtime.linux-x64";
|
||||
version = "6.0.33";
|
||||
hash = "sha256-ToaiqVy5qonomAVBg5PO1GgrPKL4Cc1BZTJ0z/2LquA=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.AspNetCore.App.Runtime.osx-arm64";
|
||||
version = "6.0.33";
|
||||
hash = "sha256-OY/vdqAzZ99I4lEZbOOQw12TE0AIb5pXxKTvDxO2M2Q=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.AspNetCore.App.Runtime.osx-x64";
|
||||
version = "6.0.33";
|
||||
hash = "sha256-53MAV3RO1kXzy5IpdZDZIOhoUzFqWHn7+A3aWwdTONQ=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.CodeCoverage";
|
||||
version = "17.11.1";
|
||||
hash = "sha256-1dLlK3NGh88PuFYZiYpT+izA96etxhU3BSgixDgdtGA=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NET.Test.Sdk";
|
||||
version = "17.11.1";
|
||||
hash = "sha256-0JUEucQ2lzaPgkrjm/NFLBTbqU1dfhvhN3Tl3moE6mI=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.App.Host.linux-arm64";
|
||||
version = "6.0.33";
|
||||
hash = "sha256-rwWOpf2Pdg84c8bKIUcMYuDTI0kXUELL/nl9psSmX+E=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.App.Host.linux-x64";
|
||||
version = "6.0.33";
|
||||
hash = "sha256-5iYNZATXOePDsLA9lI80o1Gjxw4E+B4bJbwdYJJHcZY=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.App.Host.osx-arm64";
|
||||
version = "6.0.33";
|
||||
hash = "sha256-k3LenomOlacyzq4FlBY/TwV7+ClbK4U0A/O9r0pZHT4=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.App.Host.osx-x64";
|
||||
version = "6.0.33";
|
||||
hash = "sha256-tu72AwDH1+oAIXjOJcNbeyKm1s4pncYp0avbMSBrcJQ=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.App.Ref";
|
||||
version = "6.0.33";
|
||||
hash = "sha256-BiGUcXo1FQTlZdR6ndhUQ8lrYG3KaGXNXRVF+Fc3L28=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.App.Runtime.linux-arm64";
|
||||
version = "6.0.33";
|
||||
hash = "sha256-obRKiJEVpZ5E3TE7q2oHaYwFYhI23rMiHwp+8ORkwXY=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.App.Runtime.linux-x64";
|
||||
version = "6.0.33";
|
||||
hash = "sha256-2xdhvnKsFc8utDWN09zeXzZ5op+WUqkoWLuzdtQAkrA=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.App.Runtime.osx-arm64";
|
||||
version = "6.0.33";
|
||||
hash = "sha256-9KHubWicibZOcixiByzuBKPnJM2u5DSQC9jR3MAR1bI=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.App.Runtime.osx-x64";
|
||||
version = "6.0.33";
|
||||
hash = "sha256-smh6SiTtCAuFglqWrXiGGsoIDP9dhGuIKdYjmw+xCyY=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.Platforms";
|
||||
version = "1.1.0";
|
||||
hash = "sha256-FeM40ktcObQJk4nMYShB61H/E8B7tIKfl9ObJ0IOcCM=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.Platforms";
|
||||
version = "1.1.1";
|
||||
hash = "sha256-8hLiUKvy/YirCWlFwzdejD2Db3DaXhHxT7GSZx/znJg=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.Platforms";
|
||||
version = "2.0.0";
|
||||
hash = "sha256-IEvBk6wUXSdyCnkj6tHahOJv290tVVT8tyemYcR0Yro=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.Targets";
|
||||
version = "1.1.3";
|
||||
hash = "sha256-WLsf1NuUfRWyr7C7Rl9jiua9jximnVvzy6nk2D2bVRc=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.TestPlatform.ObjectModel";
|
||||
version = "17.11.1";
|
||||
hash = "sha256-5vX+vCzFY3S7xfMVIv8OlMMFtdedW9UIJzc0WEc+vm4=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.TestPlatform.TestHost";
|
||||
version = "17.11.1";
|
||||
hash = "sha256-wSkY0H1fQAq0H3LcKT4u7Y5RzhAAPa6yueVN84g8HxU=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Myriad.Core";
|
||||
version = "0.8.3";
|
||||
hash = "sha256-vBOxfq8QriX/yUtaXN69rEQaY/psRNJWxqATLidrt2g=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Myriad.Sdk";
|
||||
version = "0.8.3";
|
||||
hash = "sha256-7O397WKhskKOvE3MkJT37BvxorDWngDR6gTUogtDZ2M=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Nerdbank.GitVersioning";
|
||||
version = "3.6.143";
|
||||
hash = "sha256-OhOtMzP+2obDIR+npR7SsoXo0KrmcsL+VCE8Z3t5gzQ=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NETStandard.Library";
|
||||
version = "2.0.3";
|
||||
hash = "sha256-Prh2RPebz/s8AzHb2sPHg3Jl8s31inv9k+Qxd293ybo=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Newtonsoft.Json";
|
||||
version = "13.0.1";
|
||||
hash = "sha256-K2tSVW4n4beRPzPu3rlVaBEMdGvWSv/3Q1fxaDh4Mjo=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Newtonsoft.Json";
|
||||
version = "13.0.3";
|
||||
hash = "sha256-hy/BieY4qxBWVVsDqqOPaLy1QobiIapkbrESm6v2PHc=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NuGet.Common";
|
||||
version = "6.11.0";
|
||||
hash = "sha256-eb7G07RyZv4AQT6ItRqdBuUf9e9BXcQygsy5RNEXfNE=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NuGet.Configuration";
|
||||
version = "6.11.0";
|
||||
hash = "sha256-2SNZkX64SB15glzQx3k+vI7btr8Yqg4CayaaaK1B0AQ=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NuGet.Frameworks";
|
||||
version = "6.11.0";
|
||||
hash = "sha256-8DC7V2IlCjiMDQ9yWbl7QQHia6OpBrbWh5rL0qa0Opw=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NuGet.Packaging";
|
||||
version = "6.11.0";
|
||||
hash = "sha256-LVLvxcB6SMdayxAsrc5bCuLLt25fqPr6KfYcYoWWIQk=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NuGet.Protocol";
|
||||
version = "6.11.0";
|
||||
hash = "sha256-3vdB/8IiJ2LMHhFXLWOzf0H59Ow/zcoq6W4uCHbihCQ=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NuGet.Versioning";
|
||||
version = "6.11.0";
|
||||
hash = "sha256-03edgWvbqUtbzpBBTIxTwsSRoj1T2muGVL+vTuIHXag=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NUnit";
|
||||
version = "4.2.2";
|
||||
hash = "sha256-+0OS67ITalmG9arYCgQF/+YbmPRnB3pIIykew0kvoCc=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NUnit3TestAdapter";
|
||||
version = "4.6.0";
|
||||
hash = "sha256-9Yav2fYhC4w0OgsyUwU4/5rDy4FVDTpKnWHuwl/uKJQ=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "RestEase";
|
||||
version = "1.6.4";
|
||||
hash = "sha256-FFmqFwlHhIln46k56Z8KM1G+xuPEh/bceKCQnJcdcdc=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Runtime";
|
||||
version = "4.3.0";
|
||||
hash = "sha256-qwhNXBaJ1DtDkuRacgHwnZmOZ1u9q7N8j0cWOLYOELM=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.native.System";
|
||||
version = "4.3.0";
|
||||
hash = "sha256-ZBZaodnjvLXATWpXXakFgcy6P+gjhshFXmglrL5xD5Y=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.unix.System.Private.Uri";
|
||||
version = "4.3.0";
|
||||
hash = "sha256-c5tXWhE/fYbJVl9rXs0uHh3pTsg44YD1dJvyOA0WoMs=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Diagnostics.DiagnosticSource";
|
||||
version = "7.0.0";
|
||||
hash = "sha256-9Wk8cHSkjKtqkN6xW7KnXoQVtF/VNbKeBq79WqDesMs=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Formats.Asn1";
|
||||
version = "6.0.0";
|
||||
hash = "sha256-KaMHgIRBF7Nf3VwOo+gJS1DcD+41cJDPWFh+TDQ8ee8=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.IO.Abstractions";
|
||||
version = "4.2.13";
|
||||
hash = "sha256-nkC/PiqE6+c1HJ2yTwg3x+qdBh844Z8n3ERWDW8k6Gg=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.IO.FileSystem.AccessControl";
|
||||
version = "4.5.0";
|
||||
hash = "sha256-ck44YBQ0M+2Im5dw0VjBgFD1s0XuY54cujrodjjSBL8=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Memory";
|
||||
version = "4.5.5";
|
||||
hash = "sha256-EPQ9o1Kin7KzGI5O3U3PUQAZTItSbk9h/i4rViN3WiI=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Private.Uri";
|
||||
version = "4.3.0";
|
||||
hash = "sha256-fVfgcoP4AVN1E5wHZbKBIOPYZ/xBeSIdsNF+bdukIRM=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.Metadata";
|
||||
version = "1.6.0";
|
||||
hash = "sha256-JJfgaPav7UfEh4yRAQdGhLZF1brr0tUWPl6qmfNWq/E=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Runtime";
|
||||
version = "4.3.1";
|
||||
hash = "sha256-R9T68AzS1PJJ7v6ARz9vo88pKL1dWqLOANg4pkQjkA0=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Runtime.CompilerServices.Unsafe";
|
||||
version = "6.0.0";
|
||||
hash = "sha256-bEG1PnDp7uKYz/OgLOWs3RWwQSVYm+AnPwVmAmcgp2I=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Security.AccessControl";
|
||||
version = "4.5.0";
|
||||
hash = "sha256-AFsKPb/nTk2/mqH/PYpaoI8PLsiKKimaXf+7Mb5VfPM=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Security.Cryptography.Pkcs";
|
||||
version = "6.0.4";
|
||||
hash = "sha256-2e0aRybote+OR66bHaNiYpF//4fCiaO3zbR2e9GABUI=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Security.Cryptography.ProtectedData";
|
||||
version = "4.4.0";
|
||||
hash = "sha256-Ri53QmFX8I8UH0x4PikQ1ZA07ZSnBUXStd5rBfGWFOE=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Security.Principal.Windows";
|
||||
version = "4.5.0";
|
||||
hash = "sha256-BkUYNguz0e4NJp1kkW7aJBn3dyH9STwB5N8XqnlCsmY=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Text.Encodings.Web";
|
||||
version = "7.0.0";
|
||||
hash = "sha256-tF8qt9GZh/nPy0mEnj6nKLG4Lldpoi/D8xM5lv2CoYQ=";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Text.Json";
|
||||
version = "7.0.3";
|
||||
hash = "sha256-aSJZ17MjqaZNQkprfxm/09LaCoFtpdWmqU9BTROzWX4=";
|
||||
})
|
||||
]
|
Reference in New Issue
Block a user